카테고리 없음

[깃] Head / Fetch, Pull / Rebase, Cherry-pick, Merge

쿠마냥 2024. 5. 25. 17:06

1. Git Head는 무엇일까?

HEAD는 깃에서 작업 중인 브랜치의 ‘최신 커밋’을 가리키는 포인터이다. 따라서…

  • 체크아웃을 하면 새 브랜치의 최신 커밋으로 이동한다.

HEAD로 알 수 있는 것은 다음과 같다.

  • 현재 작업 중인(체크아웃된) 브랜치가 무엇인가?
  • 해당 브랜치의 최신 커밋이 무엇인가?
  • HEAD~1은 현재 커밋의 바로 이전 커밋, HEAD~2는 이전이전 커밋을 나타낸다. 즉 최근 커밋들을 탐색할 수 있다.
  • HEAD~1로 이동한 다음 새 커밋을 추가하면, 이 커밋은 어느 브랜치에도 속하지 않게 된다. (detached HEAD 상태라고 부름) 여기서 ‘git checkout -b new-branch-name’로 새 브랜치에 커밋을 넣을 수도 있으며, 그러지 않고 다른 브랜치로 체크아웃해 버린다면 결국 GC에 의해 정리되고 만다.

2. Git Fetch와 Git Pull의 차이

git fetch와 git pull은 모두 원격 저장소의 상태를 로컬로 업데이트하기 위해 쓰이지만, 중요한 차이가 있다. 

  • git pull = git fetch + git merge

라는 것!

원격 저장소의 최신 상태를 확인하고 싶지만, 아직 로컬에 merge하고 싶지 않다면 git fetch를 사용한다. (다시 한 번 말하면, 원격 저장소의 데이터를 가져오기만 하고 반영은 안 한다) 이후 로컬에서 최신 변경 사항을 검토하고 merge하면 git pull한 것과 같은 상태가 된다.

 

3. Git Rebase / Cherry-pick / Merge

git rebase

git rebase브랜치2에서 이루어진 커밋들을 브랜치1의 최신 커밋 위로 ‘재배치(rebase)’한다.

  • 커밋 히스토리가 일렬종대하게 된다.
  • 만약 이런 상황이라면 사용에 주의가 필요하다. → 브랜치2가 브랜치1로부터 분기되었고, 이후 브랜치2는 새로운 커밋을 했다. → 브랜치2는 자신의 원격 저장소에 이를 푸시했다. 아직 브랜치1에 merge하지는 않았다. → 이때 rebase하면 브랜치2의 새 커밋들이 브랜치1의 최신 커밋 이후에 시작된 것처럼 만들 수 있다. → 브랜치2의 로컬과 원격 저장소가 불일치하게 된다. 로컬 커밋은 변경되었으나, 원격은 그대로다! → 브랜치2로 작업을 계속하려 한다면, 이는 큰 문제가 된다. → 해결방법은 ‘git push —force’. 로컬 저장소의 내용을 원격에 강제 반영한다.

git merge

git merge브랜치1과 2의 변경을 모두 검토하고 통합한다. 만약 merge하다가 충돌이 일어날 경우 수동으로 해결한다.

  • 안전하다.
  • 각 브랜치의 히스토리가 보존된다. 
  • 대부분 merge 하는 것이 일반적.

git cherry-pick

git cherry-pick다른 브랜치의 특정 커밋 하나를 현재 작업 중인 브랜치로 가져온다.

  • 변경을 선택적으로 반영하고 싶을 때 사용한다.
  • 그러나 줄줄이 소세지처럼 엮어 있는 커밋을 가져오려 할 경우 큰일이 날 수 있다.