[Git][rebase] git merge와 rebase의 차이점, rebase는 왜 사용할까? rebase 사용법

GY·2022년 1월 26일
3

Git

목록 보기
13/13
post-thumbnail

원티드 프리온보딩 코스의 첫 과제를 진행하면서, 어떻게 커밋 내역을 잘 관리할 수 있을지에 대한 고민을 했다. 먼저 제안해서 rebase를 사용해보았지만, 나도 아주 자세히 알고 있다는 생각은 들지 않았다... 이 김에 다시 한번 정리해보았다.

💎 Git rebase는 왜 필요한가

🔹 git merge와 다른점

🔸 Merge

머지는 브랜치를 통합하는 것이다.

  • 병합 시 합쳐진 브랜치의 커밋 메시지가 중복으로 쌓인다.
  • 새로운 머지 커밋을 생성한다.

🔸 Rebase

base를 재설정한다는 의미로, 브랜치의 base를 옮긴다.
branch는 base지점을 가지고 있어 base 에서부터 코드를 수정한다.

  1. 처음에는 B지점을 base로 두 개의 브랜치가 뻗어져나왔다. D, E 커밋을 진행한다.
  2. rebase하여 C지점으로 base를 이동시켜 두 개의 브랜치의 코드를 합치는데, 이 때 D, E 커밋은 base로 새로 지정된 C 지점 이후로 정렬된다.

그래서 이렇게 정렬하는 이유는 뭘까?

  • Git History를 깔끔하게 관리할 수 있다.
    - 모든 feature branch마다 merge commit이 남기 때문에 main 브랜치를 공유하는 개발자가 많고 프로젝트 규모가 클 경우 branch history가 지저분해진다. 즉, 독립된 브랜치에서 로직 하나를 작성하고 수정하더라도, 다른 작업화 그 내역이 겹쳐 구분하기 어려워진다.

  • fast-forward merge가 가능하다.
    - rebase를 하면 병합 시 브랜치의 커밋 메시지가 시간순서대로 합쳐진다.
    - 다른 브랜치의 커밋 이력 위에서 mater브랜치를 기준으로 다른 브랜치의 커밋이력을 깔끔하게 재정렬한다.

주의할 점

  • 커밋 이력이 재정렬되어 다른 새로운 해쉬 ID가 부여된다.
  • 만약 master 브랜치에서 다른 브랜치를 기준으로 rebase를 실행하면 master커밋 이력이 변하므로 master브랜치에서 다른 브랜치를 기준으로 rebase를 하는 경우는 피하는 것이 좋을 것이다.

🔹 git 충돌 수정

충돌 해결후
git add .
git rebase --continue 명령어를 입력해 커밋 순서대로 충돌내역을 계속해 해결해주면 된다.
rebase를 진행하기 전 상황으로 돌아가기 위해서는 git rebase --abort를 하면 된다.


🔹 push

git push origin 브랜치명 -f
rebase는 commit history를 정리하는 역할을 하기 때문에 같은 브랜치에서 rebase를 할 때마다 history가 달라질 수 있다.git은 history가 다른 브랜치의 푸시를 허용하지 않기 때문에 force push를 진행해야 한다.


브랜치 명 수정하기

rework

커밋 메시지를 변경할 커밋 앞에 reword 명령어를 입력해 수정한다.
커밋 메시지를 변경할 경우 커밋의 해시값도 변경된다.

🔸 edit

커밋 메시지와 작업내용을 변경한다.
변경할 커밋을 edit으로 바꿔 저장 후 종류하면
변경할 커밋으로 checkout되는데, 이때 수정하면 된다.

🔸 변경사항 저장

git add .
git commit --amend -m "변경할 커밋 메시지"
git rebase --continue

🔸 drop

커밋 히스토리에서 커밋을 삭제하는 것으로, drop으로 변경후 저장하면 해당 커밋이 drop된다.


🔹 rebase를 사용한 Git Flow

실제로 rebase를 사용해 실무에서는 어떻게 Git Flow를 가져가는지 궁금해서 찾아보다가
우아한 형제들의 기술블로그를 참고했다.

다음의 예시는 우아한 형제들의 기술블로그에서 소개한 하나의 티켓(기능을 구현하기 위해 나눈 작업의 세부단위)을 처리하는 과정이다. 예) - 로그인 레이아웃 생성

  1. upstream/feature-user 브랜치에서 작업 브랜치를 생성합니다
  • git fetch upstream
  • $ git checkout -b bfm-100_login_layout –track upstream/feature-user
  1. 작업 브랜치에서 소스코드를 수정합니다. (뚝딱뚝딱 :hammer:)

  2. 작업 브랜치에서 변경사항을 커밋합니다. (보통은 vi editor에서 커밋 메세지를 작성 함)
    (bfm-100_login_layout)]$ git commit -m "BFM-100 로그인 화면 레이아웃 생성"

  3. 만약 커밋이 불필요하게 어려 개로 나뉘어져 있다면 squash를 합니다. (커밋 2개를 합쳐야 한다면)
    (bfm-100_login_layout)]$ git rebase -i HEAD~2

5. 작업 브랜치를 upstream/feature-user에 rebase합니다.
(bfm-100_login_layout)]$ git pull –rebase upstream feature-user

push와 PR을 제출하기전, 여기에서 rebase를 한다.

동료와 같은 기능을 개발하면 하나의 feature 브랜치에 커밋을 하게 된다. 같은 커밋에서 시작하면 feature 브랜치에 하나씩 merge할 수도, 다른 커밋과 엮여서 머지되기도 한다. 머지할 때는 새로운 머지커밋이 생성되기 때문이다.

이렇게 되면 커밋 그래프가 복잡해지고 이력확인도 어려워지므로 커밋을 순차적으로 만드는 것이 필요하다.
작업한 커밋이 feature브랜치의 최신 상태에서 시작하도록 rebase를 수행하는 것이다.

rebase를 수정하면 그래프가 이렇게 단순화된다.



Reference

profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.

0개의 댓글