挽救丢失的Git提交

261 阅读2分钟
原文链接: guangqi.wang
# 1. 找到所有的提交id, 不直接使用git log是因为git log已经看不到提交信息了
$ cd <project_root>
$ find .git/objects/??/* -type f | awk -F'/' '{print "echo "$3$4" `git cat-file -t "$3$4"`"}' | bash | grep ' commit' > /tmp/commit.txt
# 结果如下
$ cat /tmp/commit.txt | more
011ba470078d9acca35e19ef1492dcb5f07d1896 commit
02525eab8134ef0e87566105339eca02b477bb93 commit
05d16b3b3876fe8b74abc0fd25ea34ac096ef583 commit
 
# 2. 从提交信息中确认丢失的提交,根据提交的备注或时间以及提交者等信息查找,每次提交都写详细的备注绝对是有好处的
$ cat /tmp/commit.txt | awk '{print "echo \"\n\"commit "$1"; git cat-file -p "$1}' | bash
 
commit 011ba470078d9acca35e19ef1492dcb5f07d1896
tree d421b5033183277cf951466637b8a1092aa425c4
parent 63e955796a23331a0c4262c5b3b9b5c52c1be0c2
author Echo <xx@aa.com> 1518313421 +0800
committer Echo <xx@aa.com> 1518313488 +0800
 
commit comment 1
 
commit 02525eab8134ef0e87566105339eca02b477bb93
tree 1bbe46076647bf4eeddf0ee4d1c0602d87b33bf6
parent 49a31ea3c0196eb9b243edf491474c8ff0e93aef
author Echo <xx@aa.com> 1519721476 +0800
committer Echo <xx@aa.com> 1519721476 +0800
 
commit comment 2
 
# 3. 恢复改动,假设我们找到丢失的提交就是“011ba470078d9acca35e19ef1492dcb5f07d1896”这个
# 首先确保当前的git是干净的,没有任何改动,如果有可以全部暂存下,干净的git应该是这样(git st是git status的别名)
$ git st
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
 
nothing to commit, working tree clean
# 将丢失的提交信息还原回来,注意是提交信息,不是提交内容
$ git read-tree 011ba470078d9acca35e19ef1492dcb5f07d1896
# 查看变更,此时应该会出现两种变更,已暂存的,和未暂存的。已暂存的是我们丢失的提交,而为暂存的是应为我们只还原了丢失的提交信息,而提交内容还未还原
$ git st
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
 
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    modified:   xx/bb/cc.php
    modified:   xx.json
        ...
 
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
 
    modified:   xx/bb/cc.php
    modified:   xx.json
        ...
 
# 4. 接下来我们需要还原提交内容,很简单,直接将未暂存的改动还原掉即可
$ git checkout -- .
# 还原未暂存改动后我们使用 git st 查看变更的时候发现只有暂存的改动,而且这些改动就是丢失的提交
# 这时候还不能直接提交,因为我们中途可能会有别的提交,如果直接提交这个的话会导致中间的提交被覆盖。
# 针对这种情况的回复还得人肉来恢复中途的提交,谁叫你作呢,欠的债必须肉偿呀。
# 等中途提交都还原或合理合并后就可以提交这个改动了,至此我们丢失的内容又还原回来了,开不开心,意不意外。
# end