假设我有一个文件a.txt
。有一天,我删除了它,承诺并推动了它。
第二天,我想恢复最后一次提交,带回a.txt
。我尝试使用git revert
,但当我git blame
时,所有行都显示了恢复提交哈希。最初的责备历史遗失了。
我可以恢复文件并保留文件历史记录,即好像之前没有删除过文件吗?请注意,我不得在推送提交时更改历史记录。
谢谢!
答案 0 :(得分:7)
你 CAN 这样做!以下是:
git merge <sha> -s ours
合并。git diff <sha>^..<sha> | git apply
重新应用对工作副本的更改。git checkout -p
可能适合您)。这产生了一个有两个分支的历史;一个文件被删除的文件,另一个文件从未被删除。因此,git能够跟踪文件历史记录而无需诉诸-C -C -C
等英雄事迹。 (事实上,即使使用-C -C -C
,该文件也不会被恢复&#34;,因为git看到的是一个新文件被创建为作为副本以前存在的文件。使用此技术,您将相同的文件重新引入存储库。)
答案 1 :(得分:1)
使用指定的-C
选项运行git blame三次:
git blame -C -C -C
这会导致git blame
查找从先前提交中的文件复制的内容。
来自the documentation for git blame
:
<强>
-C|<num>|
强>除了
-M
之外,检测从其他文件中移动或复制的行 在同一次提交中被修改。重组时这很有用 您的程序并跨文件移动代码。当这个选项是 给定两次,该命令另外查找来自其他的副本 创建文件的提交中的文件。当给出此选项时 三次,该命令另外查找来自其他的副本 任何提交中的文件。
<num>
是可选的,但它是数字的下限 Git必须检测到的字母数字字符在移动/复制之间 用于将这些行与父提交相关联的文件。而且 默认值为40.如果给出了多个-C
个选项,则为 <{1}}的{{1}}参数将生效。
答案 2 :(得分:0)
您可以使用git reset
代替git revert
来完成此操作。 git reset
删除新提交并签出先前的提交。如果您已经推送到上游,则不建议这样做。
NAME
git-reset - Reset current HEAD to the specified state
SYNOPSIS
git reset [-q] [<tree-ish>] [--] <paths>...
git reset (--patch | -p) [<tree-ish>] [--] [<paths>...]
git reset [--soft | --mixed | --hard | --merge | --keep] [-q] [<commit>]
DESCRIPTION
In the first and second form, copy entries from <tree-ish> to the index. In the third form, set the
current branch head (HEAD) to <commit>, optionally modifying index and working tree to match. The
<tree-ish>/<commit> defaults to HEAD in all forms.
因为你已经推了:
git reset
并强行推送git push -f
。