rebase
rebase 는 브랜치의 분기 이후의 커밋들을 부모 브랜치의 최근 커밋 위로 재배치 해주는 작업입니다.
rebase 를 진행하는 방식은 크게 두 가지가 있습니다.
- 아래와 같이 실행하면 develop 브랜치의 분기 이후의 커밋들을 main 브랜치의 최근 커밋 위로 재배치 해줍니다.
git switch develop # develop 브랜치로 이동
git rebase main # main 브랜치로 rebase
- 아래는 -i 옵션을 사용하여 리베이스 작업을 인터랙티브하게 진행하는 방식입니다. git rebase -i 명령어를 사용하면 단순히 git rebase 했을때와 다르게 리베이스 과정 중에 커밋을 수정, 삭제, 합치기 등 세부적으로 제어할 수 있습니다.
git switch develop # develop 브랜치로 이동
git rebase -i main # main 브랜치로 인터랙티브하게 rebase
리베이스 편집기에서 명령어 오타, 혹은 논리적 오류 등으로 인해 작업 설정에 오류가 발생했을 경우 경우 git rebase --edit-todo 를 통해 리베이스 편집기를 다시 열어 리베이스 todo 리스트를 다시 수정한 후 편집기를 닫고 git rebase --continue 를 입력해주면 다음 단계로 정상적으로 넘어갑니다.
rebase 진행중에 리베이스 충돌이 발생하면 (pick, squash 모두) 그때마다 충돌을 해결하고 수정 파일을 스테이징 영역에 추가한 후 git rebase --continue 를 입력해주면 커밋 메시지를 수정할 수 있는 편집창이 나타나며 (pick 의 경우 하나의 커밋에 대해, squash 의 경우 여러 커밋을 합친 커밋에 대해) 커밋 메시지 작성 후 다음 작업으로 넘어갑니다.
git add <conflicted-files> # 리베이스 충돌 파일 수정 후 스테이징 영역에 추가
git rebase --continue # 리베이스 재개
리베이스 충돌이 발생하지 않았을 경우 pick 의 경우 커밋 메시지 수정 없이 바로 다음 작업으로 넘어가며, squash 의 경우 연달아 나오는 squash 의 마지막 커밋까지 합친 커밋의 커밋 메시지를 작성하는 편집창이 나타납니다.
rebase 가 완료되면 아래와 같이 분기된 브랜치의 분기 이후의 커밋들이 부모 브랜치의 최근 커밋 위로 재배치되어 커밋 히스토리가 선형적으로 이어집니다.
squash
브랜치 squash 는 브랜치 내 여러 개의 커밋을 하나의 커밋으로 압축하는 작업입니다. 이는 PR 을 올릴때 깔끔한 히스토리를 유지할 수 있게 도와줍니다. git rebase 를 통해 squash 를 진행할 수 있으며 그 과정은 다음과 같습니다.
1. 압축하고자하는 브랜치에서 git rebase -i 명령어를 사용하여 인터랙티브 리베이스 모드에 진입합니다.
git switch develop # develop 브랜치로 이동
git rebase -i HEAD~6 # 가장 최근 커밋 여섯 개에 대해 squash 관련 설정 지정
2. 리베이스 편집기에서 squash 할 커밋을 선택합니다. pick 을 사용하면 해당 커밋을 그대로 유지하며 squash 를 사용하면 해당 커밋을 이전 커밋과 합칩니다. 아래 예시의 경우 ghi9012 는 def5678 로, mno7890, pqr1234 은 jkl3456 으로 squash 됩니다.
pick abc1234 First commit
pick def5678 Second commit
squash ghi9012 Third commit
pick jkl3456 Fourth commit
squash mno7890 Fifth commit
squash pqr1234 Sixth commit
가장 맨 위의 커밋이 가장 과거의 커밋이며 아래로 갈수록 최근 커밋입니다.
3. squash 작업 설정을 완료하면 Git 은 새로운 커밋 메시지를 작성할 수 있는 편집기를 열어줍니다. 이 곳에서 새로운 커밋 메시지를 작성하거나, 기존 커밋 메시지를 조합하여 자유롭게 편집할 수 있습니다. 위의 예시와 같이 커밋이 압축되는 지점이 두 군데라면 커밋 메시지 또한 두 번 작성하게 됩니다.
git merge --squash
브랜치 병합시 --squash 옵션을 사용하면 대상 브랜치의 커밋을 하나의 커밋으로 압축하여 병합을 진행할 수 있습니다.
git switch main # main 브랜치로 이동
git merge --squash develop # develop 브랜치 squash 하여 병합
병합 충돌이 발생했을 경우 기존 병합 충돌 처리 방식과 동일하게 병합 충돌이 발생한 파일을 수정한 후 수정 파일을 스테이징 영역으로 이동한 뒤 커밋을 진행하면 됩니다.
병합 충돌이 발생하지 않았을 경우 git merge --squash 는 병합 커밋과 구분되는 동작을 의도한 설계 원칙 때문에 자동으로 커밋을 생성하지 않습니다. 따라서 다음과 같이 직접 커밋을 진행해주어야 병합이 완료됩니다.
git commit # 커밋 진행 (자동 생성 커밋 메시지 사용 혹은 수정)
squash 를 통해 병합을 진행하면 아래와 같이 병합 커밋은 생성되지 않습니다. 즉, 병합 기록이 남지 않고 하나의 커밋이 선형적으로 이어집니다.
이 작업은 git rebase -i 를 통해서도 동일하게 수행할 수 있습니다.
git switch develop # develop 브랜치로 이동
git rebase -i main # 가장 과거의 커밋만 pick, 나머지 커밋은 모두 squash
git switch main # main 브랜치로 이동
git merge develop # develop 브랜치와 병합
두 접근 방식 모두 main 브랜치에 하나의 커밋으로 병합되며, 결과는 동일하지만 과정에서의 차이가 발생합니다. git merge --squash develop 은 develop 브랜치를 그대로 유지하지만 git rebase -i develop 은 develop 브랜치의 히스토리를 정리하는 과정이 포함됩니다.
'Dev > VCS' 카테고리의 다른 글
Git 태그 (2) | 2024.12.31 |
---|---|
Git 브랜치 삭제 (3) | 2024.12.29 |
Git fast-forward merge, 3-way merge (0) | 2024.12.24 |
Git 협업 방법 clone, fork (2) | 2024.12.17 |
Git 원격 브랜치, 원격 추적 브랜치, 트래킹 브랜치 (4) | 2024.12.17 |