[Git] Rebase interactive

Sangwoo Park·2022년 6월 5일
0

Git

목록 보기
3/3
post-thumbnail

git으로 version control을 하다 보면 commit이 쌓입니다.

한번에 깔끔한 commit을 만들 수 있으면 좋겠지만, 사람이라면 실수를 하기 마련이죠.

종종 이전 커밋들을 수정하고싶은 경우가 생기곤 합니다.

그럴 때 유용하게 사용할 수 있는 git의 기능이 바로 rebase -i 입니다.

이 기능은 타임머신과도 같아서, 내가 원하는 시점으로 이동해 과거를 바꾸는 듯 한 기분이 들기도 합니다.

이 강력한 기능에 대해 알아보겠습니다.

1. 커밋 합치기 (Squash)

여러가지의 커밋을 하나로 합치는 기능입니다.


위와 같은 커밋의 상황이 있다고 가정해 봅시다.

이 때 두번째, 세번째, 네번째, 다섯번째 커밋을 합쳐서 하나의 커밋으로 만들고 싶어진 상황입니다.

git rebase -i HEAD~4 을 입력하면 rebase 상태로 돌입합니다.

여기서 저는 HEAD 지점으로부터 (HEAD 포함) 4개의 커밋을 합치고 싶기에 HEAD~4라고 입력합니다.


그러면 위와 같은 edit 화면이 나타나면서 Rebase Commands에 대한 설명이 친절하게 주석으로 나옵니다.
여기서 우리가 사용할 command는 s (squash) 입니다.

커밋들을 합치는 과정은 나중에 생긴 커밋들을 먼저 생긴 커밋에 합친다고 생각하면 됩니다.

따라서 합칠 커밋들 중 가장 처음 생긴 커밋만 pick으로 놔두고, 나머지 합칠 커밋들은 s 혹은 squash로 변경해주면 됩니다.

편집 콘솔에서 i를 눌러 insert 모드로 진입 한 뒤에 pick으로 되어있는 command 들을 s로 바꿔줍니다.

이제 :wq로 저장을 합니다.
(❗ 이 단계에서 :q 를 입력하면 저장이 되지 않고 rebase가 취소됩니다.)

그러면 커밋 메세지를 수정하는 단계로 이동합니다.


여기서 수정한 메세지가 합쳐진 커밋의 메세지가 될 것입니다.

저는 커밋 메세지를 깔끔하게 하나로 정리해보겠습니다.

이제 :wq 로 저장 하면 커밋이 합쳐지며, 성공 메세지가 나옵니다.

처음 봤던 커밋 히스토리 그래프를 다시 보면 두번째~다섯번째 커밋들이 하나로 합쳐진 것을 확인할 수 있습니다.

2. 실수 되돌리기

1) rebase 완료 전

아직 rebase가 끝나지 않았는데, 중간 단계에서 뭔가 꼬였을 때,
git rebase --abort를 입력하면 모든 rebase가 취소되며, rebase 시작 전의 상태로 되돌아가게 됩니다. rebase 중 만들었던 커밋이나 코드의 변화도 모두 삭제되니 유의하여 사용하세요.

2) rebase 완료 후

rebase를 사용하다 실수를 하면 예상치 못한 결과가 나올 때가 있습니다.
저도 그래서 땀이 줄줄 났던 경험이 있어요 😅
하지만 걱정하지 마세요, 언제든지 되돌릴 수 있습니다. (로컬에서는요)

침착하게 콘솔창에 git reflog를 입력합니다.


그러면 여태까지 내가 했던 커밋의 변경내역이 모두 표시됩니다. rebase를 포함해서요.

사진에 제가 테스트하다가 rebase command를 잘못 입력했다가 취소한 내역까지 모두 나왔네요 😂

rebase를 잘못해서, 다시 rebase 하기 전으로 되돌아가고 싶어졌다고 합시다.

이 때 git reset <commit> 을 하게되면 해당 commit으로 돌아가게 됩니다.

이 때, reflog가 사라지는게 아니라, 돌아간 변경사항 또한 reflog에 쌓입니다.

그럼 git reset 3e2a719를 하여 다시 커밋을 합치기 전으로 돌아가보겠습니다.

다시 reflog를 확인해보면, moving to <commit> 이라고 새로 생긴 로그를 볼 수 있으며, 커밋 히스토리를 다시 확인하면 rebase 전으로 돌아온 것을 확인 할 수 있습니다.

3. 과거의 커밋 수정하기

다시 다섯번째 커밋까지 있다고 가정하고, 두번째 커밋에 빠뜨린 게 있어 수정해야한다고 가정합시다.

이 때는

  1. 타임머신을 타고 과거로 돌아가
  2. 커밋을 수정하고
  3. 다시 현재로 돌아오면 됩니다.

그 과정을 살펴보겠습니다.

우선 git rebase -i HEAD~<n> 을 입력하여 수정하고싶은 커밋이 있는 지점으로 이동합니다.
저는 git rebase -i HEAD~4 를 입력하여 두번째 커밋 지점으로 이동했습니다.

이 때, rebase command는 edit 을 입력해 줍니다.

:wq를 입력하고 나면

You can amend the commit now, with 
	git commit --amend
Once you are satisfied with your changes, run 
	git rebase --continue

이런 안내가 나옵니다. 해석하자면 commit을 수정하고, 다 되면 git rebase --continue를 실행하라는 겁니다.

이제 커밋 히스토리를 보면 우리의 HEAD는 두번째 커밋으로 이동해있는걸 알 수 있습니다.

코드를 변경하고 나서 변경한 코드를
git add . 를 입력하여 스테이징 한 후에
git commit --amend 를 입력하여 스테이징 한 내역을 두번째 커밋에 반영합니다.

이제 다시 타임머신을 타고 현재로 돌아오겠습니다.
git rebase --continue 를 입력합니다.

성공적으로 마쳤다면, 아래와 같이 과거가 바뀌어있는 것을 확인할 수 있습니다.

4. 과거의 커밋 합치기

그럼 다시, 다섯번째 커밋까지 있다고 가정하고, 첫번째 커밋두번째 커밋을 합치고 싶어졌습니다.
그러면

  1. 합치고 싶어 진 커밋이 있는 시점까지 타임머신을 타고 돌아간 뒤
  2. 커밋들을 합치고 (Squash)
  3. 다시 현재로 돌아오면 됩니다.

지금부터 그 과정을 살펴보겠습니다.

우선 git rebase -i HEAD~<n> 을 입력하여, 합치고싶은 커밋이 있는 지점으로 이동합니다.
저는 git rebase -i HEAD~4 를 입력해 두번째 커밋 지점으로 이동했습니다.

두번째 커밋을 reset 하여 첫번째 커밋에 합쳐보겠습니다.

git reset HEAD~1 을 입력하여, 현재 커밋의 변경사항은 유지한 채, 바로 이전의 커밋까지 reset 합니다. (git reset의 사용법을 알고 있다고 가정하겠습니다.)
만약 내가 5개의 커밋을 합치고싶다면, git reset HEAD~4를 입력하면 되겠죠?

이제 첫번째 커밋을 수정하여 (구)두번째 커밋의 변경내역을 합쳐줍시다.
git add . 를 입력하여 현재의 변경 내역을 스테이징 한 후에
git commit --amend 를 입력하여 스테이징 된 내역을 첫번째 커밋에 반영합니다.
편집기에서 커밋 메세지를 수정하는 과정을 거치고 나면 (insert 모드에서 메세지 수정 + :wq로 저장)
첫번째 커밋두번째 커밋을 성공적으로 합친 것을 확인할 수 있습니다.

그 때의 커밋 히스토리 그래프는 아래와 같습니다.
(아직 우리는 rebase중이라는 것을 잊지 마세요!)

이제 수정을 마쳤으니, 다시 타임머신을 타고 현재로 돌아갈 차례입니다.
git rebase --continue 를 입력하면 끝입니다.

성공적으로 rebase가 된 이후의 커밋 히스토리 그래프를 봅시다.

성공적으로 첫번째와 두번째 커밋이 합쳐졌습니다! 😀


마치며

rebase interactive에 대해 알아보았습니다. 버전을 강력하게 컨트롤 할 수 있지만 처음 접하면 조금 복잡해 보일 수 있어요.

하지만 abort, reflog 등을 이용하여 되돌릴 수 있는 방법이 있으니, 걱정 말고 충분히 연습하면 금방 익숙해져서 유용하게 사용할 수 있는 좋은 기능이라고 생각해요.

제가 주로 사용하는 방법에 대해서 포스팅했지만, interactive를 활용하는 방법은 더 많이 있으니 직접 문서를 읽으며 탐구하는것도 재밌을 것 같아요.
긴 글 읽어주셔서 감사합니다!

profile
going up

0개의 댓글