8

假设我有一个文件a.txt。有一天,我删除了它,提交并推送。

第二天,我想恢复上一次提交,将a.txt. 我尝试使用git revert,但是当我这样做时git blame,所有行都显示还原提交哈希。原来的责备历史丢失了。

我可以恢复文件并保留文件历史记录,即,就好像该文件以前没有被删除一样?请注意,由于提交已被推送,因此我不能更改历史记录。

谢谢!

4

3 回答 3

7

你可以做到这一点!就是这样:

  1. 从要撤消的删除之前的提交开始一个新分支。
  2. 将有问题的更改与 合并git merge <sha> -s ours
  3. 如果提交除了您要保留的删除之外还有更改:
    1. 使用 将更改重新应用到您的工作副本git diff <sha>^..<sha> | git apply
    2. 放弃删除(许多技术可用;git checkout -p可能对您很有效)。
  4. 将此分支合并回主分支(例如 master)。

这产生了一个有两个分支的历史;一种是文件被删除,另一种是从未被删除。因此,git 能够跟踪文件历史记录,而无需求助于-C -C -C. (事实上​​,即使使用-C -C -C,该文件也没有“恢复”,因为 git 看到的是一个新文件是作为先前存在的文件的副本创建的。使用这种技术,您将相同的文件重新引入存储库。 )

于 2016-06-03T19:36:25.017 回答
2

使用指定的选项运行 git blame-C三次:

git blame -C -C -C

这会导致git blame查找从先前提交中的文件复制的内容。

文档中git blame

-C|<num>|

此外-M,检测从在同一提交中修改的其他文件移动或复制的行。当您重新组织程序并跨文件移动代码时,这很有用。当此选项被给出两次时,该命令还会在创建文件的提交中查找其他文件的副本。当此选项被给出 3 次时,该命令还会在任何提交中查找来自其他文件的副本。

<num>是可选的,但它是 Git 必须检测为在文件之间移动/复制以将这些行与父提交相关联的字母数字字符数的下限。并且默认值为40。如果给出多个-C选项, <num>则最后一个的参数-C将生效。

于 2015-08-19T17:47:23.470 回答
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
于 2015-08-19T17:40:26.847 回答