
git push가 거절당했습니다. 제가 창구를 둘로 만들어놨더군요
블로그 첫 글을 지웠습니다. 처음 만들 때 딸려온 예제 글이라 이제 필요가 없었거든요.
지우고, 커밋하고, git push를 눌렀더니 이렇게 나왔습니다.
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'github.com/...'
거절.
창구가 둘이었습니다
원인을 알고 나니 당연했습니다. 제 블로그는 글을 넣는 길이 두 개입니다.
하나는 제 PC입니다. 파일을 고치고 git push로 올립니다.
다른 하나는 브라우저입니다. 블로그에 글쓰기 화면을 붙여뒀는데, 이건 GitHub에 직접 커밋합니다. 제 PC를 안 거칩니다.
밖에서 휴대폰으로 오타 하나만 고쳐도, 그 순간부터 제 PC는 뒤처진 상태가 됩니다. 그리고 저는 그걸 모르는 채로 며칠 뒤에 git push를 누릅니다.
거절은 고장이 아닙니다
메시지를 끝까지 읽으면 git이 이유를 설명해줍니다.
hint: Updates were rejected because the tip of
hint: your current branch is behind its remote
hint: counterpart. If you want to integrate the
hint: remote changes, use 'git pull' before
hint: pushing again.
“네 브랜치 끝이 원격보다 뒤처져 있다.” 그러니까 원격에는 있는데 제 PC에는 없는 커밋이 있다는 뜻입니다. 제가 브라우저로 쓴 그 글입니다.
git 입장에서는 덮어쓸 수 없으니 멈춘 것입니다. 고장이 아니라 안 잃어버리게 해주는 장치입니다. (fetch first)나 (non-fast-forward)라고 뜨는데, 둘 다 같은 이야기입니다.
pull부터 눌렀더니 이번엔 이겁니다
시키는 대로 git pull을 했습니다.
error: Your local changes to the following files would be
overwritten by merge:
src/content/blog/first-post.md
Please commit your changes or stash them before you merge.
Aborting
또 막혔습니다. 이번에는 작업하던 게 남아 있어서입니다.
원격에서 받아올 내용이 제가 지금 손대고 있는 파일과 겹치니까, git이 그걸 덮어쓰기 전에 멈췄습니다. 이것도 보호 장치입니다.
여기서 순서가 하나 정리됩니다. 커밋을 먼저 하고 pull합니다. 거꾸로 하면 이 자리에서 막힙니다.
그리고 충돌
커밋하고 다시 pull했더니 이번엔 이런 게 나왔습니다.
CONFLICT (modify/delete):
src/content/blog/first-post.md deleted in HEAD
and modified in 8aa65f9. Version 8aa65f9 of
src/content/blog/first-post.md left in tree.
Automatic merge failed; fix conflicts and then
commit the result.
읽어보면 상황이 그대로 적혀 있습니다. 저는 지웠고, 원격에서는 고쳤습니다. git은 둘 중 뭘 원하는지 모르니까 판단을 저에게 넘깁니다.
git status를 보면 더 짧게 나옵니다.
Unmerged paths:
(use "git add/rm <file>..." as appropriate
to mark resolution)
deleted by us:
src/content/blog/first-post.md
deleted by us. 지운 건 제 쪽이라는 표시입니다.

여기서 헷갈리기 쉬운 게 하나 있습니다. 충돌 났을 때 습관적으로 git add -A를 치면, 지웠던 파일이 도로 살아납니다. 충돌 상태에서는 원격 버전 파일이 폴더에 남아 있거든요. 그걸 통째로 담아버리는 겁니다.
지우는 쪽으로 가려면 add가 아니라 rm입니다.
git rm src/content/blog/first-post.md
git commit --no-edit
git push
--no-edit은 병합 메시지를 그냥 기본값으로 쓰겠다는 뜻입니다. 이번엔 통과했습니다.
--force를 쓰면 안 되는 이유
검색하면 git push --force가 바로 나옵니다. 이걸 누르면 거절이 사라지긴 합니다.
대신 브라우저로 쓴 글이 통째로 없어집니다.
--force는 “원격을 내 PC 상태로 맞춰라”라는 뜻입니다. 그런데 제 PC에는 그 글이 없습니다. 없는 상태로 맞추라고 했으니 지워지는 게 맞습니다.
거절당한 상황은 원격에 내가 모르는 게 있다는 신호입니다. 그 상태에서 --force는 “모르는 걸 지워라”와 같은 말입니다.
순서를 붙여뒀습니다
같은 일을 또 겪을 것 같아 벽에 붙이듯 적어뒀습니다.
# 1. 하던 것부터 저장
git add -A
git commit -m "..."
# 2. 원격 것 받아오기
git pull --no-edit
# 3. 충돌 나면 어느 쪽을 남길지 고르고
git rm <파일> # 지우는 쪽
git add <파일> # 남기는 쪽
git commit --no-edit
# 4. 올리기
git push
그리고 습관 하나. 작업을 시작하기 전에 git pull을 먼저 합니다. 특히 브라우저로 글을 쓴 날은요. 3초짜리 습관인데, 이걸 안 해서 반나절을 쓴 셈입니다.
짚고 갈 것
이건 git이 어려워서 생긴 문제가 아닙니다. 같은 저장소에 글을 넣는 창구를 제가 둘로 만들어놓고, 하나만 쓰는 것처럼 굴어서 생긴 문제입니다.
브라우저 글쓰기는 편합니다. 지하철에서 오타를 고칠 수 있는 건 큰 장점이고 계속 쓸 생각입니다. 다만 그걸 붙이는 순간부터 내 PC는 더 이상 유일한 원본이 아니라는 것만 기억하면 됩니다.
거절 메시지가 그걸 알려주려던 거였고요.
참고한 문서
- Git 문서 — git push (fast-forward가 아닌 push) — 거절되는 이유, —force가 위험한 이유, —force-with-lease
- Git 문서 — git merge (충돌 해결) — pull로 합칠 때 충돌을 정리하고 커밋하는 흐름
- Git 문서 — git status (짧은 형식의 충돌 표시) — “deleted by us” 같은 표시의 뜻
댓글
로그인도 이메일도 필요 없습니다. 이름만 적고 편하게 남겨주세요.
지금은 댓글을 불러올 수 없습니다. 잠시 뒤에 다시 시도해 주세요. 급한 내용이면 ryuma@kakao.com로 보내주셔도 됩니다.