2

我在暂存索引中添加了一堆更改git add *但尚未提交,我想删除它们,撤消添加,所以令git rm -rf .我惊讶的是,它从我的硬盘驱动器中删除了它们,我想要一种方法让它们回来; 然而,我已经做出了巨大的改变,我想把这些改变拿回来。

TLDR:我删除了我的整个项目git rm -rf .,我需要一些方法来重置删除,以便我保留未提交的更改并取回我的文件。请我太害怕我可能会失去我的整个项目。

回答:我的存储库基本上是一个包含很多内容的网站,根据下面的答案,我制作了我的存储库的 2 个副本,我们称它们为副本 A 和副本 B,因为 AI 确实git reset --hard回到了最新的提交,我得到了我的文件回来了,但丢失了我对它们所做的更改。所以对于副本 BI 做了git fsck --lost-found并进入 .git/lost-found/other/ 目录,其中包含我的文件的多个哈希命名版本,我一直打开它们,顺便说一句,它们是 60 多个文件,我认识的每个文件我都将其重命名为它的实际名称,然后将它而不是旧版本放在副本 A 中,最后我删除了我的原始存储库,我现在使用副本 A 作为我的网站。就像现在什么都没有发生一样。一个小小的愚蠢错误 => 5 小时的痛苦。不要重复我所做的,永远不要。

现在git status将我的所有文件显示为“已删除:”,并且显示为绿色。

4

5 回答 5

4

使用

find .git/objects/ -type f -printf "%T+\t%p\n" \
  | sort \
  | sed 's:.*git/objects/\(.*\)/\(.*\):\1\2:' \
  | while read object; do
       echo -n "$object "; 
       git cat-file -t "$object";
    done

您应该获得按时间排序的对象和类型列表。

例如,在测试存储库中:

908553f63e9126f933b690970d41adc3377e3360 blob
31e0d0e213c9976308fbb91c542ced9218fa8f6a tree
5b181f91c49d287b4670fcf3545656dc0c0ef5f4 commit
de683137e0b2d0a40f766307e81999986e4b31c2 blob
086cb344a4fd8a9d671006b8e5844f2437faa3ab tree
930ba9809b5d50410b72c3fbff111d948f1027fa commit
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 blob
40cda8e010466dc7a4a0eb107e7e45804290685e blob

最后两个 blob 是在最后一次提交之后创建的,如果您使用例如打印它们。git cat-file -p 40cda8e010466dc7a4a0eb107e7e45804290685e,您应该能够恢复文件内容。

您也可以通过这种方式获得一些树(用于git ls-tree <tree-id>打印它们),但不是顶级树,因为它直接存储在索引中。

于 2019-06-14T12:28:16.147 回答
3

对于已提交的文件,git reset --hard将全部恢复。

对于那些已添加但未提交的,请尝试git fsck --lost-found. 它将打印悬挂的 blob 并在.git/lost-found/other. 您可以运行git cat-file -p $blobcat .git/lost-found/other/$blob查看内容。blob 不记录文件路径,因此您需要通过内存或未新修改的关键字来映射内容和文件路径git grep $keyword。找到 blob 的路径后,运行cp .git/lost-found/other/$blob $path以恢复它。

于 2019-06-14T12:16:21.693 回答
3

可能会有希望:您之前添加到索引中的对象可能仍然存在,尽管它们不再被引用。我做了以下测试:

$ git init test
$ cd test
$ echo hello > README.md
$ git add README.md
$ git commit -m"Add README.md"
$ echo world >> README.md
$ cat README.md
hello
world
$ git add README.md
$ git rm -f README.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    README.md

$ git fsck
Checking object directories: 100% (256/256), done.
unreachable blob 94954abda49de8615a048f8d2e64b5de848e27a1
$ git show 94954abda49de8615a048f8d2e64b5de848e27a1
hello
world

所以即使在 之后git rm -f,添加到索引中的文件内容仍然存在。.git/lost-found/other您可以通过运行将它们全部转储到git fsck --lost-found.

索引本身不存储为 Git 对象,而是直接驻留在 中.git/index,所以我认为这已被不可逆转地覆盖。这意味着文件的路径以及权限等任何元数据都已丢失。

于 2019-06-14T12:31:46.173 回答
1

git status为您提供有关可用于恢复文件的命令的一些提示:

$ git rm  -rf .
$ git status

On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  deleted: file1
  deleted: file2

要取消暂存已删除的文件:

$ git reset HEAD file1 file2
$ git status

On branch master
Your branch is up to date with 'origin/master'.

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)

    deleted:    file1
    deleted:    file2

no changes added to commit (use "git add" and/or "git commit -a")

签出已删除的文件:

$ git checkout -- file1 file2
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
于 2019-06-14T14:13:53.617 回答
0

正如评论者所说,您应该做的第一件事是备份您的项目目录。

您可以使用git reset --hard HEAD. 由于您清除了暂存树,因此您未提交的更改不再存在于 git 中(正如其他几个答案所指出的那样,这可能不是真的),因此您恢复它们的唯一机会是您或您的操作系统可能已经进行的任何备份。

很抱歉,这对当前情况没有帮助,但为了将来参考,您可以使用git reset HEAD.

于 2019-06-14T12:09:29.203 回答