여러 사람이 한 프로젝트(레포지토리)에서 협업 할 때에는 브랜치 관리가 필수적이다. 다른 말로 표현하면 혼자 한 프로젝트를 전담한다면 git에서 브랜치 관리가 크게 중요하지 않다. 과거의 나는 대부분 혼자(혹은 두어명이) 하나의 레포를 전부 관리했었고, 그러다 보니 git의 다양한 커맨드를 사용할 일이 없었다. 그러다 보니 가끔 충돌이 발생할 때 문제를 해결하는 방법에 대해서도 민망할 정도로 무지한 편이었다.
그러다 최근에 git의 다양한 커맨드를 알게 되어 잘 사용하고 있는데, 사용할수록 그동안 모르고 살았던 시간이 아깝다는 생각이 들었고 (ㅋㅋㅋ) 많은 사람들이 git rebase 를 비롯한 다양한 기능을 편하게 사용하길 바라며 내용을 정리해보고자 한다.
✅ git rebase
다른 사람과 협업하기 위해 commit message를 간결하고 명확하게 남겨야 한다는 건 대부분의 사람들이 알고 있을 것이다. 그런데 문제는 현실 세계에선 그를 지키기가 생각보다 어렵다는 점이다. 또한 브랜치 관리 전략에 따라 여러 브랜치를 분기되었다면, 병합 지점에 따라 그래프의 복잡도가 꽤 높아지기도 한다.
디버깅을 한다거나 히스토리를 트래킹 해야 하는 상황에서 이런 그래프를 마주친다면 (피하고 싶지만...) 고도의 집중력을 발휘해 어디서 분기되어서 어디서 병합되었는지를 눈으로 따라가야 한다. 이런 상황들을 해소하기 위해 git rebase를 사용할 수 있다.
공식 문서에서는 rebase를 다시 지정이라 번역하고 있다. 대부분 아래의 두 상황을 다시 지정하기 위한 기능이라고 보면 된다.
- 이전 커밋 메시지를 수정하나 여러 커밋을 합치는 등의 커밋 정리
- 브랜치가 분기된 시점 이후로 분기된 브랜치로부터 업데이트가 있었다면 분기되는 지점을 최신화
이제 각각의 사례에서 어떻게 사용하는지 확인해보자.
✅ 이전 commit 정리하기
본격적으로 commit을 정리하기 전에 아래와 같은 작업 내역이 있다고 가정해보자. 우리가 작업할 내용은 feature/group 브랜치다.
여기서 이 브랜치 위에서 작업한 커밋은 총 네 개이기 때문에 HEAD로부터 4개의 커밋을 수정하기 위해 아래와 같이 입력할 수 있다.
$ git rebase -i HEAD~4
커맨드를 입력했다면 아래와 같은 창이 띄워질 것이다. commit hash를 통해 확인해보자. 가장 최근의 커밋이 가장 아래에 보인다. 그 아래로는 주석처리 되어 있는 git rebase에서 사용할 수 있는 커맨드를 확인할 수 있을 것이다. 우리는 그 중에서도 squash를 사용해볼 예정이다.
[참고]
p, pick = 커밋을 그대로 사용
r, reword = 커밋 메시지를 변경
e, edit = 커밋의 변경 내역을 수정
s, squash = 해당하는 커밋을 이전 커밋에 병합
f, fixup = sqaush 와 유사하지만 해당하는 커밋 메시지를 삭제
x, exec = shell에서 실행하는 커맨드
우리는 가장 아래의 두 커밋을 합치고 싶기 때문에 bc69bde를 pick하고 7b89a60를 squash하도록 한다.
아래처럼 파일을 작성하면 아래의 화면처럼 커밋 메시지 중 어떤 것으로 사용하고 싶은지를 지정할 수 있다. #을 통해 주석처리 시킬 수 있다. 이 커밋의 경우 두 커밋의 내용이 동일하기 때문에 하나를 주석처리 시켰다.
두 커밋을 합친 후에는 변경된 내역을 확인할 수 있다. 그리고 git log 그래프 옵션을 통해 브랜치를 확인해보면 커밋해시가 변경된 것을 확인할 수 있다.
이를 리모트에 올려야 하는데, 당연하게도 리모트의 해시와 달라졌기 때문에 git push 하는 과정에서 --force 옵션을 사용해주어야 한다.
$ git push --force
push가 완료된 후 다시 브랜치를 확인해보면 아래와 같이 새롭게 변경된 커밋 해시로 업데이트 된 커밋 히스토리를 확인할 수 있다.
🚫 위의 예시들을 통해 rebase를 사용하면 브랜치를 깔끔하게 관리할 수 있다는 사실을 알게 되겠지만, 이미 github에 올라간 커밋을 수정한다는 것은 협업을 하는 관점에서 위험한 일이기도 하다. 가능한 협업이 진행되고 있는 브랜치에서는 git push --force를 사용하지 않도록 주의해야 한다.
✅ 정리하며
이번 글에서는 git rebase가 무엇인지 그리고 interactive 옵션 중 squash 커맨드를 사용하여 간단하게 커밋 히스토리를 정리해보았다.
다음 글에서는 여기에 이어서 브랜치를 관리하는 방법에 대해서 알아보자.
✅ References
- Github Docs: About git rebase
- 좋지 않은 사례 1: very large tree what is wrong with our branch workflow and how to fix it
'개발 > Backend' 카테고리의 다른 글
HTTP/3, HTTP over QUIC (0) | 2022.07.24 |
---|---|
프로세스(Process)와 스레드(Thread) (0) | 2021.08.15 |
[redis] redis의 데이터 타입 (0) | 2021.06.17 |
[chrome dev summit 2021] Payment and address form best practices (0) | 2021.06.10 |
[kafka] Kafka란 (0) | 2021.01.28 |