如何在没有第一次提交的情况下撤销 git rm -rf dirname?

14

我做了:

git init
git add .
git rm -rf dirname

查看其他答案后,git reset --hard HEADgit checkout -fgit reflog都没有起作用,显然是因为没有HEAD可以返回,也没有提交可以从中恢复文件。

有没有办法拿回这些文件?


2
请更新被接受的答案,以便实际上允许获取文件。 - thibaut noah
8个回答

15

警告: 在不使用 -n 选项(1)的情况下运行 git prune 将会擦除您无法访问的数据。

可能有一种方法,可以使用 git prunegit cat-file

通过运行 git prune -n 命令,可以列出将被修剪删除的对象:

$ git prune -n
9cc84ea9b4d95453215d0c26489d6a78694e0bc6 blob
c315143703752ef4d11ca7d93f2c324872b2ebff blob

每行对应一个已删除的文件。

现在,使用 git cat-file 命令,我们可以将被删除文件的内容恢复到一个新文件中:

git cat-file -p 9cc84ea9b4d95453215d0c26489d6a78694e0bc6 > restored-filename

(1) 来自于 git prune 文档:

名称
git-prune - 从对象数据库中清除所有无法访问的对象

选项
-n
--dry-run
不要删除任何东西; 只报告它将要删除什么。


3
这是唯一真正有用的答案!谢谢! - Maksim Kovalev
1
你真是救星!在为一个项目工作了12个小时并尝试进行初始提交后,我不小心运行了 git rm -rf . 来撤销一次更改。我当时真的以为所有的工作都永远丢失了。给未来的自己的提示 - 总是从空仓库开始,然后随着进展逐步添加文件! - giran

10

无路可走。

通常,git rm 在删除文件之前会检查它们是否已经提交,以便不会丢失您的工作内容。然而,使用 -f 会覆盖此检查。

简而言之:

  • 不要使用 -f
  • 不要触碰任何尚未提交的内容。

3
就像UNIX中的-f选项一样,这意味着你需要非常确定自己在做什么。 - B Seven
考虑到我刚刚恢复了我的数据,这个说法显然是不正确的,也不应该被接受作为答案。 - thibaut noah

3

如果您尚未提交,可以通过执行以下操作来恢复目录:

git stash
git stash pop
git co dirname

这显然是解决所提出问题的最佳答案。它应该附带已接受答案中提供的警告,才能成为完美的答案。 - matt

2
据我所知,Git会像执行“rm -rf”一样取消关联文件。无论它是否知道这些文件的存在与否,它都会毫不犹豫地删除目录。实际上,您唯一的选择就是尝试使用一个文件恢复工具来尝试恢复已经像您执行了“rm -rf”一样删除的文件。请注意保留HTML标签,并使文本更通俗易懂。

2
如果git没有跟踪dirname目录,它将不允许您使用git rm -rf删除该目录,因为它不知道该目录的存在。您将(可能)会收到以下错误消息:
fatal: pathspec 'dirname' did not match any files

如果您在git init之后执行了git add .git add dirname,则唯一的删除方式是这样的。如果是这种情况,您的文件已经被删除了,因为它从来没有被提交,Git也不会跟踪它。这就像在普通文件夹上执行rm -rf一样(除非您有备份,否则无法恢复)。


但是它真的这样吗?我没有测试过,但我认为-f标志将抑制该错误。 - Matt
除非你使用 -f,否则会“覆盖最新检查”,不管那意味着什么。 - B Seven
@Matt - 不,它不会抑制那个。git rm中的-f仅用于覆盖最新检查。 - manojlds
我刚在Git 1.7.5.4上进行了测试。git rm -rf不会触及未暂存的目录,但它会愉快地清除已暂存但未提交的目录。 - Lambda Fairy

1

git reset --hard 在删除操作尚未提交时有所帮助,一般来说,删除操作被 Ctrl+Z 打断了。


0

git stash 是对我有效的命令。


0

首先输入 "git stash"

然后输入 "git stash pop"

接着你会看到一个已删除文件的列表。逐个复制文件名并使用

"git restore 文件名..." 来放弃工作目录中的更改


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接