如何还原“ git rm -r”?


378

我不小心说了git rm -r .。我该如何恢复?

我没有犯。

我认为所有文件都标记为删除,并且也从我的本地结帐中实际删除。

编辑:我可以(如果我知道命令)恢复到最后一次提交。但是如果我能撤消它会好得多git rm -r .。因为我不太确定在上次提交之后和提交之前我做了什么git rm -r .


3
对于这个特定问题,reset --hard是一个很好的解决方案...它已经列出,因此我仅在此评论中提到您可能需要检查git-reflog的文档。
威廉·珀塞尔

8
请注意,由于您没有提供-fgit rmgit,因此不会删除已暂存或未暂存更改的任何文件,因此a git reset; git checkout .应该可以恢复所有内容。
CB Bailey 2010年

只要注意git checkout即可。将清除所有未进行的更改。
PeterB 2011年

1
我只是做了这样的事情,而且我不明白为什么我的本地文件被删除了(而且像OP一样,我还没有提交。)
Xonatron

使用Git 2.23+(2019年8月),您将使用git restore:还原文件git restore -s@ -SW -- .。请参阅下面的答案
VonC

Answers:


468
git reset HEAD

应该做。如果您不需要任何未提交的更改,那么

git reset --hard HEAD

应该强制将所有内容重置为您的最后一次提交。如果您确实有未提交的更改,但是第一个命令不起作用,请使用git stash以下命令保存未提交的更改:

git stash
git reset --hard HEAD
git stash pop

22
请注意,这git reset --hard HEAD会破坏您在当前工作目录的父目录中所做的任何有用的更改。
亚历克斯·布朗

10
@米尔德:我还是流着汗!
hoipolloi 2011年

6
我没有拒绝投票,但我只是尝试隐藏,重设,弹出并丢失了我最近的所有更改。也许我误解了答案。
Greg M. Krsak'2

1
这对我很少有用,我很高兴我在Dropbox文件夹中工作。可怜的形式,但每次都会救我...
Nuby

3
当我执行git stash pop时,它只是再次删除了文件,这是因为它隐藏了我(不小心)删除了一些文件的事实。如果您要保留未提交的更改,则此答案无效。
sudo 2015年

252

当我意识到我需要一些文件时,我git-rm了一些文件,并在下一次提交之前继续进行更改。除了存储和重置外,如果需要,您可以简单地检出丢失/删除的单个文件:

git checkout HEAD path/to/file path/to/another_file

这将使您其他未提交的更改保持完整,没有任何解决方法。


6
这很有帮助,因为我还有其他未提交的更改。
2014年

4
对于那些偶然发现此问题以寻求还原单个git rm而不是整个递归的人,此答案有所帮助git rm -r。对于完全递归删除,其他解决方案可能会更好,具体取决于删除的文件数量。
tresf

你,我的男人,应该得到奖励。
萨拉米特

如果可以的话,我会点击它100次!
瓦格纳·布拉加

57

要重新获得一些单个文件或文件夹,可以使用以下方法

git reset -- path/to/file
git checkout -- path/to/file

这将首先重新创建的索引条目,path/to/file并重新创建文件(如上一次提交)HEAD

提示:可以将提交哈希传递给两个命令,以从较早的提交重新创建文件。有关详细信息,请参见git reset --helpgit checkout --help


最佳答案。轻松手术“撤消”单个git rm手术,而无需清除其他未提交的更改。
wberry

帮助了我!最佳答案。
阿克拉姆

28

更新:

由于git rm .删除工作结帐以及索引中此目录和子目录中的所有文件,因此需要撤消以下每个更改:

git reset HEAD . # This undoes the index changes
git checkout .   # This checks out files in this and child directories from the HEAD

这应该做您想要的。它不会影响已签出代码或索引的父文件夹。


原来的答案不是:

reset HEAD

将达到目的,并且不会删除您对文件所做的任何未提交的更改

之后,您需要重复git add排队的所有命令。


1
对不起,我总是设置git alias.co="checkout",这样git co做结帐。
亚历克斯·布朗

25

如果以上操作均无效,则可以使用建议从以下位置检索数据:http : //www.spinics.net/lists/git/msg62499.html

git prune -n
git cat-file -p <blob #>

4年后,仍然是救命稻草!
ThievingSix

我编写了一个c ++程序来连接结果(我在存储库中挂了大约100个对象,这是必要的)。只需编译并运行,然后传入您的git repo本地目录即可。raw.githubusercontent.com/bluuman/git-recover-files/master/...
詹姆斯:测量

14

撤消git rm

git rm file             # delete file & update index
git checkout HEAD file  # restore file & index from HEAD

撤消git rm -r

git rm -r dir          # delete tracked files in dir & update index
git checkout HEAD dir  # restore file & index from HEAD

撤消git rm -rf

git rm -r dir          # delete tracked files & delete uncommitted changes
not possible           # `uncommitted changes` can not be restored.

Uncommitted changes包括not staged changesstaged changes but not committed


当然,无法撤消任何操作git rm -rf,因为这也可能删除未跟踪或暂存的(仅)文件。
jpaugh

git rm -rf file并且git rm -rf dir不会删除任何未跟踪的文件。
xu

10

如果您已提交并推送了更改,则可以执行此操作以取回文件

// Replace 2 with the # of commits back before the file was deleted.
git checkout HEAD~2 path/to/file

这适用于``要提交的更改:'',其中我仍然需要从旧的git cherry-pick中删除文件。我尝试了git reset HEAD〜<number> <file>无效。
Mushcraft

7

已经有一些不错的答案,但是我可能会建议一种很少使用的语法,该语法不仅可以很好地工作,而且可以很明确地显示您想要的内容(因此不会令人恐惧或神秘)

git checkout <branch>@{"20 minutes ago"} <filename>

3

获取列表提交

git log  --oneline

例如,稳定提交具有哈希: 45ff319c360cd7bd5442c0fbbe14202d20ccdf81

git reset --hard 45ff319c360cd7bd5442c0fbbe14202d20ccdf81
git push -ff origin master

1

我有一个相同的情况。就我而言,解决方案是:

git checkout -- .

0

在Git 2.23+(2019年8月)中,将使用正确的命令来还原文件(和索引)... git restore(不是reset --hard令人困惑的git checkout命令

那是:

git restore -s=HEAD --staged --worktree -- .

或其缩写形式:

git restore -s@ -SW -- .

-1

我遇到了完全相同的问题:正在清理文件夹,重新排列和移动文件。我输入:git rm 然后按回车; 然后感觉我的肠子有点松了。幸运的是,我没有直接输入git commit -m“”。

但是,以下命令

git checkout .

恢复了一切,挽救了我的生命。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.