在 Git 存储库中查找并恢复已删除的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/953481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Find and restore a deleted file in a Git repository
提问by avdgaag
Say I'm in a Git repository. I delete a file and commit that change. I continue working and make some more commits. Then, I find I need to restore that file.
假设我在 Git 存储库中。我删除了一个文件并提交了该更改。我继续工作并做出更多的承诺。然后,我发现我需要恢复该文件。
I know I can checkout a file using git checkout HEAD^ foo.bar
, but I don't really know when that file was deleted.
我知道我可以使用 检出文件git checkout HEAD^ foo.bar
,但我真的不知道该文件何时被删除。
- What would be the quickest way to find the commit that deleted a given filename?
- What would be the easiest way to get that file back into my working copy?
- 找到删除给定文件名的提交的最快方法是什么?
- 将该文件恢复到我的工作副本的最简单方法是什么?
I'm hoping I don't have to manually browse my logs, checkout the entire project for a given SHA and then manually copy that file into my original project checkout.
我希望我不必手动浏览我的日志,检出给定 SHA 的整个项目,然后手动将该文件复制到我的原始项目检出中。
回答by CB Bailey
Find the last commit that affected the given path. As the file isn't in the HEAD commit, this commit must have deleted it.
查找影响给定路径的最后一次提交。由于该文件不在 HEAD 提交中,因此此提交必须已将其删除。
git rev-list -n 1 HEAD -- <file_path>
Then checkout the version at the commit before, using the caret (^
) symbol:
然后使用插入符号 ( ^
) 符号检查之前提交时的版本:
git checkout <deleting_commit>^ -- <file_path>
Or in one command, if $file
is the file in question.
或者在一个命令中,如果$file
是有问题的文件。
git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"
If you are using zsh and have the EXTENDED_GLOB option enabled, the caret symbol won't work. You can use ~1
instead.
如果您使用的是 zsh 并启用了 EXTENDED_GLOB 选项,则插入符号将不起作用。你可以~1
改用。
git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"
回答by Robert Munteanu
- Use
git log --diff-filter=D --summary
to get all the commits which have deleted files and the files deleted; - Use
git checkout $commit~1 path/to/file.ext
to restore the deleted file.
- 使用
git log --diff-filter=D --summary
得到所有已删除的文件和文件删除了提交; - 使用
git checkout $commit~1 path/to/file.ext
恢复删除的文件。
Where $commit
is the value of the commit you've found at step 1, e.g. e4cf499627
$commit
您在步骤 1 中找到的提交值在哪里,例如e4cf499627
回答by Manu
To restore all those deleted files in a folder, enter the following command.
要恢复文件夹中所有已删除的文件,请输入以下命令。
git ls-files -d | xargs git checkout --
回答by Brett
I came to this question looking to restore a file I just deleted but I hadn't yet committed the change. Just in case you find yourself in this situation, all you need to do is the following:
我来到这个问题是想恢复我刚刚删除的文件,但我还没有提交更改。万一您发现自己处于这种情况,您需要做的就是:
git checkout HEAD -- path/to/file.ext
git checkout HEAD -- path/to/file.ext
回答by Josh Lee
If you're insane, use git-bisect
. Here's what to do:
如果您疯了,请使用git-bisect
. 以下是该怎么做:
git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>
Now it's time to run the automated test. The shell command '[ -e foo.bar ]'
will return 0 if foo.bar
exists, and 1 otherwise. The "run" command of git-bisect
will use binary search to automatically find the first commit where the test fails. It starts halfway through the range given (from good to bad) and cuts it in half based on the result of the specified test.
现在是运行自动化测试的时候了。'[ -e foo.bar ]'
如果foo.bar
存在,shell 命令将返回 0 ,否则返回1。的“运行”命令git-bisect
将使用二进制搜索来自动查找测试失败的第一个提交。它从给定范围(从好到坏)的一半开始,并根据指定测试的结果将其切成两半。
git bisect run '[ -e foo.bar ]'
Now you're at the commit which deleted it. From here, you can jump back to the future and use git-revert
to undo the change,
现在您处于删除它的提交处。从这里,您可以跳回未来并用于git-revert
撤消更改,
git bisect reset
git revert <the offending commit>
or you could go back one commit and manually inspect the damage:
或者您可以返回一次提交并手动检查损坏情况:
git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .
回答by VonC
My new favorite alias, based on bonyiii's answer(upvoted), and my own answer about "Pass an argument to a Git alias command":
我最喜欢的新别名,基于bonyiii的回答(已投票),以及我自己关于“将参数传递给 Git 别名命令”的回答:
git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- )~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- )~1 | grep '^D' | cut -f 2); }; f'
I have lost a file, deleted by mistake a few commits ago?
Quick:
我丢失了一个文件,在几次提交前被误删除了?
快的:
git restore my_deleted_file
Crisis averted.
危机避免了。
Warning, with Git 2.23 (Q3 2019) comes the experimental commandnamed git restore
(!).
So rename this alias (as shown below).
警告,在 Git 2.23(2019 年第三季度)中出现了名为(!)的实验性命令git restore
。
所以重命名这个别名(如下所示)。
Robert Daileyproposes in the commentsthe following alias:
Robert Dailey在评论中提出以下别名:
restore-file = !git checkout $(git rev-list -n 1 HEAD -- "")^ -- ""
And jeganadds in the comments:
For setting the alias from the command line, I used this command:
为了从命令行设置别名,我使用了这个命令:
git config --global alias.restore "\!git checkout $(git rev-list -n 1 HEAD -- \"$1\")^ -- \"$1\""
回答by wisbucky
If you know the filename, this is an easy way with basic commands:
如果您知道文件名,这是使用基本命令的简单方法:
List all the commits for that file.
列出该文件的所有提交。
git log -- path/to/file
The last commit (topmost) is the one that deleted the file. So you need to restore the second to last commit.
最后一次提交(最顶层)是删除文件的提交。所以你需要恢复倒数第二个提交。
git checkout {second to last commit} -- path/to/file
回答by Fedir RYKHTIK
To restore a deleted and commited file:
要恢复已删除和提交的文件:
git reset HEAD some/path
git checkout -- some/path
It was tested on Git version 1.7.5.4.
它在 Git 版本 1.7.5.4 上进行了测试。
回答by Paulo Linhares - Packapps
If you only made changes and deleted a file, but not commit it, and now you broke up with your changes
如果您只进行了更改并删除了一个文件,但没有提交它,那么现在您与您的更改分手了
git checkout -- .
but your deleted files did not return, you simply do the following command:
但是您删除的文件没有返回,您只需执行以下命令:
git checkout <file_path>
And presto, your file is back.
很快,您的文件又回来了。
回答by Alex
I've got this solution.
我有这个解决方案。
Get the id of the commit where the file was deleted using one of the ways below.
git log --grep=*word*
git log -Sword
git log | grep --context=5 *word*
git log --stat | grep --context=5 *word*
# recommended if you hardly remember anything
You should get something like:
使用以下方法之一获取删除文件的提交的 ID。
git log --grep=*word*
git log -Sword
git log | grep --context=5 *word*
git log --stat | grep --context=5 *word*
# 如果你几乎不记得任何事情,推荐
你应该得到类似的东西:
commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 Author: Alexander Orlov Date: Thu May 12 23:44:27 2011 +0200
replaced deprecated GWT class - gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script
commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302 Author: Alexander Orlov Date: Thu May 12 22:10:22 2011 +0200
提交 bfe68bd117e1091c96d2976c99b3bcc8310bebe7 作者:Alexander Orlov 日期:2011 年 5 月 12 日星期四 23:44:27 +0200
replaced deprecated GWT class - gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script
提交 3ea4e3af253ac6fd1691ff6bb89c964f54802302 作者:Alexander Orlov 日期:2011 年 5 月 12 日星期四 22:10:22 +0200
3. Now using the commit id bfe68bd117e1091c96d2976c99b3bcc8310bebe7 do:
3. 现在使用提交 ID bfe68bd117e1091c96d2976c99b3bcc8310bebe7 做:
git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java
As the commit id references the commit where the file was already deleted you need to reference the commit just before bfe68b which you can do by appending ^1
. This means: give me the commit just before bfe68b.
由于提交 ID 引用文件已被删除的提交,因此您需要在 bfe68b 之前引用提交,您可以通过附加^1
. 这意味着:在 bfe68b 之前给我提交。