rebase

정민교·2023년 6월 6일
3

git

목록 보기
22/22
post-thumbnail

git rebase는 꼭 알아야 하는 것은 아니지만 알아두면 매우 유용한 기능입니다.

꼭 알아야 하는 것은 아니라고 말한 이유는 굳이 rebase를 몰라도 깃을 사용하는데 문제가 없기 때문입니다.

git rebase 를 사용하는 이유는 크게 두 가지 입니다.

  1. git merge 대신 사용
  2. 커밋(깃 히스토리)를 지우기 위해 사용

git rebase 는 알아두면 매우 유용하다고 이야기 하였지만,

언제 rebase를 쓰면 좋은지 언제 쓰지 말아야 하는지 상황을 꼭 알고 있어야 유용하게 사용할 수 있습니다.

✔️git merge 대신 사용

git merge와 git rebase 모두 두 개의 브랜치를 하나로 병합하기 위해 사용할 수 있습니다.

그럼 왜 이 기능을 두 명령어가 가능하도록 했을까요?

merge 시 발생하는 문제를 rebase가 해결하는 상황을 살펴봅시다.

위와 같이 master 브랜치의 두 번째 커밋에서 feature 브랜치를 생성하였습니다.

그리고 2개의 추가 커밋을 생성했는데, 팀원 중 누군가가 작업을 완료해서

matser 브랜치에 PR을 하고 승인이 되었던, 직접 push를 했던 master 브랜치에 새로운 변경사항이 생겼습니다.

저는 feature 브랜치에서 작업 중이었는데 master 브랜치의 새로운 내용도 빨리 feature 브랜치에 포함시키고 나머지 작업을 이어나가고 싶습니다.

그래서 merge 를 진행했습니다.

git merge master

masterfeature 에 서로 모르는 커밋 이력이 존재하기 때문에 fast-forward가 아닌 커밋 메세지를 생성하는 병합이 이루어졌습니다.

이렇게 또 작업을 이어나가던 중 누군가 또 master 브랜치에 push 를 해서 master 브랜치에 변경사항이 생겼습니다.

merge 합니다.

제가 이 feature 브랜치에서 일을 오래하면 할 수록,

팀원들이 일을 많이 해서 master 브랜치에 새로운 변경사항이 쌓이면 쌓일수록

feature 브랜치에는 계속해서 저 merge commit이 생겨날 것 입니다.

이렇게 계속 merge commit이 생기면 히스토리가 너무 지저분해지고, 이력을 파악하기가 힘들어집니다.

rebase는 merge가 아닌 방법으로 브랜치를 병합하는 기능입니다.

rebase를 하면 커밋 히스토리를 재작성 합니다.

git rebase master

feature 브랜치에 있는 상태에서 위 명령을 실행합니다.

feature 브랜치의 base를 master 브랜치로 재설정하겠다 이런 뜻입니다.(merge랑 헷갈려서...)

위 그림을 보면 알 수 있듯, feature 브랜치를 생성한 시점은 master 브랜치의 두 번째 커밋인데

feature 브랜치의 시작이 master 브랜치의 끝이 되었습니다.

git rebase는 특정 브랜치(여기서는 feature 브랜치빙빈다.에 생성되어 있던 각 커밋을 새로 생성(커맷 해시가 바뀝니다)하고,

커밋 히스토리를 새롭게 구성(커밋들을 재배치)하여, 브랜치의 베이스를 새로 설정하는 작업을 하는 것이 rebase 작업입니다.

master 브랜치에는 아무 영향이 없습니다.

커밋이 생성된 순서를 바꾸는 것은 아닙니다. 각 커밋마다 생성된 날짜 정보는 보존됩니다.

다른 사람들도 가지고 있는 커밋들이 있는 브랜치(공유된 커밋이 있는 브랜치)를 rebase 하면 안됩니다.

즉, 다른 사람들에게는 없는 커밋이 내 컴퓨터에 있을 때만 rebase 를 사용해야 합니다.

rebase 는 커밋을 새로 생성한다고 했습니다. 원래 커밋 해시가 아닌 새로운 커밋 해시가 생기는데요,

다른 사람들도 다 가지고 있는 commit들이었는데 제가 갑자기 그 커밋들을 지우고 새로 생성한다면 말도 안되는 혼란이 생길 것 입니다.

말 그대로 나 빼고 모든 사람들이 내가 없는 커밋을 가지고 있고, 나만 다른 사람들은 없는 커밋을 가지고 있는 상황이 되는 것이니까요.

예를 들면, feature 브랜치는 내가 로컬에서 생성한 브랜치고 여기서 작업해서 커밋한 커밋들을 push 한 적 이 없습니다.

그렇다면 현재 feature 브랜치에서 가지고 있는 커밋들은 남들은 모르고 나만 가지고 있는 커밋입니다.

따라서 feature 브랜치를 rebase 하는 것은 괜찮습니다.

하지만 master, dev 등 공통적으로 사용하는 브랜치들을 rebase 한다면 문제가 발생할 것입니다.

결론적으로, 내가 작업하는 브랜치만 rebase 해야 합니다.

📌git rebase 충돌

git rebase 를 하는 과정에서도 충돌이 발생할 수 있습니다.

rebase 도중 충돌이 발생하면 rebase 가 잠시 멈추며,

git rebase --abort

rebase 를 취소하거나 혹은 충돌을 해결하여 충돌된 파일을 add 한 후에

git rebase --continue

위 명령을 실행해 rebase 를 마저 진행하라고 안내가 나옵니다.

충돌을 너무 무서워 할 필요가 없습니다.

merge 혹은 rebase 도중 충돌이 발생했으면 충돌이 난 파일을 확인하고,

merge commit을 남기거나 rebase를 마저 진행하면 됩니다. 이 절차는 git이 다 알려주니까 출력 문구를 잘 읽어보는 것이 도움이 많이 됩니다.

✔️커밋 히스토리를 조작하기 위해 사용

커밋 메세지를 변경하거나 커밋 본문을 변경할 수도 있고, 커밋을 제거 혹은 합칠 수도 있습니다.

특정 브랜치를 생성해서 작업하고 있다고 가정합니다.

꽤 오래 작업을 진행하다보니 퇴근을 해야할 시간이 됐고, 집에서 다시 마저 해보고 싶은 생각이 들었습니다.

그래서 일단 커밋을 진행해야 할 상황입니다.

버그가 있을 수도, 미완인 상태일 수도 있지만 커밋을 진행하고 원격 브랜치로 push 합니다.

하지만 push 하기 전에 깔끔하게 다듬고 커밋 메세지도 좀 유의미 혹은 혹시라도 지키지 못한 회사 커밋 규칙에 맞게 수정하고 싶은데 그냥 올리는 것이 너무 찜찜합니다.

재작성 할 수 있다면 정말 편하지 않을까요?

git rebase -i HEAD~4 # -i 는 interactive 를 의미

현재 브랜치를 어디 브랜치로 rebase 하는 지 명시하지 않습니다. HEAD 기준 4개 이전의 커밋이 rebase 기준이 된다고 생각하면 됩니다.

현재 브랜치를 다른 브랜치로 rebase 하는 것이 아니고, 명시한 범위 내의 모든 커밋을 현재 브랜치의 끝으로 rebase 합니다.

이 범위 안에 있는 커밋들을 하나씩 새로 다시 생성되겠죠. 재생성된 커밋은 이전 커밋과는 별개의 커밋입니다.

커밋 해시가 달라지기 때문입니다.

-i 옵션을 주면 interacitve 모드가 활성화 되고 커밋 이름을 변경하거나 커밋을 제거할 수 있습니다.

pick - 이 커밋을 사용, 바꾸지 않고 그대로 유지
reword - 이 커밋을 사용하는 대신 다른 커밋 메세지로 수정
edit - 이 커밋 코드(내용)를 수정하고 커밋 메세지 또한 수정 가능
fixup - 이 커밋의 코드를 이전 커밋으로 병합하고 커밋 메세지는 제거
drop - 이 커밋 제거

참고로 가장 최큰 커밋을 수정하는 명령은 아래와 같습니다.

git commit --amend

amend 를 수행하기 전에 코드를 수정하고 add 한 후 amend 를 실행하면

수정한 코드도 포함하여 커밋이 수정됩니다.

profile
백엔드 개발자

0개의 댓글