다양한 git merge 방법(3-way, fast-forward, squash, rebase)

코딩 화이팅 2024. 7. 28. 18:42

3-way merge

  • merge의 기본 동작방식
  • 브랜치에 각각 신규 commit이 1회 이상 있는 경우 merge 명령을 내리면 두 브랜치의 코드를 합쳐서 새로운 commit을 자동으로 생성

fast-forward merge

  • 새로운 브랜치에만 commit이 있고 기준이 되는 브랜치에는 신규 commit이 없는 경우
  • 딱히 합칠게 없어서 그냥 신규 브랜치 보고 "지금부터 니 이름은 main 브랜치야" 라고 해주는 것
  • 기준이 되는 브랜치에 신규 commit이 없으면 자동으로 fast-forward merge가 발동된다.
    • 이게 싫다면 git merge --no--ff 브랜치명 해서 강제로 3-way merge 해도 된다.

브랜치 삭제

git branch -d 브랜치이름
git branch -D 브랜치이름
  • 3-way, fast-forward 아무렇게나 merge해도 브랜치를 merge하고 나면 브랜치가 자동으로 삭제되진 않는다.
  • 병합이 완료된 브랜치 삭제 시엔 -d
  • 병합하지 않은 브랜치 삭제 시엔 -D

rebase and merge

rebase

브랜치의 시작점을 다른 commit으로 옮겨주는 행위

  1. rebase를 이용해서 신규 브랜치의 시작점을 main 브랜치 최근 commit으로 옮긴다.
  2. fast-forward merge하는 것

하는 이유?

  • 3-way merge 말고 강제로 fast-forward 하고 싶을 때
  • commit 내역을 한 줄로 계속 이어서 남기고 싶을 때

방법

git switch 새로운브랜치
git rebase main

git switch main
git merge 새로운브랜치
  1. 새로운 브랜치로 먼저 이동
  2. git rebase main
  3. 그럼 브랜치가 main 브랜치 끝으로 이동하는데 그걸 fast-forward merge

특징

  • 강제 fast-forward merge나 다름 없긴함
  • main 말고 다른 브랜치끼리도 가능
  • 단점 : 브랜치끼리 차이가 너무 많은 경우 rebase하면 충돌이 많이 발생할 수 있는데 그거 하나하나 해결하기 귀찮음

 

대충 모든 브랜치를 3-way merge 해버리면 대참사가 일어날수도 있음

이렇게...

  • 3-way merge 된 것들은 복잡해보일 수 있다.
  • main 브랜치 git log 출력해보면 3-way merge된 브랜치들의 commit 내역도 다 같이 출력되어서 더러워진다.

squash and merge

  • 3-way merge처럼 선으로 이어주지 않고 새 브랜치에 있던 코드 변경 사항들이 main 브랜치로 이동한다.
  • main 브랜치의 git log 출력해볼 때 merge 완료된 브랜치의 commit 같은 것들이 출력되지 않는다.

방법

git switch main
git merge --squash 브랜치명
git commit -m '메세지'
  • 그냥 --squash 옵션을 추가하면 끝
  • 브랜치에서 만들어놨던 많은 commit을 다 합쳐서 하나의 commit으로 main 브랜치에 생성해줌.

  • 결과는 둘 다 똑같은데 일반 merge는 선으로 이어져있고 squash는 이동돼 있다.
  • 브랜치 100개 만들어놨는데 일반 merge를 잔뜩 해놓으면 나중에 git log 그래프가 매우 복잡해질 수 있다. 이게 싫다면 rebase나 squash 사용