在Git存储库中查找和恢复已删除的文件
说我在Git仓库。 我删除一个文件并提交更改。 我继续工作,做更多的承诺。 然后,我发现我需要恢复该文件。
我知道我可以使用git checkout HEAD^ foo.bar
来签出一个文件,但是我不知道该文件何时被删除。
- find删除给定文件名的提交最快的方法是什么?
- 将该文件恢复到我的工作副本最简单的方法是什么?
我希望我不必手动浏览我的日志,签出一个给定的SHA整个项目,然后手动将该文件复制到我原来的项目结帐。
find影响给定path的最后一个提交。 由于该文件不在HEAD提交中,因此该提交必须将其删除。
git rev-list -n 1 HEAD -- <file_path>
然后使用脱字符号( ^
)符号检出之前提交的版本:
git checkout <deleting_commit>^ -- <file_path>
或者在一个命令中,如果$file
是有问题的文件。
git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"
- 使用
git log --diff-filter=D --summary
获取删除文件和删除文件的所有提交; - 使用
git checkout $commit~1 filename
来恢复被删除的文件。
要恢复文件夹中所有已删除的文件,请input以下命令。
git ls-files -d | xargs git checkout --
如果你疯了,使用git-bisect
。 这是做什么:
git bisect start git bisect bad git bisect good <some commit where you know the file existed>
现在是时候运行自动化testing了。 如果存在foo.bar
,shell命令'[ -e foo.bar ]'
将返回0,否则返回1。 git-bisect
的“run”命令将使用二进制search来自动查找testing失败的第一个提交。 它从给定的范围(从好到坏)开始中途,根据指定的testing结果将其减半。
git bisect run '[ -e foo.bar ]'
现在你在删除它的提交。 从这里开始,你可以跳回到将来,用git-revert
来取消这个改变,
git bisect reset git revert <the offending commit>
或者您可以返回一个提交并手动检查损坏情况:
git checkout HEAD^ cp foo.bar /tmp git bisect reset cp /tmp/foo.bar .
我来到这个问题寻找恢复我刚刚删除的文件,但我还没有承诺的变化。 万一你发现自己处在这种情况下,你只需要做以下事情:
git checkout HEAD -- path/to/file.ext
我最喜欢的别名,基于bonyiii的回答 (upvoted)和我自己的回答:“ 传递参数给Git别名命令 ”:
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'
我已经丢失了一个文件,在几次提交之前被误删了?
快:
git restore my_deleted_file
危机避免了。
罗伯特·戴利 在评论中提出了以下别名:
restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"
而jegan补充说 :
为了从命令行设置别名,我使用了这个命令:
git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\""
恢复已删除并提交的文件:
git reset HEAD some/path git checkout -- some/path
它在Git版本1.7.5.4上进行了testing。
如果你知道文件名,这是一个简单的方法与基本的命令:
列出该文件的所有提交。
git log -- path/to/file
最后一个提交(最上面)是删除文件的提交。 所以你需要恢复第二个到最后一个提交。
git checkout {second to last commit} -- path/to/file
我有这个解决scheme 。
-
使用以下某种方法获取文件被删除的提交的ID。
-
git log --grep=*word*
-
git log -Sword
-
git log | grep --context=5 *word*
-
git log --stat | grep --context=5 *word*
git log --stat | grep --context=5 *word*
#如果你几乎不记得任何东西,
-
-
你应该得到像这样的东西:
提交bfe68bd117e1091c96d2976c99b3bcc8310bebe7作者:Alexander Orlovdate:四月12日星期四23:44:27 2011 +0200
replaced deprecated GWT class - gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script
提交3ea4e3af253ac6fd1691ff6bb89c964f54802302作者:Alexander Orlovdate:四月12日星期四22:10:22 2011 +0200
3 。 现在使用提交ID bfe68bd117e1091c96d2976c99b3bcc8310bebe7做:
git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java
由于提交ID引用文件已经被删除的提交,你需要引用在bfe68b之前的提交,你可以通过追加^1
。 这意味着:在bfe68b之前给我提交。
如果您只做了更改并删除了一个文件,但没有提交,现在您已经与您的更改分手了
git checkout -- .
但你删除的文件没有返回,你只需要执行下面的命令:
git checkout <file_path>
而且,你的文件又回来了。
git checkout /path/to/deleted.file
在许多情况下,将coreutils (grep,sed等)与Git结合使用会非常有用。 我已经很了解这些工具,但Git不那么重要。 如果我想要search已删除的文件,我会执行以下操作:
git log --raw | grep -B 30 $'D\t.*deleted_file.c'
当我find修订/提交时:
git checkout <rev>^ -- path/to/refound/deleted_file.c
就像其他人在我之前所说的一样。
该文件现在将恢复到删除之前的状态。 如果你想保留它,记得重新提交到工作树。
git undelete path/to/file.ext
-
把它放在你的
.bash_profile
(或者打开一个命令shell时加载的其他相关文件)中:git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
-
然后使用:
git undelete path/to/file.ext
这个别名首先检查find这个文件存在的最后一个提交,然后从该文件存在的最后一个提交执行该文件path的git检出。 资源
所以我不得不从一个特定的提交恢复一堆已删除的文件,我用两个命令来pipe理它:
git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git checkout <rev>^ -- git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git reset HEAD
(注意每个命令末尾的尾部空格。)
这些文件已被添加到.gitignore文件,然后用git rm清除,我需要恢复文件,但是然后取消它们。 我有数百个文件要恢复,为每个文件手动input的东西,如在其他例子将是太慢了。
在我们的例子中,我们意外地删除了一个提交中的文件,稍后我们意识到我们的错误,并希望找回所有被删除的文件,但不是那些被修改的文件。
基于查尔斯·贝利的优秀答案,这里是我的一个class轮:
git co $(git rev-list -n 1 HEAD -- <file_path>)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- <file_path>)~1 head | grep '^D' | cut -f 2)
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
还原已删除的文件:
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
如果您知道删除文件的提交,请运行此命令,其中<SHA1_deletion>
是删除该文件的提交:
git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --
pipe道之前的部分列出了在提交中被删除的所有文件; 他们都是从以前的提交结算,以恢复他们。
如果您遇到这个问题的频率更高,而且您愿意使用Git GUI工具,请查看DeepGit并在其中使用File | Search 。