Git 数据恢复

数据恢复

当我们使用 git reset --hard 将当前数据恢复到之前的某个版本时,在这个提交之后的提交将会丢失。如果我们想找到丢失的提交节点,可以进行下面的操作:

  1. 首先,使用 git reflog 或者 git log -g 可以查看我们改变 HEAD 指针的过程。
  2. 在输出的信息中,我们就可以找到那次提交的 HASH 值,以此就可以恢复到那个提交节点。

Git 会将我们操作 HEAD 的过程记录下来,放在 .git/logs 目录下。git reflog 就是显示这些引用更改的日志。

实际操作

初始化仓库,并建立四次提交。

$ echo 'version 1' > test.txt
$ git add . && git commit -m "first commit"
$ echo 'version 2' > test.txt
$ git add . && git commit -m "second commit"
$ echo 'version 3' > test.txt
$ git add . && git commit -m "third commit"
$ echo 'version 4' > test.txt
$ git add . && git commit -m "forth commit"

然后恢复到第二次提交:

$ git reset --hard HEAD^^

查看提交历史:

$ git log
commit 4b2291bffa6543ecfc972e876a8c75752c8400f5 (HEAD -> master)
Author: Vactor <[email protected]>
Date:   Mon Jul 16 00:43:05 2018 +0800

    second commit

commit 5522d5148d6de7d161bf6ac372e77598192d5284
Author: Vactor <[email protected]>
Date:   Mon Jul 16 00:42:45 2018 +0800

    first commit

找不到第三次和第四次提交了! 怎么办?
使用 git reflog :

$ git reflog
4b2291b (HEAD -> master) HEAD@{0}: reset: moving to HEAD^^
24d3559 HEAD@{1}: commit: forth commit
ef8d434 HEAD@{2}: commit: third commit
4b2291b (HEAD -> master) HEAD@{3}: commit: second

或者 git log -g :

$ git log -g
commit 4b2291bffa6543ecfc972e876a8c75752c8400f5 (HEAD -> master)
Reflog: HEAD@{0} (Vactor <[email protected]>)
Reflog message: reset: moving to HEAD^^
Author: Vactor <[email protected]>
Date:   Mon Jul 16 00:43:05 2018 +0800

    second commit

commit 24d355980596e45fd8288e5d80e2b5fee56ad1a0
Reflog: HEAD@{1} (Vactor <[email protected]>)
Reflog message: commit: forth commit
Author: Vactor <[email protected]>
Date:   Mon Jul 16 00:43:40 2018 +0800

    forth commit

commit ef8d43472e087ed9204808ebfec5da88528fd35e
Reflog: HEAD@{2} (Vactor <[email protected]>)
Reflog message: commit: third commit
Author: Vactor <[email protected]>
Date:   Mon Jul 16 00:43:24 2018 +0800

    third commit

找到了所有丢失的信息,就可以恢复了。创建一个新的分支,指向第三次提交!

$ git branch recover-branch ef8d434

引用日志也没了怎么办?

如果将引用日志也删除了,那该怎么办呢?可以使用下面的命令,找到所有没有被其他对象引用的对象,也就是那些游离的对象。
我们将 .git/logs 删除,然后执行命令:

$ git fsck --full
Checking object directories: 100% (256/256), done.
dangling commit 24d355980596e45fd8288e5d80e2b5fee56ad1a0

就会发现第四次提交处于 dangling 状态。因为第四次提交的父节点是第三次提交,所以第三次提交并不是 dangling 状态。

原文在这里

相关推荐