git pull은 편리해서 습관적으로 쓰이지만, 그 편리함 뒤에 숨어 있는 자동 병합(또는 자동 리베이스) 때문에 예상치 못한 충돌이나 지저분한 병합 커밋을 만나는 경우가 있다. 이 장은 git fetch와 git pull이 실제로 서로 다른 두 단계로 이뤄진 조합이라는 사실을 밝힌다.
개요
두 명령의 관계를 한 줄로 요약하면, git pull은 git fetch 다음에 git merge(또는 설정에 따라 git rebase)를 자동으로 실행하는 축약형이다.
| |
기본 개념
git fetch는 원격 저장소의 새 커밋·브랜치 정보를 로컬의 refs/remotes/origin/ 아래로 내려받을 뿐, 현재 작업 중인 브랜치나 작업 트리를 전혀 건드리지 않는다. 이 성질 때문에 fetch는 “지금 무슨 변경이 있었는지 안전하게 확인만 하고 싶을 때” 쓰기 좋다.
| |
이렇게 확인한 뒤 원하는 방식(merge 또는 rebase)으로 직접 반영할지 결정할 수 있다는 것이 fetch의 장점이다. 반면 git pull은 이 확인 단계 없이 곧바로 병합까지 진행하므로, 로컬에 커밋되지 않은 작업이 남아 있거나 병합 충돌이 날 수 있는 상황이라면 예고 없이 그 상황과 맞닥뜨리게 된다.
종류/세부
pull의 기본 동작을 병합에서 리베이스로 바꾸기
git pull은 기본적으로 merge를 실행하지만, pull.rebase 설정으로 rebase를 실행하도록 바꿀 수 있다.
| |
16장에서 다룬 merge vs rebase 선택 기준이 여기서도 그대로 적용된다 — 원격의 최신 커밋을 로컬의 아직 push하지 않은 커밋 앞에 깔끔하게 반영하고 싶다면 pull --rebase가 직선 히스토리를 유지하는 데 유리하지만, 이미 다른 사람과 공유 중인 브랜치에서는 15장의 위험이 그대로 적용된다.
무엇을 fetch할지 지정하기
인자 없는 git fetch는 등록된 원격(기본은 origin)의 모든 브랜치를 대상으로 하지만, 특정 브랜치만 받아오도록 좁힐 수 있다.
| |
--prune은 팀원이 원격 브랜치를 삭제했는데 로컬에는 그 흔적(refs/remotes/origin/old-branch)이 남아 git branch -a(11장) 목록을 어지럽히는 상황을 정리할 때 유용하다.
주의사항·함정
커밋되지 않은 변경이 있는 상태에서 git pull을 실행하면 충돌 위험이 있다: pull은 곧바로 merge를 실행하므로, 12장에서 설명한 브랜치 전환 시 충돌과 유사하게 로컬 변경과 겹치는 부분이 있으면 문제가 생길 수 있다. 중요한 작업 중이라면 먼저 커밋하거나 git stash(29장)로 치워둔 뒤 pull하는 편이 안전하다.
“pull이 항상 최신 상태로 만들어준다"는 오해: pull은 명시한 원격·브랜치의 정보만 가져온다. 다른 원격(예: 17장에서 다룬 upstream)의 변경 사항은 그 원격을 대상으로 별도로 fetch·pull해야 반영된다.
fetch만 하고 병합을 잊어버리는 경우: fetch로 최신 정보를 받아왔지만 병합(또는 rebase)을 실행하지 않으면, 로컬 브랜치는 여전히 예전 상태에 머물러 있다. git status(06장)의 “Your branch is behind ‘origin/main’ by N commits” 메시지가 이 상태를 알려주는 신호다.
![Featured image of post [Git] 19. git fetch vs git pull](/post/git/git-fetch-vs-git-pull/wordcloud_hu_3f5a99123943c7de.webp)
![[Git] 17. git remote — 원격 저장소 등록](/post/git/git-remote-command-managing-remote-repositories/wordcloud_hu_ea9e4da91cbf1c73.webp)
![[Git] 18. git clone](/post/git/git-clone-command-copy-repository/wordcloud_hu_d317ea1a5439c059.webp)
![[Git] 19. git fetch vs git pull](/post/git/git-fetch-vs-git-pull/wordcloud_hu_98e312a4a7ccfd67.webp)
![[Git] 21. Fork와 Pull Request 워크플로(GitHub Flow)](/post/git/fork-pull-request-workflow-github-flow/wordcloud_hu_681908459f6099a8.webp)
![[Git] 11. 브랜치 개념과 git branch](/post/git/git-branch-concept-and-command/wordcloud_hu_d0c627d2bdd2eb50.webp)
![[Git] 14. Fast-forward vs 3-way merge](/post/git/fast-forward-vs-three-way-merge/wordcloud_hu_c86e279c96ef44f2.webp)