热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在Git存储库中查找并恢复已删除的文件-FindandrestoreadeletedfileinaGitrepository

SayIminaGitrepository.Ideleteafileandcommitthatchange.Icontinueworkingandmakesom

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签出文件,但我真的不知道该文件何时被删除。

  1. What would be the quickest way to find the commit that deleted a given filename?
  2. 找到删除给定文件名的提交的最快方法是什么?

  3. What would be the easiest way to get that file back into my working copy?
  4. 将该文件恢复到我的工作副本的最简单方法是什么?

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,然后手动将该文件复制到我的原始项目结帐中。

21 个解决方案

#1


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 -- 

Then checkout the version at the commit before, using the caret (^) symbol:

然后使用插入符号(^)符号检查之前提交的版本:

git checkout ^ -- 

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"

#2


  1. Use git log --diff-filter=D --summary to get all the commits which have deleted files and the files deleted;
  2. 使用git log --diff-filter = D --summary来获取已删除文件和删除文件的所有提交;

  3. Use git checkout $commit~1 filename to restore the deleted file.
  4. 使用git checkout $ commit~1 filename恢复已删除的文件。

Where $commit is the value of the commit you've found at step 1, e.g. e4cf499627

其中$ commit是您在步骤1中找到的提交的值,例如e4cf499627

#3


To restore all those deleted files in a folder enter the following command.

要还原文件夹中的所有已删除文件,请输入以下命令。

git ls-files -d | xargs git checkout --

#4


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

#5


If you’re insane, use git-bisect. Here's what to do:

如果你疯了,请使用git-bisect。这是做什么的:

git bisect start
git bisect bad
git bisect good 

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.

现在是时候运行自动化测试了。如果存在foo.bar,则shell命令'[ - e foo.bar]'将返回0,否则返回1。 git-bisect的“run”命令将使用二进制搜索自动查找测试失败的第一个提交。它从给定范围的中间开始(从好到坏),并根据指定测试的结果将其减半。

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 

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 .

#6


My new favorite alias, based on bonyiii's answer (upvoted), and my own answer about "Pass an argument to a Git alias command":

我最喜欢的别名,基于bonyiii的回答(upvoted),以及我自己的回答“将参数传递给Git alias命令”:

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~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.


Robert Dailey proposes in the comments the following alias:

Robert Dailey在评论中提出以下别名:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

And jegan adds in the comments:

而jegan在评论中补充道:

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\"" 

#7


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

#8


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版本上进行了测试。

#9


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 

And presto, your file is back.

而且,你的档案又回来了。

#10


I've got this solution.

我有这个解决方案。

  1. Get the id of the commit where the file was deleted using one of the ways below.

    使用以下方法之一获取文件被删除的提交的ID。

    • git log --grep=*word*
    • git log --grep = * word *

    • git log -Sword
    • git log -Sword

    • git log | grep --cOntext=5 *word*
    • git log | grep --cOntext= 5 * word *

    • git log --stat | grep --cOntext=5 *word* # recommended if you hardly remember anything
    • git log --stat | grep --cOntext= 5 * word *#推荐,如果你几乎记不起来的话

  2. You should get something like:

    你应该得到类似的东西:

commit bfe68bd117e1091c96d2976c99b3bcc8310bebe7 Author: Alexander Orlov Date: Thu May 12 23:44:27 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

commit 3ea4e3af253ac6fd1691ff6bb89c964f54802302 Author: Alexander Orlov Date: Thu May 12 22:10:22 2011 +0200

commit 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之前给我提交。

#11


git checkout /path/to/deleted.file

#12


In many cases, it can be useful to use coreutils (grep, sed, etc.) in conjunction with Git. I already know these tools quite well, but Git less so. If I wanted to do a search for a deleted file, I would do the following:

在许多情况下,将coreutils(grep,sed等)与Git结合使用会很有用。我已经非常了解这些工具了,但是Git不那么了。如果我想搜索已删除的文件,我会执行以下操作:

git log --raw | grep -B 30 $'D\t.*deleted_file.c'

When I find the revision/commit:

当我找到修订/提交时:

git checkout ^ -- path/to/refound/deleted_file.c

Just like others have stated before me.

就像其他人在我面前所说的那样。

The file will now be restored to the state it had before removal. Remember to re-commit it to the working tree if you want to keep it around.

该文件现在将恢复到删除之前的状态。如果要保留它,请记住将其重新提交到工作树。

#13


git undelete path/to/file.ext
  1. Put this in your .bash_profile (or other relevant file that loads when you open a command shell):

    将它放在.bash_profile(或打开命令shell时加载的其他相关文件)中:

    git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
    
  2. Then use:

    git undelete path/to/file.ext
    
  3. 然后使用:git undelete path / to / file.ext

This alias first checks to find the last commit where this file existed, then does a git checkout of that file path from that last commit where this file existed. source

此别名首先检查以查找此文件存在的最后一次提交,然后从该文件存在的最后一次提交执行该文件路径的git检出。资源

#14


So I had to restore a bunch of deleted files from a specific commit and I managed it with two commands:

所以我不得不从特定的提交中恢复一堆已删除的文件,并使用两个命令进行管理:

git show  --diff-filter=D --summary --name-only --no-commit-id | xargs git checkout ^ -- 
git show  --diff-filter=D --summary --name-only --no-commit-id | xargs git reset HEAD 

(Note the trailing space on the end of each command.)

(注意每个命令末尾的尾随空格。)

The files had been added to the .gitignore file and then cleared with git rm, I needed to restore the files but then unstage them. I had hundreds of files to restore, typing things manually for each file as in the other examples was going to be far too slow.

这些文件已经添加到.gitignore文件中,然后用git rm清除,我需要恢复文件,然后取消它们。我有几百个要恢复的文件,为每个文件手动输入内容,因为在其他示例中这将太慢。

#15


user@bsd:~/work/git$ rm slides.tex
user@bsd:~/work/git$ git pull 
Already up-to-date.
user@bsd:~/work/git$ ls slides.tex
ls: slides.tex: No such file or directory

Restore the deleted file:

恢复已删除的文件:

user@bsd:~/work/git$ git checkout
D       .slides.tex.swp
D       slides.tex
user@bsd:~/work/git$ git checkout slides.tex 
user@bsd:~/work/git$ ls slides.tex
slides.tex

#16


I had the same question. Without knowing it, I had created a dangling commit.

我有同样的问题。在不知情的情况下,我创造了一个悬空的提交。

List dangling commits

列出悬空提交

git fsck --lost-found

git fsck --lost-found

Inspect each dangling commit

检查每个悬挂的提交

git reset --hard

git reset --hard

My files reappeared when I moved to the dangling commit.

当我转向悬空提交时,我的文件重新出现。

git status for the reason:

git状态原因如下:

“HEAD detached from

“HEAD与 <分配的提交id分离> ”

#17


In our case we accidentally deleted files in a commit and some commit later we realized our mistake and wanted to get back all the files that were deleted but not those that were modified.

在我们的例子中,我们意外地删除了提交中的文件,稍后我们意识到了我们的错误,并希望找回所有已删除但未修改的文件。

Based on Charles Bailey's excellent answer here is my one liner:

根据Charles Bailey的优秀答案,这是我的一个班轮:

git co $(git rev-list -n 1 HEAD -- )~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- )~1 head | grep '^D' | cut -f 2)

#18


If you know the commit that deleted the file(s), run this command where is the commit that deleted the file:

如果您知道删除文件的提交,请运行此命令,其中 是删除文件的提交:

git diff --diff-filter=D --name-only ~1  | xargs git checkout ~1 --

The part before the pipe lists all the files that were deleted in the commit; they are all checkout from the previous commit to restore them.

管道前面的部分列出了提交中删除的所有文件;它们都是从上一次提交结账以恢复它们。

#19


Actually, this question is directly about Git, but somebody like me works with GUI tools like WebStorm VCS other than knowing about git cli commands.

实际上,这个问题直接关于Git,但是像我这样的人使用WebStorm VCS等GUI工具,而不是了解git cli命令。

I right click on the path that contains the deleted file, then go to Git and then click on Show History.

我右键单击包含已删除文件的路径,然后转到Git,然后单击“显示历史记录”。

enter image description here

The VCS tools show all revisions train and I can see all commits and changes of each of them.

VCS工具显示所有修订版本,我可以看到每个版本的所有提交和更改。

enter image description here

Then I select the commits that my friend delete the PostAd.js file. now see below:

然后我选择我的朋友删除PostAd.js文件的提交。现在看下面:

enter image description here

And now, I can see my desire deleted file. I just double-click on the filename and it recovers.

现在,我可以看到我的愿望删除文件。我只需双击文件名即可恢复。

enter image description here

I know my answer is not Git commands but it is fast, reliable and easy for beginner and professional developers. Webstorm VCS tools are awesome and perfect for working with Git and doesn't need any other plugin or tools.

我知道我的答案不是Git命令,但它对于初学者和专业开发人员来说快速,可靠且容易。 Webstorm VCS工具非常棒,非常适合与Git一起使用,不需要任何其他插件或工具。

#20


Simple and precise-

简单而精确 -

First of all, get a latest stable commit in which you have that file by -

首先,获取最新的稳定提交,其中您拥有该文件 -

git log 

Say you find $commitid 1234567..., then

假设您找到$ commitid 1234567 ...,然后

git checkout <$commitid> $fileName

This will restore the file version which was in that commit.

这将恢复该提交中的文件版本。

#21


$ git log --diff-filter=D --summary  | grep "delete" | sort

推荐阅读
author-avatar
打篮球的乔巴
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有