Robust Project Structure
Git rebase와 git pull의 차이
git rebase와 git pull(fetch+merge)의 차이점과 깃 플로우 관리에 있어서의 장단점에 대해서 알아본다.
Problem - git rebase와 git pull의 차이
이번 프로젝트에서 가장 까다로웠던 것은 모든 개인(feature을 비롯한 모든) 브랜치가 main에서 git pull을 통해 최신화된다는 점이었다. git pull(fetch+merge)에서 주의해야 할 점은, 로컬 브랜치에서 커밋을 가진 상태로 pull을 시도해 머지하는 경우 코드가 덮어씌워질 수 있다는 점이다.
Goal - git pull(fetch+merge)로 깃 플로우를 관리할 시 코드가 덮어씌워지는 현상에 대해서 확인하고, 더 안전한 방법을 찾아본다
- git pull(fetch+merge)로 깃 플로우를 관리할 시 코드가 덮어씌워지는 현상에 대해서 확인하고, 더 안전한 방법을 찾아본다
stackoverflow 에서 설명하는 이 케이스를 확인해 보았다.
pull은 당신의 파일을 덮어씌우지 않습니다.pull을 사용할 경우, 해당 대상 브랜치를 먼저fetch하고 이것을 당신의 로컬 코드에 적용합니다. 이것은git merge와 동일한 과정입니다. 만약 당신이 App.tsx 파일을 푸시했고 이것을 로컬에서 수정한 상황이라고 생각합니다.
- 이 상황에서 당신이
pull을 수행하는 경우 git은 당신의 로컬 수정사항을 기록하고 있으며 이것은 별 문제없이 병합이 됩니다.- 하지만 다른 사람이 같은 파일을 수정하는 경우, 이것은
conflict로 이어져 당신의 선택을 통해 원하는 버전이 머지됩니다.- 만약 다른 사람이 같은
pull과정을 통해 이 1.cpp 파일을 변경한 커밋을 내가pull로 가지고 오는 경우, 파일이 덮어씌워질 수 있다.
- 여기서 문제가 되는 것은, git pull은 머지 커밋을 생성하기 때문에 같은 부분을 수정하는 커밋을 pull 해서 머지하는 경우 머지 커밋간의 시간 우선순위에 의해서 코드가 덮어씌워지는 현상이 있을 수 있다는 것이다.
Implementation - 그렇다면 어떻게 해야 하나?
- git rebase
- 자식 브랜치에서는 머지 커밋을 생성하는
pull대신rebase를 사용한다. 먼저main의 변경점을 가져온 뒤에, 그 다음에 내 커밋을 적용해서 머지 커밋을 없애고 내 커밋을 가장 최신으로 유지한다.
- git pull
- 부모 브랜치(main)에서는 pull request만을 사용해서 자식을 병합한다.(cherry-pick?) 머지 커밋은 여기서만 생성한다.