我运行了git update-ref -d HEAD
命令,它删除了我的所有文件。文件夹大小仍然很大,所以,我想这些文件在某种程度上是在git的内存中。我该如何恢复这些文件?
这是打破你的回购的好方法;
$ 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.
一切都很好。
如果可能的话,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 commit
和notice
关于一个未出生的分支 - 在这种情况下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命令;根据您的命令环境根据需要进行修改)。