git rebase & squash

1. 목적

  • 그동안 내가 써온 git의 기본적인 merge 방식은 다음과 같다

스크린샷, 2019-11-17 22-00-11.png

  • 마스터에서 따온 베이스와 일어난 커밋 두개(f1, f2)를 병합하여 새로운 커밋을 만들어 이를 마스터에 적용시킨다.

  • 얼핏 보기에 별 문제가 없어보일 수 있지만, 이런식의 머지 방식을 가지게되면 문제가 2가지 발생한다.

    1. 커밋이 일어난 시점이 전부 제각각이라 어떤부분이 먼저 병합되었는지 추적이 힘듦
    2. 커밋이 일어날때마다 메시지가 쌓이게됨
  • 이를 각각 해결하기 위해 git rebase(1)와 squash(2)를 각각 쓰게된다.

2. How to rebase & squash

  • 이제 우리가 하게될 리베이스는 다음과 같다.

스크린샷, 2019-11-17 22-07-33.png

  • 그림을 해설해 보자면 다음과 같다.

    1. 내 커밋은 마스터의 가장 최근 버전에 병합된다는것.
    2. 내 브랜치에서 일어난 커밋은 단 한번이라는것.
  • rebase와 squash는 다음과 같이 진행한다.

    1. 마스터를 가장 최근의 버전으로 땡긴다.

       git pull
    2. 리베이스 하고싶은 브랜치에서 다음 명령어를 입력한다.

       git rebase -i master 브랜치명
    3. 내가 커밋을 2번이상 진행했다면 열리는 대화창에는 다음과 같은 내용이 보일것이다.

       pick asdfsfdasdfasdfasdfasdfasdf
       pick asdfasdfasdfsdfsdf
       pick asdfsadfasdfasdfasdfasdf

      (화면을 캡쳐하지못해 asd로 대충 표현해보았다;)

    4. pick이후의 내용은 각각의 commit을 의미한다. 결국 저렇게 pick이 3줄이 나왔다면, 내가 3번의 커밋을 했다는 뜻이며, 이를 하나로 줄여주어야 한다.

    5. 머지할 내용의 첫 커밋만 pick으로 둔 후 나머지는 s로 바꾸어준다.

       pick asdfsfdasdfasdfasdfasdfasdf
       s    asdfasdfasdfsdfsdf
       s    asdfsadfasdfasdfasdfasdf
    6. Ctrl+X를 눌러 나가주면 커밋메시지를 정리할 수 있는 창이 뜬다. 이 단계에서 내가 남기고싶은 커밋 메세지를 짧게 남겨준 후 다시 Ctrl+X를 눌러준다

    7. 만약 이 과정에서 Conflict가 발생하지 않았다면 성공한것이므로 작업이 끝났다면 푸시하면 된다.

    8. 만약 컨플릭트가 났다면, 충돌이 난 후 git rebase --continue를 눌러 다시 진행해준다.

    9. 만약 내가 브랜치를 push한 시점과 rebase한 시점사이에 merge가 일어났다면, 내 브랜치는 이전의 푸시로 인해 push할 목표브랜치를 이전 시점으로 기억하고 있다. 이 경우에는 force push (강제푸시)를 사용해 푸시를 진행해야한다.

      git push -f origin branchname