假设我在Git存储库中。我删除一个文件并提交更改。我继续工作,并做出更多承诺。然后,我发现删除该文件后需要恢复该文件。
我知道我可以使用gitcheckout<commit>--filename.txt签出文件,但我不知道该文件何时被删除。
如何查找删除给定文件名的提交?如何将该文件恢复到工作副本中?
假设我在Git存储库中。我删除一个文件并提交更改。我继续工作,并做出更多承诺。然后,我发现删除该文件后需要恢复该文件。
我知道我可以使用gitcheckout<commit>--filename.txt签出文件,但我不知道该文件何时被删除。
如何查找删除给定文件名的提交?如何将该文件恢复到工作副本中?
当前回答
查找删除文件的提交:
git log --diff-filter=D --oneline -- path/to/file | cut -f -d ' '
样本输出:
4711174
从Git 2.23开始,实际上有一个restore命令。它仍然是实验性的,但为了恢复您在提交中删除的内容(在本例中为4711174),您可以键入:
git restore --source=4711174^ path/to/file
注意提交id之后的^,因为我们希望从删除文件之前的提交中恢复一些内容。
--source参数告诉restore命令在哪里查找要还原的文件,它可以是任何提交,甚至可以是索引。
参见:git 2.23.0的git restore doc
其他回答
我最喜欢的别名,基于bonyiii的答案(已投票),以及我自己关于“向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
危机得以避免。
警告:Git 2.23(2019年第3季度)带来了名为Git restore(!)的实验命令。因此,请重命名此别名(如下所示)。
罗伯特·戴利在评论中提出了以下别名:
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 reset HEAD some/path
git checkout -- some/path
它在Git 1.7.5.4版本上进行了测试。
我也有同样的问题。在不知情的情况下,我创建了一个悬空的承诺。
列出悬空提交
git fsck—找到丢失
检查每个悬空提交
git reset--hard<commit id>
当我移动到悬空提交时,我的文件再次出现。
git状态,原因如下:
“HEAD从<commit id where it detached>分离”
如果尚未提交删除,下面的命令将在工作树中恢复已删除的文件。
$ git checkout -- <file>
您可以使用下面的命令获取工作树中所有已删除文件的列表。
$ git ls-files --deleted
如果已提交删除,请找到发生删除的位置,然后从此提交中恢复文件。
$ git rev-list -n 1 HEAD -- <file>
$ git checkout <commit>^ -- <file>
如果您正在查找要恢复的文件路径,以下命令将显示所有已删除文件的摘要。
$ git log --diff-filter=D --summary
git checkout /path/to/deleted.file