관련지식
git, sourcetree, rebase, squash

git으로 형상관리를 할때 git에 commit/push 시점을 언제 할 것인지는 프로젝트에서 어떻게 정할지에 따라 달라집니다. 그런데 간혹 여러개의 커밋이 모두 한 작업에 대한 커밋일수도 있습니다. 그럴때 커밋을 하나로 합치는 것이 이력 관리상 보기에 더 좋을것입니다. 어떻게 하면 되는지 알아보겠습니다.

이력 정리는 rebase를 통해 할 수 있습니다. 다만 git 관리 툴 마다 리베이스 방식이 조금 달라지는데 소스트리에서는 rebase 명령어를 이용한 squash를 제공하고 있습니다.(squash는 깃의 명령어가 아닙니다.)

아래 이미지에서 가장 최근 이력부터 ‘youtube-dl 다운 추가중’ 은 모두 한 작업입니다.
다만 어떤 이유로 인해 개발이 완료되지 않은채 여러번 커밋했어야 했을 뿐입니다.

병합하고 싶은 이력중 가장 오래된 이력의 바로 앞 이력을 선택하고 마우스 우클릭을 합니다.

‘Rebase children of ~~~~ interactively…’ 를 클릭합니다. 그러면 아래와 같이 선택한 이력 이후의 이력만 목록화 되어있는것을 보실 수 있습니다.

이력 하나를 선택하면 하단에 있는 squash 버튼이 활성화 됩니다.

버튼의 이름 처럼 이전 이력과 병합하는 버튼입니다. 계속 클릭해서 원하는 위치까지 병합합니다.

저렇게 합쳐진 이력은 이후에 한개의 이력으로 바뀔 것입니다. 이력에 걸맞는 이력이름으로 바꿔야겠죠? 하단에 ‘Edit Message’ 를 눌러 변경합니다.

이제 ‘OK’를 클릭하면 완료 됩니다. squash는 임시로 새로운 브랜치를 생성하는 방식이기 때문에 최신이력~병합이력 사이의 이력 갯수가 많을수록 오래 걸립니다. 잠시후 작업이 끝나면 아래 처럼 새로운 커밋이 만들어진 것을 볼수 있습니다.

주목할 것은 pull 건수가 9개 있는 것입니다. 이것은 로컬 저장소와 원격 저장소의 히스토리 이력이 다르기 때문에 발생한 것입니다. 서버쪽 이력은 스쿼시가 안된 상태의 이력이므로 로컬 저장소의 이력으로 덮어쓸 것입니다. ‘push’를 클릭합니다.

로컬 저장소와 서버 저장소의 이력이 다르기 때문에 원래는 push가 안되지만 밑에 있는 ‘Force Push’ 를 체크하고 푸시하면 로컬의 이력으로 서버 이력을 엎어칠수 있습니다. 간단하죠?

그런데 같은 원격 저장소를 사용하는 다른 클라이언트는 여전히 과거의 이력을 가지고 있을것입니다. 이 저장소들을 서버 이력으로 엎어치기 위해서는 과거 이력으로 reset 시킨후에 pull을 받아야 합니다. 그 과정에서 작업중인 내역이 사라지지 않도록 주의하셔야 합니다. 끝!