이전 글에서 깃허브의 브랜치 전략에 대해 일부 알아봤습니다.
다만 브랜치 전략을 바꾸는 것만으로는 병합 순서와 갯수가 꼬이는 일을 고칠 수 없기에, 이번 글에서는 병합 방식에 대해 알아볼까 합니다.
Git에서는 보통 네 가지의 병합 방식이 존재합니다.

Merge Commit은 가장 기본적인 병합 방식으로, 브랜치를 병합하기 전 Merge Commit을 생성하는 방식입니다.
병합 후 브랜치 별 작업 내용이 명확히 구분되지만, 불필요한 Merge Commit으로 인해 히스토리가 복잡해지는 문제가 발생합니다.

특히, Hotfix나 Readme edit 등 사소한 커밋에도 Merge Commit이 붙기 때문에 커밋의 갯수가 방대해지고, 그래프 구조가 복잡해지는 문제가 생깁니다.
만약 Merge Commit을 사용하게 될 경우 겪게 될 문제가 하나 존재합니다.
만약 dev 브랜치 --> main 브랜치 와 같은 형식으로 병합을 진행할 경우, main에는 dev 브랜치의 내용과 함께 무조건 Merge Commit이 생성되기 때문에 dev 브랜치는 항상 커밋이 한 개 모자라게 됩니다.
| Test [main]
| \
| | Test2 [dev]
| | Test3
| | Test4
| /
| Merged (이 커밋이 dev 브랜치엔 없어서, dev 브랜치는 항상 커밋이 하나 부족함)
이를 해결하기 위해선 dev 브랜치를 main 브랜치와 동기화해줘야 합니다.
git pull origin main을 사용하여 해결 가능합니다.

Fast-forward Merge는 목표 브랜치의 Head 커밋이 변경되지 않았을 경우 사용할 수 있는 병합 방식이며, 단순히 목표 브랜치의 Head 커밋을 현재 브랜치의 가장 마지막 커밋으로 변경하는 방식입니다.
커밋 파일이 생기지 않아 커밋 내역이 깔끔하고 작업 흐름이 보이지 않기 떄문에 핫픽스 브랜치와 같은 단기 브랜치에는 적합하지만, 목표 브랜치의 Head 커밋이 변경되거나 기록을 남겨야 하는 상황이라면 사용하기 어렵습니다.

Squash Merge는 브랜치의 커밋들을 한 커밋에 압축하는 병합 방식입니다.
보통 병합 관련 글을 찾아보면 이에 관한 내용이 자주 나오지 않는 편인데, 커밋 기록을 최대한 보존하는 다른 병합 방식과는 정 반대로 모든 커밋 내역을 감추기 때문에 나오지 않는 것으로 보입니다.

하나의 대표 커밋으로 브랜치의 커밋 내역을 나타내기 떄문에 기능 순서대로 커밋 내역을 남겨야 하는 경우에 적합하지만, 반대로 하나의 커밋이 브랜치의 모든 커밋을 의미하기 때문에, 커밋별 롤백이 어려워지게 됩니다.

Rebase Merge는 커밋의 순서를 재정렬하고, 다른 브랜치 위에 커밋 내역을 덧붙이는 방식의 병합입니다.
언뜻 보면 Fast-Forward와 비슷하다고 볼 수 있겠으나, Head가 현재 브랜치의 시작점과 같을 경우에만 사용할 수 있는 Fast-Forward와는 달리, 커밋 내역을 재정렬한 뒤 목표 브랜치 뒤에 현재 브랜치의 커밋 내역을 잇기 떄문에 Head가 달라져도 사용할 수 있습니다.

만약 Rebase Merge를 사용할 경우, 커밋을 새로 생성하여 다시 덧붙이는 방식으로 커밋 내역을 잇기 떄문에 이미 푸시된 값을 변경하는 force push를 사용해야 하며, 병합 후 커밋들의 해시 값이 변경되게 됩니다.
이러한 변경 사항이 실제 협업 중인 브랜치에 적용될 경우 다른 사람들의 작업에서 병합 충돌이나 내역 왜곡 등의 문제를 일으킬 확률이 높습니다.
이렇게 4개의 병합 방식에 대해 살펴보았습니다.
현재 Velog Dashboard 프로젝트에서는 Squash Merge 방식을 사용하고 있지만, 병합 방식에 대해 충분히 이해한 후에도 커밋 순서가 꼬였던 문제에 대한 명확한 원인은 아직 찾지 못한 것 같습니다. (적어도 Squash Merge에서 발생하는 커밋 순서 관련 문제를 아직은 발견하지 못했습니다.)
최근 들어 브랜치 구조를 정리하고 이전처럼 Trunk 형태로 전환하면서 자연스럽게 문제가 해결되었지만, 그 과정에서 이전에 경험한 문제의 원인을 명확히 파악하기 어려워진 점은 아쉬움으로 남습니다.
깔끔한 정리 좋습니다~~ 2way merge 와 3way merge 분류부터 갈라주시면 더 좋지 않을까 해요!