#git reflog - HEAD 변경 이력을 볼 수 있다. 커밋은 어디 안 간다

LA in the Rearview Mirror

되돌릴 방법이 없으면 종종 걸음밖에 못 걷는다. 쫄아서. 하지만 복구 방법을 안다면 크게 걸을 수 있다. 과감해지는 거지. 과거를 볼 수 있다면 큰 걸음을 걸을 수 있다.

git reflog

저장된 HEAD 변경 이력을 보는 명령어. git을 쓰다보면 한 번은 찾아보게 된다. 언제? 뭔가 망했을 때. 커밋이 날아가진 않았을까 불안해하며.

HEAD 변경 이력만 가지고 있는데, 도움이 될까? 이것만 가지고 가능해? 가능하다. git은 persistent 자료구조를 구현했기 때문이다.

/pnotes/assets/2014-01-13-1994-00.png

master로 rebase 해보자.

/pnotes/assets/2014-01-13-1994-01.png

없어지는 것은 하나도 없다. C4, C5 잘 살아 있다. 다만 HEAD가 C5’를 가리키고 있어서 로그에 안 보일 뿐이다.

처음 rebase 설명 그림을 봤을 때, C4, C5가 C4’, C5’ 위치로 옮겨가는 건 줄 알았다. 아니다. 잘못 알았다. git 객체를 변경할 수 없다.

rebase를 잘못했다. 어떻게 돌릴 수 있을까? C5만 가리킬 수 있으면 된다. 커밋 id를 외우고 있으면 간단한데, 그럴리는 없겠지. rebase를 하면서 topic 브랜치도 C5’를 가리키게 됐다. 그래서 topic 브랜치도 도움이 안 된다.

reflog를 사용하면 된다. rebase를 하기 전 HEAD가 C5를 가리켰다. 이 정보를 사용하면 된다.

$ git reflog
8d029ef HEAD@{0}: rebase finished: returning to refs/heads/topic
8d029ef HEAD@{1}: rebase: c5
1256deb HEAD@{2}: rebase: c4
fc498f4 HEAD@{3}: checkout: moving from topic to fc498f4f7eeb9d345549bb2bd0441e7
9c16c89 HEAD@{4}: checkout: moving from master to topic

$ git reset --hard head@{4}

첫번째 열에 출력되는 커밋 id를 사용해도 되고 head@{4}와 같은 tree-ish를 사용해도 된다. rebase는 head@{3}부터 시작하므로 head@{4}로 reset하면 된다.

$ git log -g
commit 8d029eff92d307849ec2a9054afac7a7e54e56b3
Reflog: HEAD@{2} ...
Reflog message: rebase finished: returning to refs/heads/topic
...

    c5

commit 8d029eff92d307849ec2a9054afac7a7e54e56b3
Reflog: HEAD@{3} ...
Reflog message: rebase: c5
...

    c5

...

git log -g 명령어로 reflog와 커밋을 같이 볼 수 있다.

참고


크리에이티브 커먼즈 라이선스
A Random Post
Feedback plz <3 @ohyecloudy, ohyecloudy@gmail.com