위 스크린샷에서 m 은 master, f 는 feature 이다.
master 에서 git pull origin master 를 하여 master 에서 변경사항이 생겼을 때, feature 에서는 최신화를 위해 git merge master 를 통해 최신화 시킨다.
이것이 merge 이다.
이때 merge commit 이 발생한다. 이로 인해 history 가 지저분해 보일 수 있다.
이를 해결할 수 있는 것이 git rebase
이다.
feature branch 가 초기 master 시점에서 파졌다면, 그 이후의 master 내용은 feature 가 갖고 잊지 않다. 여기서 git rebase 를 사용하면 master 의 최종 버전으로 feature 를 붙일 수 있다. 이때 master 는 영향을 받지 않고 그대로 feature 에만 적용된다.
rebase 라는 단어의 의미를 생각해 보자.
base 가 되는 부분을 재설정한다는 의미이다.
하지만 이렇게 rebase 를 하게 되면 history 를 건드리게 된다.
이 경우, push 를 하려고 해도 git 에서 history 의 문제로 push 를 막게 된다.
이 때, git push origin feature --force
라는 명령어를 사용하면 강제로 push 를 할 수 있게 된다.
이 상황을 어느정도 재현해 보겠다.
깃헙에서 연습용 repo 를 클론받아 곧바로 feature branch 를 생성한 뒤 커밋을 3개 남겼다.
마스터 브랜치로 이동해서 git log 를 확인해 보면 당연하게도 feature 브랜치에 쌓였던 log 는 존재하지 않는다.
그대로 마스터브랜치에서 어떠한 작업을 한 후 commit 을 하면 repo 에서 pull 받은 상황을 재현할 수 있다.
이제부터 rebase 를 시작하려 한다.
현재 master 브랜치에서 git log 를 해보면 나의 커밋인
"commit one from master"
의 base 가 되는 커밋은 태현님의 커밋이다.
이부분에서 feature 브랜치를 생성했으므로 feature 브랜치의 base 역시 git log 를 통해 살펴보면 당연히 동일하다.
이제 feature 브랜치에서
git rebase -i master
라는 명령어를 입력해 보자.
이 때 squash 를 사용할 수 있다.
첫번째 줄을 제외한 나머지 줄을 squash 를 의미하는 s 로 바꿔준다.
저장을 하면 아래와 같은 화면이 뜬다.
이 상황에서 커밋 메세지를 모두 합칠 수가 있다.
모든 커밋 메세지를 지우고 이를 통합할 커밋 메세지를 남긴 후 저장을 한다.
(tip: 커밋 메세지를 지울 때 dd 를 입력하면 한줄을 통째로 지울수 있다.)
이제 git log 를 통해 확인해 보면
원래 base 였던 태현님의 커밋 => 내가 마스터에서 남긴 commit => squash 를 통한 최종 결과물
즉 base 가 마스터의 최종 커밋으로 바뀐 것을 확인할 수 있다.
이제 git push origin feature
명령어를 입력해보고, 안될 시
git push origin feature --force
를 입력하자.
git rebase --abort
git rebase --continue