Log Stash

as an Industrial Personnel

Note

TIL: git --fixup, --autosquash

SavvyTuna 2017. 6. 23. 01:14
요즘 계속 git이야기만 쓰게 되는것 같네. 요즘 회사 게임 내부 구조 관련된것만 보니까 어쩔 수 없긴 한데..

tl;dr

git commit --fixup=<commit>

위 명령으로 현재 커밋을 하면서 특정 다른 커밋에 fixup할 것이라고 마킹을 해 놓고,

git rebase -i --autosquash <commit>

인터랙티브 모드 rebase를 --autosquash 옵션으로 열면 fixup하고 싶었던 일을 알아서 해준다. todo를 보면, 달라 붙어야 하는 커밋은 자동으로 달라 붙을 커밋 아래줄로 옮겨져 있고, 'pick'대신에 'fixup'이 작성되어 있다. 물론 리베이스를 하는 커밋 범위내에 달라 붙을 커밋이 포함되어 있어야 함. (fixup 마킹해놓은 커밋은 HEAD로 부터 7커밋 떨어져 있는데 HEAD~3을 지정해 봤자 의미 없음.)

--fixup처럼 --squash옵션도 있다.

이야기

최근 요 며칠동안 회사에서 나는 '이리저리 흩어져 있으며 의도에 맞지 않게 묶여진 타입들과, 그 타입들의 사용처들을 정리하는 일'을 하고 있었다. 어느정도 완벽히 동작하지 않으면 아예 작업내역이 공유되면 안되는 작업이었기 때문에, 나는 현재 공통 개발 브랜치인 develop에서 나만의 브랜치를 따서 작업하고 있다. 예를 들면 feature/type처럼. (실제로 내가 회사에서 쓰는 브랜치 이름은 아님)

계속 fetch받고, origin/develop을 rebase하면서 최신 코드 반영 사항을 맞춰나가고 있는데, 우연히도 팀원들이 다 내가 작업하는 곳과 다른 부분만을 작업하고 있어서 덕분에 한번도 충돌 없이 편안하게 최신화를 시켜주고 있었다.

그러다 오늘 비슷한 부분의 네이밍을 바꾸는 작은 커밋 하나가 develop에 들어왔고, 내 로컬 브랜치의 10개 정도 되는 커밋을 다시 rebase하는 사이에 자잘한 충돌이 생겼었다. (물론 네이밍 바꾸는것, 커밋 올리는것도 팀원분이 다 사전에 말하고 진행했고, 충돌 규모도 매우 작았음)

물론 리베이스 도중에 충돌을 resolve하고 나면 빌드를 하거나 테스트를 돌려서 문제가 없는지 확인해 보는게 맞지만, 유니티 리프레쉬 시키고 다시 서버 맞추고 플레이어 id 맞추고 인게임 접속해서 해당 사항 확인해보는데에 소모되는 시간이 많이 크기 때문에, 그냥 리베이스 다 끝나고 유니티에서 컴파일 에러를 확인해 보기로 했다. 물론 머지를 잘못해서 컴파일 에러가 생겼고, 그렇기 때문에 내가 이 글을 쓰고 앉아 있겠지.

컴파일 에러는 7글자정도만 수정하면 될 정도로 간단하게 해결할 수 있었다. 문제는 이 변경사항이 반영되어야 할 커밋이 HEAD로부터 7계단 멀리 있는 커밋이었다. 물론 'asdf'나 'fix me up' 따위의 성의없는 커밋 메세지로 대충 일단 커밋 해 놓고, git rebase -i HEAD~7로 인터랙티브 리베이스 세션을 연 다음, 에디터로 열려진 todo파일을, 합쳐져야 할 커밋을 합칠 커밋 아래에 놓고 'pick''fixup' 으로, 요즘은 또 귀찮아서 'f' 만으로 고쳐놓고, 다시 저장해놓는것으로 커밋을 원래 있어야 할 커밋과 합칠수는 있다.

rebase todo

라인마다 명령어('pick')를 교체하거나 행의 순서를 바꾸는것으로 커밋들을 조작할 수 있다.^1

복잡한 일은 아니지만, 합쳐져야할 목적지 커밋의 해쉬 id를 어딘가에 적어놓는게 진짜 귀찮다. 그렇다고 그냥 기억해 두자니 이번엔 그래도 fixup해야하는 커밋이 하나밖에 없어서 그렇지 보통 두 세개 생길때도 많고, 오토스태쉬에 이것저것 하다보면 리베이스 세션 열리기까지 정말 오래 걸리는데 그 때 동안 딴짓 하느라 안 잊어버릴 수가 없다.

그래서 찾아봤더니 (사실 옆자리 친구가 오래전에 알려주긴 했다만 귀담아 듣진 않았다) 커밋할 때 --fixup=<commit>이나 --squash=<commit> 옵션을 사용해서, 나중에 리베이스 할 때 달라붙을 목적지 커밋을 지정할 수 있다.

git commit --fixup=<commit id>

이런식으로. 이렇게 만들어지는 커밋의 커밋 메세지는 앞에 "fixup!" 이라는 문자열이 붙게된다. --squash도 마찬가지로 "squash!" 라고 붙고.

이렇게 커밋들을 쌓아놓고 있다가, 필요한 시점에

git rebase -i --autosquash <commit>

로 리베이스 세션을 열게 된다. 그러면 알아서 자동으로 'pick'이 커밋 할 때 지정한대로 'fixup'이나 'squash'로 바뀌어져 있으며, 목적지 커밋 다음 라인으로 행이 이동된 상태로 작성된 todo파일이 열리게 되어있다. 한번 쓱 보고 저장해주면 그대로 리베이스 진행.

주의해야 할 점은 --autosquash 옵션이 붙기 위해선 무조건 인터랙티브(-i) 모드로 열어야 한다는점. 그리고 <commit>으로 부터 HEAD 사이에 달라붙을 목적지 커밋이 포함되어야 한다. 나 같은 경우에는 HEAD로 부터 7커밋 떨어져 있는곳에 fixup을 해야 했는데, 이럴경우 git rebase -i --autosquash HEAD~3으로 열어봤자 아무 의미 없음.