说我在Git存储库中。我删除了一个文件并提交了更改。我继续工作,并做了一些更多的提交。然后,我发现我需要恢复该文件。
我知道我可以使用 git checkout HEAD^ foo.bar
,但我真的不知道该文件何时被删除。
- 找到删除给定文件名的提交的最快方法是什么?
- 将该文件恢复到我的工作副本的最简单方法是什么?
我希望我不必手动浏览我的日志,检查整个项目的给定SHA,然后手动将该文件复制到我的原始项目结帐中。
说我在Git存储库中。我删除了一个文件并提交了更改。我继续工作,并做了一些更多的提交。然后,我发现我需要恢复该文件。
我知道我可以使用 git checkout HEAD^ foo.bar
,但我真的不知道该文件何时被删除。
我希望我不必手动浏览我的日志,检查整个项目的给定SHA,然后手动将该文件复制到我的原始项目结帐中。
查找影响给定路径的最后一次提交。由于该文件不在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"
如果您使用zsh并启用了EXTENDED_GLOB选项,则插入符号将不起作用。您可以使用 ~1
代替。
git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"
git log --diff-filter=D --summary
获取已删除文件和删除文件的所有提交;git checkout $commit~1 filename
恢复已删除的文件。哪里 $commit
是您在步骤1中找到的提交的值,例如 e4cf499627
要还原文件夹中的所有已删除文件,请输入以下命令。
git ls-files -d | xargs git checkout --
我来到这个问题寻找恢复我刚删除的文件,但我还没有提交更改。如果您发现自己处于这种情况,您需要做的就是以下内容:
git checkout HEAD -- path/to/file.ext
如果你疯了,请使用 git-bisect
。这是做什么的:
git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>
现在是时候运行自动化测试了。 shell命令 '[ -e foo.bar ]'
如果是,将返回0 foo.bar
存在,否则为1。 “运行”命令 git-bisect
将使用二进制搜索自动查找测试失败的第一个提交。它从给定范围的中间开始(从好到坏),并根据指定测试的结果将其减半。
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 .
我最喜欢的别名,基于 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"
为了从命令行设置别名,我使用了以下命令:
git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\""
如果您知道文件名,这是使用基本命令的简单方法:
列出该文件的所有提交。
git log -- path/to/file
最后一次提交(最顶层)是删除文件的提交。所以你需要恢复倒数第二次提交。
git checkout {second to last commit} -- path/to/file