[Git] CLI로 rebase 수행

2022. 4. 22. 16:49Git

1. rebase 사용하기

3-way 병합 사용시 병합 커밋이 생성되기 때문에 이력이 지저분해질 수 있습니다. 이와 같은 경우 rebase를 사용할 수 있습니다. rebase는 베이스 커밋을 재배치 하는 기능입니다.

 

rebase의 원리

1. HEAD와 대상 브랜치의 공통 조상을 탐색 (아래 그림의 C2)
2. 공통 조상 이후에 생성한 커밋들(C4, C5 커밋)을 대상 브랜치 뒤로 재배치를 수행

 

reset --hard 및 rebase 시도

(feature1) $ git reset --hard HEAD~ # 현재 브랜치를 한 단계 되돌림

(feature1) $ git log --oneline --graph --all -n5 # 로그 확인

(feature1) $ git rebase main # HEAD 브랜치의 커밋들을 main 브랜치로 재배치

위 rebase 수행 결과를 보면 충돌이 발생한 것을 알 수 있습니다. 충돌을 해결합니다.

 

rebase 도중 충돌 해결

(feature1|REBASE 1/1) $ git status

file1.txt 충돌 해결

(feature1|REBASE 1/1) $ git add file1.txt

(feature1|REBASE 1/1) $ git commit

 

 

file1.txt before

file1.txt after

(feature1|REBASE 1/1) $ git rebase --continue # 리베이스 계속 진행

(feature1)            $ git log --oneline --graph --all -n5 # 로그 확인

(feature1)            $ git checkout main

(main)                $ git merge feature1 # 빨리 감기 병합

 

3-way 병합과 rebase의 비교

  3-way 병합 rebase
특징 병합 커밋이 따로 생성됨 현재 커밋들을 수정하면서 대상 브랜치 위로 재배치함
장점 한번만 충돌이 발생됨 깔끔한 히스토리
단점 트리가 약간 지저분해짐 여러 번 충돌이 발생할 수 있음

 

2. 유용한 rebase 사용법 : 뻗어나온 가지 없애기

보통 커밋 만들기

(main) ch06_git-playground $ echo "main1" > main1.txt # main1.txt 파일 생성

(main) ch06_git-playground $ git add main1.txt

(main) ch06_git-playground $ git commit -m "main 커밋1"

(main) ch06_git-playground $ git push origin main

(main) ch06_git-playground $ git log --oneline -n5 # 로그 확인

 

 

가지 커밋 만들기

(main) ch06_git-playground $ git reset --hard HEAD~ # HEAD를 한단계 되돌리기

(main) ch06_git-playground $ echo "main2" > main2.txt # main2.txt 파일 생성

(main) ch06_git-playground $ git add main2.txt # 스테이징

(main) ch06_git-playground $ git commit -m "main2 커밋" # 커밋

(main) ch06_git-playground $ git log --oneline --graph --all -n5 # 로그 확인

git reset --hard HEAD~ 수행 이후

위 수행결과를 보면 로컬 저장소인 [main] 브랜치가 pull을 하지 않고 커밋을 했기 때문에 가지(origin/main)가 생겼습니다.

 

git pull 수행 결과

(main) $ git pull

(main) $ git log --oneline --graph --all -n5

위 수행결과를 보면 로컬 저장소인 [main] 브랜치가 원격 저장소 [main] 브랜치로부터 pull을 수행했을 때 병합 커밋이 생긴것을 볼 수 있습니다. 병합 커밋이 생겨서 히스토리가 좀더 복잡해졌습니다.

 

rebase로 가지 지우기

(main) $ git reset --hard HEAD~

(main) $ git rebase origin/main # rebase 수행으로 현재 커밋 재배치

(main) $ git log --oneline --all --graph -n5 # 로그 확인

(main) $ git push origin main

reset 이후

rebase 명령 이후

push 이후

 

3. rebase 주의사항

주의사항은 원격저장소에 푸시한 브랜치는 rebase 하지 않는 것이 원칙입니다.

 

4. 임시 브랜치 사용하기

원래 작업하려고 했던 브랜치의 커밋으로 임시 브랜치를 생성하고 해당 브랜치에서 병합 또는 rebase를 수행, 만약 문제가 되면 삭제하면 됩니다. 임시 브랜치의 사용은 충돌해결, merge, rebase등의 리스크를 해결해줍니다.

 

임시 브랜치 생성 사용 및 삭제

(main) ch06_git-playground $ git branch test feature1 # feature1 브랜치에서 임시 브랜치 생성

(main) ch06_git-playground $ git checkout test

(test) ch06_git-playground $ echo "test content" > test.txt

(test) ch06_git-playground $ git add test.txt

(test) ch06_git-playground $ git commit -m "test.txt 파일 추가"

(test) ch06_git-playground $ git log --oneline --graph --all -n5 # 커밋 로그 보기

 

(test) ch06_git-playground $ git rebase main

(test) ch06_git-playground $ git log --oneline --graph --all -n5

(test) ch06_git-playground $ git checkout main

(main) ch06_git-playground $ git branch -D test

위와 같이 [test] 라는 이름의 임시 브랜치를 생성한 다음에 commit, merge, rebase 등 다양한 작업을 테스트해보고 불필요해지면 삭제하면 됩니다.

 

References

source code : https://github.com/yonghwankim-dev/git_study
팀 개발을 위한 Git Github 시작하기, 정호영 진유림 저

'Git' 카테고리의 다른 글

[Git] git commit 명령의 동작 원리  (0) 2022.04.22
[Git] git add 명령의 동작 원리  (0) 2022.04.22
[Git] CLI로 3-way 병합하기  (0) 2022.04.22
[Git] CLI로 checkout 하기  (0) 2022.04.22
[Git] CLI로 브랜치 생성하기  (0) 2022.04.22