Git还原已删除的文件并保留文件历史记录

时间:2015-08-19 17:06:10

标签: git git-revert git-blame

假设我有一个文件a.txt。有一天,我删除了它,承诺并推动了它。

第二天,我想恢复最后一次提交,带回a.txt。我尝试使用git revert,但当我git blame时,所有行都显示了恢复提交哈希。最初的责备历史遗失了。

我可以恢复文件并保留文件历史记录,即好像之前没有删除过文件吗?请注意,我不得在推送提交时更改历史记录。

谢谢!

3 个答案:

答案 0 :(得分:7)

CAN 这样做!以下是:

  1. 从要撤消的删除前的提交中启动新分支。
  2. 将违规更改与git merge <sha> -s ours合并。
  3. 如果提交除了要保留的删除之外还有其他更改:
    1. 使用git diff <sha>^..<sha> | git apply重新应用对工作副本的更改。
    2. 放弃删除(许多技术可用; git checkout -p可能适合您)。
  4. 将此分支合并回主分支(例如master)。
  5. 这产生了一个有两个分支的历史;一个文件被删除的文件,另一个文件从未被删除。因此,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