반응형

출처 : http://gitready.com/advanced/2009/01/17/restoring-lost-commits.html

잃어버린 commit들 복구하기

만약 당신이 마지막 commit을 버리기 위해 git reset --hard HEAD^ 를 실행하였습니다. 그런데 그 변경이 필요하지 않았음이 밝혀졌습니다.  당신은 두 번 다시 완벽하게 알고리즘을 구현할 수 없고 다시 원래대로 복구해야 합니다. 겁먹지 말고 git은 당신의 잃어버린 그 commit을 가지고 있습니다. reset할 때 당신이 버린 commit은 "dangling" 상태가 됩니다. 그것은 git의 데이터로 보관되어 있고 다음 garbage collection 때 치워질 것입니다. 당신이 위 명령을 실행했을 때 부터 git gc를 실행하지 않는다면 당신은 그것을 복구할 수 있습니다.

예를 들어 저는 이 블로그를 위한 코드를 작성하였습니다. 그리고 바로 다음을 실행합니다.

$ git show-ref -h HEAD
  7c61179cbe51c050c5520b4399f7b14eec943754 HEAD

$ git reset --hard HEAD^
  HEAD is now at 39ba87b Fixing about and submit pages so they don't look stupid

$ git show-ref -h HEAD
  39ba87bf28b5bb223feffafb59638f6f46908cac HEAD

우리의 HEAD는 하나의 commit으로 저장된 상태입니다. 이 때 우리는 git pull으로 그것을 원래대로 돌릴 수 있다면 우리의 local repository는 그 commit을 알고 있다고 가정할 수 있습니다. 우리는 그것을 원래대로 돌리기 위해 그 commit의 SHA1이 필요합니다. 우리는 fsck명령으로 그 commit에 대해 알고 있다는 것을 증명할 수 있습니다.

$ git fsck --lost-found
  [... some blobs omitted ...]
  dangling commit 7c61179cbe51c050c5520b4399f7b14eec943754

또한, git은 reflog명령을 사용하여 아직 그 commit에 대해 알고 있다는 것을 확인 할 수 있습니다.

$ git reflog
  39ba87b... HEAD@{0}: HEAD~1: updating HEAD
  7c61179... HEAD@{1}: pull origin master: Fast forward
  [... lots of other refs ...]

결국, 우리는 복구하고자 하는 SHA1:7c61179 을 알았습니다. 만약 현재 branch에 복구하고자 하는 그 commit을 바로 적용하려면, git merge함으로서 그 commit으로 복구할 것입니다.

$ git merge 7c61179
  Updating 39ba87b..7c61179
  Fast forward
    css/screen.css |    4 ++++
    submit.html    |    4 ++--
    2 files changed, 6 insertions(+), 2 deletions(-)

이 명령은 우리의 잃어버린 변화들을 되돌릴 것이고 HEAD가 그 commit을 가리키도록 보장할 것입니다. 여기서부터 평소처럼 작업을 이어서 할 수 있습니다. 또한, 당신은 새로운 branch로 복구할 SHA1을 checkout할 수 있지만 merge가 당신이 그 hash를 가지고 있을 때 잃어버린 commit을 복구하는 가장 빠르고 쉬운 방법입니다. 혹시 당신이 다른 방법을 알고 계시면 댓글을 남겨주세요!

만약 이러한 상황에서 할 수 있는 더 많은 option들을 알고 싶다면, Mathieu Martin’s illustrated guide to recovering lost commits with Git이 충분히 당신에게 도움이 될 것입니다.


반응형

+ Recent posts