Git Merge Fast-forward/3-way
10 May 2021branch가 merge되는 방법은 크게 2가지가 있다. Fast-forward Merge와 3-way Merge 인데, https://git-scm.com/의 Git Pro 예제 시나리오를 참고해 알아보자.
시나리오
- 작업 중인 프로젝트의 중심인 master branch가 있다.
- 새로운 이슈를 처리하기 위해 issue branch를 생성한 뒤 작업을 진행
- 그러던 도중 프로젝트에 급한 문제가 발생해 이를 처리하기 위한 hotfix branch를 생성
- 문제를 해결한 뒤, 테스트까지 마친 hotfix branch 를 master로 Merge
- 진행 중이던 이슈 작업을 마친 뒤 issue branch를 master로 Merge
1. 커밋 히스토리 세팅
2. 새로운 이슈 처리 → iss53 branch 생성 후 작업
보통 위와 같이 새로운 이슈가 발생하면 운영 중인 프로젝트의 master branch가 아닌 새로운 issue branch라는 걸 생성해서(branch 명은 상관 없음) 처리 후, 테스트까지 한 다음에 master에 merge하는 방식을 따른다.
이유는 새로운 이슈 처리 시 갑자기 어떤 에러가 발생하거나 필요 없어질 수 있기 때문에 운영에 차질 없게 따로 분리해서 모든 테스트를 마친 뒤 merge한다.
3. 본 프로젝트에 문제 발생 → hotfix branch 생성 후 작업
버그를 해결하기 위해 작업 중인 iss53을 멈추고 master branch로 돌아가야 한다. branch를 변경할 때는 아직 commit하지 않은 파일이 Checkout 할 branch와 충돌할 수 있기 때문에 워킹 디렉토리를 정리하는 것이 좋다.
이제 모든 버그를 고쳤고 테스트까지 완료한 상황이다. 최종적으로 본 프로젝트 운영 환경에 적용시켜 배포하기 위해 master branch로 merge해야 한다.
4. hotfix branch를 master로 merge
merge 이후 메세지를 자세히 보면 Fast-forward 라는 메세지가 보인다.
hotfix 브랜치가 가리키는
C4
커밋이C2
커밋에 기반한 브랜치이기 때문에 브랜치 포인터는 Merge 과정 없이(새로운 커밋 생성 없이) 그저 최신 커밋으로 이동한다.
여기서 핵심은 merge 하려는 master branch의 최신 commit고 C2
이고, 그로부터 뻗어나간 hotfix branch이므로 시작점이 C2
로 commit이 같다는 점이다. 때문에 master branch가 가리키고 있던 C2
에서 iss53이 가리키고 있는 C3
을 건너 뛰고 hotfix branch의 최신 commit인 C4
로 이동하면서 C4
를 가리키고 있는 branch가 master와 hotfix, 둘이 된다.
마지막으로 hotfix branch는 삭제한다.
5. iss53 branch를 master로 merge
이제 작업 중이던 이슈를 마친 뒤 테스트까지 완료했으므로 배포를 위해 master branch에 merge 해야 한다. 하지만 이 경우 위 hotfix branch를 merge할 때와는 다르다.
만약 hotfix의 변경 사항이 이슈를 작업하는 데 있어서 중요한 사항이었다면 작업 도중 hotfix 또는 버그를 고친 master branch를 iss53에 merge 했을 것이다. 하지만 이 경우에는 iss53 branch의 시작점은 C2
commit 이었는데 반해 merge 하려는 master branch의 최신 commit은 C4
로 다르다.
즉, master branch가 iss53 branch로 이동하게 되면 hotfix의 변경 사항이 없어지게 되기 때문에 Fast-forward는 안 된다. 이때 수행되는 방법이 3-way Merge다.
Git은 각 브랜치가 가리키는 커밋 두 개와 공통 조상 하나를 사용. 단순히 브랜치 포인터를 최신 커밋으로 옮기는 게 아니라 3-way Merge 의 결과를 별도의 커밋으로 만들고 나서 해당 브랜치가 그 커밋을 가리키도록 이동
때문에 master branch에서 iss53 branch를 merge하면 아래와 같이 commit 메세지를 작성하라는 가이드가 나온다.
사실 3-way Merge는 같은 파일의 내용을 수정했을 때 충돌에 의해 실패하기도 한다. Git은 자동으로 Merge 하지 못해서 새 commit이 생기지 않으므로 변경사항의 충돌을 개발자가 직접 수정한 뒤 commit 해야 한다. 해결하는 방법은 같은 Git Pro 글에 있으므로 링크를 참고.