본문 바로가기
Git

git rebase -i 알아보기

by 봄석 2019. 9. 9.

git rebase -i 알아보기

 

git 을 사용하다 보면 , 이미 커밋한 히스토리를 변경하거나 또는 삭제하거나, 내용을 추가해야하는 상황이 자주 발생합니다.

이때 사용할수 있는 명령이 바로 $git rebase -i 입니다.

-i 는  --interactive의 약어로 말 그대로 git rebase 명령어를 대화형으로 실행하겠다는 의미입니다.

 

 

위명령어를 실행하면  '수정을 시작할 이전 커밋 ' ~ '현재 커밋(HEAD)'

범위에 있는 모든 커밋들의 리스트가 출력된다.

ex) $ git rebase -i HEAD~3을 실행하면 

-> HEAD~2 , HEAD~1, HEAD 커밋들이 출력되게 됩니다.

 

 

아래는 테스트를 위하여 미리 만들어논 커밋들 입니다.

 

 

 

git rebase 

$ git rebase -i HEAD~4

를 입력하면 아래와 같이  커밋 리스트와 , 사용할 수 있는 명령어 들에 대한 설명이 주석으로 출력됩니다.

 

본격적으로 각 명령어의 기능들에 대하여 알아보도록 하겠습니다.

 

pick

pick은 커밋을 사용하겠다는 의미입니다.

이를 이용하여 커밋의 순서를 바꿀수도 있고, 커밋의 해쉬값을 이용하여 특정 커밋을 가져올 수도 있습니다.

 

rebase 명령어를 실행하면 기본적으로 pick으로 설정되어있기 때문에 

아무것도 변경하지 않고 종료한다면, 커밋에대하여 어떠한 변경도 일어나지 않게 됩니다.

 

커밋 순서 바꾸기

커밋 two와 three의 순서를 바꿔보면 

 

before

after

커밋 히스토리에서는 커밋 순서만 변경된 것으로 보이지만, 

사실 단순히 커밋순서만 변경된것이 아니라 커밋 해쉬값또한 변경된 것을 알 수 있습니다.

 

 

reword

reword 는 커밋 메시지를 변경하는 명령입니다.

커밋메시지를 변경할 커밋 앞에 reword명령으로 수정하고, 저장하면 

해당 커밋의 메시지를 다시 작성하는 에디터 창이 열리게 됩니다("대화형이라고 하는 이유를 알 수 있습니다")

 

three와 two커밋을  reword명령어로 바꾸고 저장해보겠습니다.

three-3, two-2로 커밋메시지를 변경하였습니다.

커밋메시지는 정상적으로 변경되었고 , 커밋의 해쉬값 또한 바뀐것을 볼 수 있습니다.

 

 

edit

위에서 말한 reword는 커밋 메시지만 변경하는 명령이였다면 , edit은 커밋 메시지 뿐 아니라 

커밋의 작업 내용도 변경할 수 있는 명령입니다.

three-3라는 커밋을 edit으로 바꾸고 저장하였습니다.

 

저장후 종료하면 , 변경할 커밋으로 checkout됩니다.  그 상태에서 변경할 작업을 수행하면 됩니다.

 

위와같던 3번 함수를 아래처럼 변경하도록 하겠습니다.

 

그후 변경사항을 적용하기위해 아래처럼 입력합니다.

 

$ git add .  ->명령어로 staged상태로 변경하고

$ git commit --amend -m "변경할 커밋메시지" ->명령어로 수정된 내용을 커밋에 적용합니다.

$ git rebase --continue -> 명령어를 이용하여 rebase 를 마칩니다.

 

 

커밋내용과 메시지가 모두 변경된 것을 확인할 수 있습니다.

 

 

squash

squash는 해당 커밋을 이전 커밋과 합치는 명령어 입니다.

 

two-2  커밋을 직전 커밋인 three-3-amend커밋과 합치기 위하여 

squash 로 바꾸어 주었습니다.

저장후 종료하면 아래와 같이 커밋메시지를 수정할 수 있는 에디터 창이 뜹니다.

 

합쳐질 커밋들의 메시지를 확인한 후 , 그대로 종료하면 

이전 커밋과 하나로 합쳐진 것을 볼 수 있습니다.

 

 

fixup

fixupsquash와 동일하게 해당 커밋을 이전 커밋과 합치는 명령이지만 

커밋 메시지메시지는 합치지 않습니다. 결과적으로 이전 커밋의 메시지만 남게됩니다 .

그점만 빼면은 squash  와 동일하므로 예제는 생략하도록 하겟습니다.

 

exec

exec를 이용하면 , 각각의 커밋이 적용된 후 실행할 shell명령어를 지정할 수 있습니다.

 

각각의 커밋이 적용된 후 실행되는 것을 확인하기 위하여  커밋 중간중간에 

$ git rev-parse HEAD

명령어를 삽입하였습니다. ( HEAD가 가리키고 있는 커밋의 해쉬값을 출력해주는 명령어입니다.)

 

저장후 종료하면 아래와 같이 터미널에 출력되는것을 확인할 수 있습니다.

 

 

 

 drop

drop은 커밋 히스토리에서 커밋을 삭제하는 명령어입니다.

drop으로 바꾸고 저장해보면  해당 커밋이 drop 되는것을 확인할 수 있습니다.

 

그리고 그냥 rebase 리스트에서 해당커밋의 줄을 삭제해도 같은 효과를 볼 수 있습니다.

 

 

주의사항

$ git rebase 는

이전의 커밋 히스토리를 변경하기 때문에 항상주의하여 사용해야합니다.

만약 이미 Github처럼 같은 원격 저장소에 push까지 한 커밋이라면 변경한 커밋들은 원격 저장소에  push되지 않을 것입니다.

이때 $ git push -f 명령오로 강제로 원격 저장소에 커밋 히스토리를 덮어 쓸수도 있습니다.

만약 이전에 push한 커밋들을 다른 개발자들과 공유하고 있었다면, 커밋 히스토리의 불일치가 발생하여 

git 이 꼬이는 상황을 볼 수 있을 것입니다.

 

 

댓글2