git reset hard를 했더니 특정 로컬 커밋들이 다 날아갔다?!

엽토군·2020년 4월 22일
2
post-thumbnail

서론

다음 순서대로 작업을 하면, feature/foo 브랜치가 통째로 사라진 것처럼 보이게 된다.

git checkout develop # 이 시점 sha1 값이 ABC123 이라고 해보겠음
git checkout -b feature/foo
# 뭔가 졸라열심히 작업을 한 다음
git add .
git commit
git checkout develop
git merge feature/foo
git checkout feature/foo
git merge develop
git checkout develop
git reset --hard ABC123

지난 며칠간 졸라 힘겹게 작업해놓은 feature/foo 기능브랜치가 통째로 날아갈 위기에 처했다...
후... 밤새서 다시해야 하나... 각오를 다지다가, 좀더 각오를 강하게 다질 필요가 있어서, feature/foo 브랜치를 살릴 도리가 없다는 것을 확인하기 위해 구글에다 대고 "git undo reset hard"라고 검색했다.

어? 도리가 아주 없진 않더라.

본론

Git은 지난 한 달 정도의 모든 커밋들을 절대시간 순서대로 쭉 저장해 놓는다.
Git의 reset --hard란, 단지 그 저장된 커밋들 중 하나로 헤드를 이동하는 작업이다.
그 결과 어떤 브랜치들은 병합되어 사라진 것처럼 보일 수 있다.

마법의 주문은 이것이다.

git reflog

위 명령을 실행하면 그 절대시간 순서의 커밋들이 쭉 나온다. (아래로 갈수록 과거임)
커밋로그들을 쭉 보다보면, "앗 여기까지는 모든게 괜찮았는데" 싶은 커밋이 보일 것이다.

5aa5248d (origin/develop, develop) HEAD@{3}: checkout: moving from feature/foo to feature/foo
5aa5248d (origin/develop, develop) HEAD@{4}: reset: moving to 5aa5248dfb76672e9c5cee26d7a78ad39f59f125
6c47b8a7 HEAD@{5}: checkout: moving from develop to feature/foo
5aa5248d (origin/develop, develop) HEAD@{6}: reset: moving to 5aa5248dfb76672e9c5cee26d7a78ad39f59f125
6c47b8a7 HEAD@{7}: checkout: moving from feature/foo to develop
6c47b8a7 HEAD@{8}: merge develop: Fast-forward
0e787f01 (HEAD -> feature/foo) HEAD@{9}: checkout: moving from develop to feature/foo
6c47b8a7 HEAD@{10}: merge feature/foo: Merge made by the 'recursive' strategy.
5aa5248d (origin/develop, develop) HEAD@{11}: checkout: moving from feature/foo to develop
0e787f01 (HEAD -> feature/foo) HEAD@{12}: checkout: moving from feature/redmine-1018 to feature/foo
f382e69b (feature/redmine-1018) HEAD@{13}: commit: basic model/controller scaffolding
5aa5248d (origin/develop, develop) HEAD@{14}: checkout: moving from develop to feature/redmine-1018
5aa5248d (origin/develop, develop) HEAD@{15}: merge redmine-1010: Merge made by the 'recursive' strategy.
f0d48cdc HEAD@{16}: checkout: moving from master to develop
5b8ea66d (tag: redmine-1010, origin/master, origin/HEAD, master) HEAD@{17}: merge hotfix/redmine-1010: Merge made by the 'recursive' strategy.
945a3168 (tag: improve-admin-member) HEAD@{18}: checkout: moving from hotfix/redmine-1010 to master
a5e1a93d HEAD@{19}: commit: changed terms for book resource types
945a3168 (tag: improve-admin-member) HEAD@{20}: checkout: moving from develop to hotfix/redmine-1010
f0d48cdc HEAD@{21}: checkout: moving from feature/foo to develop
0e787f01 (HEAD -> feature/foo) HEAD@{22}: commit: homework done, reward wip # <----------------------------------------------------------- 앗 이거! 이거!!!
d4d7c85b HEAD@{23}: commit: added & applied FOOBAR models
e5a5bcd4 HEAD@{24}: commit: added FOOBAR database connection

그 커밋 sha1을 기억해둔 다음, 다시 git reset --hard <기억해둔shar1> 실행한다.

그러면 시간여행을 한 것처럼 딱 그때로 돌아갈 것이다.

결론

  • Git은 정말 최고이다.
    • 일단 커밋(이나 스태시)을 해놓았다면 죽으라는 법은 없다.
  • 주의할 점: 너무 과거의 커밋은 git reflog로도 못 살린다는 모양이다.
  • 절망할 때 절망하더라도 검색은 해보고 절망하자.
profile
4년차 PHP 개발자입니다.

1개의 댓글