git : merge options (merge / fastforward / squash / rebase)

정윤호·2024년 4월 29일
0

코드잇잇잇!

목록 보기
12/30

출처

https://git-scm.com/docs/git-merge
https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/about-merge-methods-on-github
https://lukemerrett.com/different-merge-types-in-git/
https://medium.com/@itsnarayan/types-of-git-merge-in-github-bitbucket-2a7e0fff3876


왜 궁금했을까

스프린트 미션을 진행하며, 깃도 자주 사용하게 되었다. 강의로만 들었을 때는, 전부 이해가 된줄 알았지만, 막상 실제로 해보려니까 참 실수도 많고 헤매곤 한다.
특히, 브랜치 머지할 때가 많이 긴장된다. 일어나지 않을거란걸 알지만, 혹시 내가 잘못 머지해서 내가 열심히 작업한 코드가 사라지면 어쩌지라는 생각이 참 무섭다. 두려움은 무지에서 오는 것...

오늘 나는 깃 브랜치 머지에 대해 좀 더 알아보고, 두려움을 극복하고자 한다.

4 merge options

깃헙에서 PR을 완료할 때, 4가지 merge options 을 제안한다.

  • Merge
  • Fast Forward Merge
  • Squash and Merge
  • Rebase and Merge

나와 같이 깃 사용에 익숙하지 않은 이들은, 오히려 이러한 많은 선택지 앞에 결정장애에 빠지게 되는데...
어느 시점에서 어떤 option 의 merge 가 적절한지 결정하는 것은 참 까다롭다. 깃 사전 지식이 없다면, 이런 option 들의 이름만으로, 이들의 동작을 예상하기가 쉽지 않기 때문이다.

각 옵션에는 장단점이 있고, 때에 따라 쓸모가 다르다. 따라서, 절대적으로 가장 좋은 옵션이란 것은 없고, 현재 작업하고 있는 팀의 방식, 그리고 요구사항에 적합한 merge option 을 선택하는 것이 더 중요하다. 즉, 깃의 기본적인 지식을 쌓은 뒤에는, 팀과의 소통으로 결정을 내리는 것이 바람직하다.

다음으로 각 유형이 수행하는 작업에 대한 분석과 각 과정을 다이어그램과 함께 명확히 설명하고자 한다.

Merge

기본적인 merge는 병합되는 브랜치의 각 커밋을 base 브랜치의 히스토리에 추가하고, 병합이 발생한 타임스탬프를 기록하는 merge commit을 생성한다.
이는 가장 기술적이고 자세한 히스토리를 제공하지만, 복잡한 그래프를 만들 수 있다.

장점

  • 가장 자세하고 상세한 히스토리를 제공하여 언제 일어났는지를 정확하게 알려주며, 코드 변경 내용에 대한 최상의 맥락을 제공한다.
  • git log --oneline --graph를 사용하여 브랜치가 만들어진 시기를 그래프로 볼 수 있어 변경 내용과 변경 시기를 이해하는 데 도움이 된다.
  • 최종적으로 병합된 변경 사항을 이루는 각 커밋을 볼 수 있어 세부 정보의 손실이 없다.

단점

  • merge commit은 종종 히스토리 상으로만 존재하기 때문에, 비어 있어서 오해를 발생시킬 수 있다.
  • 특히 일련의 변경 사항을 되돌리려고 할 때 특히 혼란스러울 수 있다.
  • 이전 브랜치의 복잡한 그래프가 생성되어 가독성이 떨어질 수 있다.

Fast Forward Merge

git checkout main
git merge [대상 브랜치]

위와는 다르게, 우리 브랜치가 생성된 이후 base 브랜치에 새로운 커밋이 없었다면, Git은 Fast Forward merge 를 할 수 있다. 이것은 merge commit을 생성하지 않는 다는 점을 제외하면, 위의 기본 Merge 와 유사하다.

Fast Forward merge 를 하게 되면, 다른 두 브랜치를 merge 하는 것이 아니라, base 브랜치에 직접 커밋을 한 느낌을 받을 것이다. 이 방법은 기본 브랜치에 변경 사항이 없었기 때문에, 브랜치가 발생한 것을 포착할 필요가 없다는 것다.

장점

  • 매우 깔끔한 커밋 히스토리를 유지한다.
  • 최종적으로 병합된 변경 사항을 이루는 각 커밋을 볼 수 있어 세부 정보의 손실이 없다.

단점

  • 기본 브랜치에 새로운 커밋이 없는 경우에만 수행할 수 있으며, 공유 리포지토리에서는 흔하지 않은 방식이다.
  • 브랜치가 생성된 시점이나 병합된 시점을 포착하지 못하므로, 이는 히스토리 상으로 부정확하게 보일 수 있다.

Squash & Merge

git checkout main
git merge --squash [대상 브랜치]

squash는 브랜치에 있는 모든 커밋(A,B,C)을 하나의 커밋으로 통합한다. 이 통합된 커밋은 히스토리에 추가되지만, 브랜치를 이루던 커밋들(A, B, C)은 보존되지 않는다.

장점

  • 매우 깔끔한 커밋 히스토리를 유지한다.
  • 여러 커밋을 통해 이루어진 작업을 살펴보는 대신, 로그에서 단일 커밋으로 더 간결하게 살펴볼 수 있다.

단점

  • 세부 정보의 손실로 인해 브랜치를 이루던 커밋들에 포함된 유용한 세부 사항, 논리 변경 사항 등에 접근할 수 없게 된다.
  • 개발 과정에서 기록된 재미있는 의사 결정, 리뷰 및 코멘트 등도 손실된다.

Rebase & Merge:

git checkout [feature]
git rebase main

Rebase 는 브랜치의 시작 지점을 기준 브랜치의 마지막 커밋으로 이동시키고, 그 위에 새로운 커밋을 다시 적용한다. 이는 히스토리를 깔끔하게 유지하면서도 개별 커밋의 세부 정보를 유지할 수 있다.

만일 fast forward merge 가 기본 브랜치에 변경 사항이 있었던 경우에도 작동한다면, 이는 Rebase 와 비슷할 것이다.

Rebase 는 히스토리를 보다 선형적으로 유지할 수 있지만, 여러 엔지니어가 공유하는 리포지토리에서는 다소 복잡할 수 있다.

장점

  • 매우 깔끔한 커밋 히스토리를 유지한다.
  • 개별 커밋의 세부 정보를 유지한다.

단점

  • 누군가가 병합하기 전에 기본 브랜치에 커밋을 한다면 Rebase를 다시 해야 하는 수고가 발생할 수 있다.
  • 브랜치가 생성되었거나 병합되었는지 등의 역사적인 정보가 포착되지 않아, 역사적인 관점에서 부정확하게 보일 수 있다.
  • 어떤 커밋이 어떤 PR/브랜치와 관련이 있는지 파악하기 어려울 수 있다.

결론

브랜치 merge 전략 네가지에 대해 알아봤다. 알고 나니, 앞으로 깃 사용함에 있어서 더 자신감 있고, 큰 두려움 없이 작업해나갈 것 같다...!
일단은 간략한 비교를 했는데, 각 브랜치 전략 안에서도
어떠한 옵션을 주는지에 따라, 또 상이한 양상을 보여줄 수 있다고 한다...

만일 깃 사용 중에, 이러한 세부 플래그들도 이용해야 하는 날이 온다면,
이들에 대해서도 세부적으로 다루고 정리하고자 한다...

공부의 길은 정말 길다.

profile
우리 인생 화이팅~

0개의 댓글