Git:恢复“git update-ref -d HEAD”删除的文件

问题描述 投票:0回答:2

我运行了git update-ref -d HEAD命令,它删除了我的所有文件。文件夹大小仍然很大,所以,我想这些文件在某种程度上是在git的内存中。我该如何恢复这些文件?

git
2个回答
3
投票

这是打破你的回购的好方法;

$ mkdir DeleteHead
$ cd DeleteHead/
$ git init
$ touch README.md
$ git add -A
$ git commit -m "Init."
$ git commit -m "More work" --allow-empty
$ git log
commit 83edc8bcb2e627420e47b7933580dc85b21d968e (HEAD -> master)
Date:   Fri Sep 14 17:42:47 2018 +0100

    More work

commit c175c1fbf9ee8b9d2a9eec3eb3666f19db2b9f99
Date:   Fri Sep 14 17:42:38 2018 +0100

    Init.

$ git update-ref -d HEAD

你无法获得修复它的常用技巧;

$ git log
fatal: your current branch 'master' does not have any commits yet

$ git reflog
fatal: your current branch 'master' does not have any commits yet

让我们来看看.git文件夹,看看我们能找到什么;

$ cat .git/logs/HEAD
0000000000000000000000000000000000000000 c175c1fbf9ee8b9d2a9eec3eb3666f19db2b9f99 Horba 1536943358 +0100 commit (initial): Init.
c175c1fbf9ee8b9d2a9eec3eb3666f19db2b9f99 83edc8bcb2e627420e47b7933580dc85b21d968e Horba 1536943367 +0100 commit: More work
83edc8bcb2e627420e47b7933580dc85b21d968e 0000000000000000000000000000000000000000 Horba 1536943378 +0100

这看起来很方便。让我们抓住83edc8bcb2e627420e47b7933580dc85b21d968e值(它在你的回购中会有所不同)并再次更新HEAD;

$ git update-ref HEAD 83edc8bcb2e627420e47b7933580dc85b21d968e

$ git log
commit 83edc8bcb2e627420e47b7933580dc85b21d968e (HEAD -> master)
Date:   Fri Sep 14 17:42:47 2018 +0100

    More work

commit c175c1fbf9ee8b9d2a9eec3eb3666f19db2b9f99
Date:   Fri Sep 14 17:42:38 2018 +0100

    Init.

一切都很好。


1
投票

Use Horba's answer

如果可能的话,HEAD reflog技巧是可行的方法。我也会在这里留下我自己的早期答案,以防这种方法出现问题。


(原始答案)

我运行了git update-ref -d HEAD命令,它删除了我的所有文件。

实际上,它没有:它可能删除了附加HEAD的分支名称(通常HEAD附加到分支名称)。

......我怎样才能恢复?

跑:

git fsck --lost-found

您可能会看到类似于此的输出,我在一个小型测试存储库中运行:

notice: HEAD points to an unborn branch (master)
Checking object directories: 100% (256/256), done.
notice: No default references
dangling commit 6719ac33e5c385b9fdba7c57636fbf8cc71a3f3f

如果你得到一个dangling commitnotice关于一个未出生的分支 - 在这种情况下master;你的将是你刚刚删除的任何分支 - 然后这个特定的提交(可能;请参阅下面的一些边缘情况)你想要的那个:

$ git branch master 6719ac33e5c385b9fdba7c57636fbf8cc71a3f3f

重新创建它,之后一切恢复正常:

$ git status
On branch master
nothing to commit, working tree clean

如果您收到多条dangling commit消息,请在生成的每个提交哈希ID上运行git show和/或git log。其中一个(可能)是你应该重新连接的提交。但是,您可能处于下一段中描述的情况:

如果你没有得到dangling commit消息,这意味着你在一个完全合并到其他分支的分支上。在这种情况下,不要求您重新创建分支名称;你可以简单地git checkout一些其他分支名称附加HEAD那里。

请注意,如果您使用的是分离的HEAD并使用git update-ref -d HEAD,则会破坏您的Git存储库:

$ git checkout --detach master
HEAD is now at 6719ac3... initial
$ git update-ref -d HEAD
$ git status
fatal: Not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

在这种情况下,您必须重新创建符号HEAD。不幸的是,正常的Git命令拒绝运行:

$ git symbolic-ref HEAD refs/heads/master
fatal: Not a git repository (or any parent up to mount point /)

因此你必须作弊:

$ echo 'ref: refs/heads/master' > .git/HEAD
$ git status
On branch master
nothing to commit, working tree clean

(这假定为sh / bash命令;根据您的命令环境根据需要进行修改)。

© www.soinside.com 2019 - 2024. All rights reserved.