티스토리 뷰

728x90
반응형

[1] Merge Commit 은 왜 기본적으로 Interactive Rebase 가 안될 까 ? 

Git의 rebase --interactive  (또는 간단히 rebase -i) 는 히스토리를 직선(선형)으로 평탄화하려고 설계되어 있어서,

부모가 2개 이상인 merge commit은 목록에 포함되지 않거나 편집 대상이 아닙니다.

그래서 기본적으로 머지 커밋을 Interactive Rebase (edit, fixup, reword 등) 할 수 없어요.

 

 

📌 머지 커밋의 구조

  • 머지 커밋은 브랜치를 합치는 시점에 생기며,
  • 부모가 두 개 이상 → 양쪽 브랜치의 끝을 모두 가리킵니다.
      D --- E   (feature 브랜치)
     /         
A -- B -------- M   (main 브랜치)
                ↑
                머지 커밋 (부모 = B, E)

 

여기서 M은 부모가 두 개:

  • 하나는 main 브랜치 쪽(B),
  • 하나는 feature 브랜치 쪽(E).

 

📌 그래서 interactive rebase가 힘든 이유

 

git rebase -i는 선형 히스토리(부모가 1개인 체인)만 전제로 동작합니다.

머지 커밋은 부모가 2개라 “어떤 선을 따라가야 할지” 모호하기 때문에, 기본 rebase -i 에는 나오지 않아요.

 

 

[2] --rebase-merges 옵션 

하지만 따로 --rebase-merges 옵션을 쓰면 머지 커밋도 포함한 채로 리베이스할 수 있습니다. 

 

✅  --rebase-merges 옵션이란?
git rebase는 기본적으로 선형 히스토리만 다루기 때문에,  머지 커밋(부모가 2개 이상인 커밋) 은 무시해 버립니다.

 

  --rebase-merges 옵션을 붙이면:
• 머지 커밋 구조를 보존하면서 리베이스할 수 있습니다.
• interactive rebase(-i)와 함께 쓰면 todo 리스트에 merge … 라인이 나타나서, 머지 커밋도 edit, reword, drop 같은 조작이 가능해집니다.

 

 

✅ 정리
• rebase -i = 선형 히스토리만
• rebase -i --rebase-merges = 머지 커밋 포함해서 히스토리 재작성 가능

 

 

 

포크에서는 해당 옵션을 지원안하는 것 같고 터미널을 통해 해야하는 것 같아요! 

 

https://github.com/fork-dev/TrackerWin/issues/806

 

Add option for --rebase-merges when rebasing interactively · Issue #806 · fork-dev/TrackerWin

I'm forced to leave Fork when I want to rewrite the history of a merged branch (--no-ff) as the default rebase puts the rebased commits into a linear branch. Could we have an option when rebasing t...

github.com

 

 

 

[3]  --rebase-merges 옵션 써보기

 

일단 필요한 상황을 가정해볼게요~

 

1) 추가 커밋 1을 머지 커밋에 합치고 싶을 때 

추가 커밋 1
머지 커밋

 

이런 상황에서는 --rebase-merges 옵션 안쓰고도 충분히 편하게 할 수 있어요! 

추가 커밋 1을 soft 혹은 mixed reset 하고 amend (Amend Last Commit) 해서 머지커밋에 흡수시키면 됩니다. 

 

 

 

 

✅ 2) 추가 커밋2 를 머지 커밋에 합치고 싶을 때 

추가 커밋 2
추가 커밋 1
머지 커밋

 

 

이 상황도 사실 체리픽 + 리셋 으로 쉽게 하면 되는데요,,

 

 

 

추가 커밋 1을 reset 범위에 포함시키지 않고 정석대로 리베이스 하고 싶다는 것을 전제로 해보겠습니다.

전체적은 흐름은 다음과 같고

  # 1. interactive rebase 시작 (에디터가 열림)
  # - 현재 HEAD 에서 3번째 전 커밋까지 rebase 대상으로 삼겠다.
  git rebase -i --rebase-merges HEAD~3

  # 2. 에디터에서 다음과 같이 수정:
  #    - "pick d1d55ad 추가 커밋 2"를 "fixup d1d55ad 추가 커밋 2"로 변경
  #    - 그 줄을 잘라내서 "merge -C 324dcf5 main" 바로 아래로 이동
  #
  # 수정 전:
  # merge -C 324dcf5 main # Merge branch 'main' into feature
  # pick 0f8b2db 추가 커밋 1  
  # pick d1d55ad 추가 커밋 2
  #
  # 수정 후:
  # merge -C 324dcf5 main # Merge branch 'main' into feature
  # fixup d1d55ad 추가 커밋 2
  # pick 0f8b2db 추가 커밋 1

  # 3. 저장하고 에디터 종료하면 rebase가 실행됨

 

 

직접 하나씩 해볼게요! 

 

1) 

우선 편하게 에디팅하기 위해  원하는 에디터로 열어줍니다. 

저는 Sublime Text 로 열었는데 

  GIT_EDITOR="subl --wait" git rebase -i --rebase-merges HEAD~3  # Sublime Text

 

 

Atom 으로 열고 싶으면 아래 명령어를 사용하시면 됩니다. 

  GIT_EDITOR="atom --wait" git rebase -i --rebase-merges HEAD~3   # Atom

 

 

2) 

그럼 이런 git-rebase-todo 가 나오는데 

 

 

 

이렇게 바꾸고 

 

 

 

에디터를 저장 후 종료하면 리베이스가 실행됩니다.

 

 

 

참고)

 

요거 실행 후,

git rebase -i --rebase-merges HEAD~3

 

 

에디터로 수정안하고 포크를 열어서 GUI 로 수정할 수 있다고 AI 는 말하는데

포크로 넘어가보면  Interactive Rebase 창이 안열립니다 ;;

 

--rebase-merges 옵션을 사용하는 경우, 

CLI(Command Line Interface) + 포크(GUI툴)  하이브리드로 못쓴다고 파악함.

 

 

 

 

반응형
댓글