# 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 |