git rebase

2023. 11. 29. 01:34Git

728x90
반응형

💻 git rebase

git에는 한 브랜치를 다른 브랜치와 합치는 방법이 merge명령어 이외에도 하나 더 있는데

 

그것이 rebase명령어이다.

git rebasegit merge와 같이 브랜치를 병합할때 사용한다. 그렇다면 rebase는 언제 사용하는 것일까?


➡️ commit history를 commit이 적용된 순서대로 남기고 싶을때

예를 들어 아래 그림과 같은 commit history가 있다고 가정해보자.

<그림1. main과 develop 브랜치를 병합하기 전>

develop 브랜치는 c2 commit에서 분기되어 변경사항을 c4 commit에 저장하였다.

 

main 브랜치는 c2 commit 이후에 c3 commit의 변경사항이 이미 적용되어있다.

 

만일 내가 이 프로젝트를 관리하는 PM이라면 아래 그림과 같이, 나중에 적용되는 c4 commit이 c3 commit 다음으로 오는 것이 history를 직관적으로 관리하기 편할 것이다.

<그림2. 내가 의도한 병합 후 commit history>

하지만 git merge develop 명령어를 사용하게 되면 경우에 따라 병합과정에서 c4 commit이 c3 commit 이전에 올수도 있다.

<그림3. merge 명령어로 병합 후 의도대로 history가 쌓이지 않은 상황>

이러한 상황에서 rebase 명령어를 사용하고 병합을 한다면 항상 내가 의도한, <그림2>처럼 history를 쌓을 수 있다. 어떻게 가능한 것일까?

 

rebase 명령어는 명령어 그대로 base를 다시 정하는 것이기 때문이다. 그림1의 상황으로 돌아가보자.

 

만일 <그림1>의 상황으로 돌아간 뒤 git rebase main 명령어를 친다면 아래의 <그림4>와 같이 된다.

<그림4. <그림1>에서 git rebase main 명령어를 실행한다면>

즉, 원래 c2 commit에서 분기했던 develop 브랜치가 c3 commit에서 분기한 것처럼 된 것이다.

 

이후 main 브랜치로 돌아가 develop 브랜치를 merge한다면 fast-forward 방식의 병합이 진행되어 c4 commit이 c3 commit 뒤에 그대로 쌓이게 된다.


⚠️ 주의할 점 ⚠️

rebase 명령어는 git commit history를 변경하는 것이기 때문에 혼자 사용하는 브랜치에서만 사용해야한다.

 

예를 들어 develop 브랜치를 다른 사람 두명이 각각의 로컬PC로 가져갔다고 가정해보면 아래 <그림5>와 같은 상황이 될 것이다.

<그림5. origin의 develop 브랜치를 각각 Local1, Local2로 가져옴>

여기에서 만일 Local1의 사람이 git rebase main 명령어를 실행한 후 origin develop에 force push를 했다고 가정하면 아래 <그림6>과 같이 된다.

<그림6. force push 후 상황>

이후 Local2가 작업을 끝내고 develop에 push를 하려고 해도 이미 git history가 꼬여버린 상황이기 때문에 push가 불가능하다.

 


 

Local2가 현재 develop에 작업내용을 반영하려면 다음과 같이 해야할 것이다.

 

  1. 작업내용을 어딘가에 저장
  2. origin의 develop을 다시 pull 받음
  3. 작업코드를 다시 붙힘
  4. 다시 push한다.

매우 귀찮은 일이 아닐 수 없다. 예시에서는 Local2 한명이었기에 다행이지만 협업하는 사람이 10명, 20명이라면 모두에게 눈총을 받을 것이다.

 

이러한 일이 없게 rebase나만 쓰는 브랜치에서 commit history를 정리할때만 사용하자.

 

예시에서는 develop 브랜치를 예로 들었지만 실제로 develop에서 하면 큰일난다.

최소한 develop의 자식 브랜치(feature, refactor 등등)에서 할 것

728x90
반응형