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

Git还原已删除的文件并保留文件历史记录,git,git-revert,git-blame,Git,Git Revert,Git Blame,假设我有一个文件a.txt。有一天,我删除了它,提交并推送 第二天,我想恢复上一次提交,带回a.txt。我尝试使用了git revert,但是当我使用git-burn时,所有的行都显示了revert-commit散列。最初的历史已经丢失 我是否可以恢复该文件并保留该文件的历史记录,即该文件是否以前未被删除?请注意,我不能更改历史记录,因为提交已被推送 谢谢 您可以使用git reset而不是git revert来执行此操作git reset删除新提交并签出以前的提交。如果您已经推到上游,则不建议

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

第二天,我想恢复上一次提交,带回
a.txt
。我尝试使用了
git revert
,但是当我使用
git-burn
时,所有的行都显示了revert-commit散列。最初的历史已经丢失

我是否可以恢复该文件并保留该文件的历史记录,即该文件是否以前未被删除?请注意,我不能更改历史记录,因为提交已被推送


谢谢

您可以使用
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重置[-q][[-]。。。
git重置(--patch |-p)[[-][…]
git重置[--soft |--mixed |--hard |--merge |--keep][q][]
描述
在第一个和第二个表单中,将条目从复制到索引。在第三种形式中,设置
当前分支头(head)到,可以选择修改索引和工作树以匹配。这个
/在所有表单中默认为HEAD。
既然你已经推了:

  • 如果那天没有活动的协作者,请使用
    git reset
    并强制推送
    git push-f

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

git blame -C -C -C
这会导致
git
查找从以前提交的文件复制的内容

发件人:

-C | |

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

是可选的,但它是数量的下限 Git必须检测为在两个位置之间移动/复制的字母数字字符 用于将这些行与父提交关联的文件。和 默认值为40。如果提供了多个
-C
选项,则 最后一个
-C
参数将生效

你可以这样做!以下是方法:

  • 从要撤消的删除之前的提交开始新的分支
  • 使用
    git Merge-s ours
    合并有问题的更改
  • 如果除了要保留的删除之外,提交还有更改:
  • 使用
    git diff^重新应用对工作副本的更改git应用
  • 放弃删除(有许多技术可用;
    git checkout-p
    可能对您很有用)
  • 将此分支合并回主分支(例如主分支)

  • 这产生了一个有两个分支的历史;其中一个文件被删除,另一个文件从未被删除。因此,git能够跟踪文件历史,而不必求助于像
    -C-C-C
    这样的英雄行为。(事实上,即使使用
    -C-C-C
    ,文件也不会被“还原”,因为git看到的是一个新文件是作为以前存在的文件的副本创建的。通过这种技术,您可以将同一个文件重新引入到存储库。)

    您的意思是说您不能执行--强制推送到上游吗?git不跟踪文件历史记录;它只跟踪整个根目录的历史记录。因此,在请求查看历史记录时重建文件历史记录是一个问题,而不是在还原文件时。@shengy不,我不能删除文件并推到上游,
    git reset
    此时对他不起作用。你确定这能起作用吗?我尝试了类似于
    git init
    echo”test>a.txt的东西
    git add a.txt
    git commit-m“commit 1”
    echo“foobar”>>a.txt
    git add a.txt
    git commit-m“commit 2”
    git rm a.txt
    git revert HEAD
    这两行都显示了revert commit…@fushar我很确定git需要不止一个字来注册您移动了什么东西。文件上说最少40个字符。为了更加完整,我对答案中的引语进行了编辑。我只是想在最简单的例子中说明您的解决方案不起作用。实际上,它在我真正的项目上也不起作用(我删除的文件内容当然比40大得多)。对于您的编辑--
    git-C1-C1-C1 a.txt
    不幸的是,对于
    a.txt
    示例也不起作用。@fushar-Huh,您是对的。我似乎无法让它工作。文档似乎在说它应该可以工作,所以可能是个bug。要么是这样,要么就是我完全误解了它的工作原理。它就像一种享受,我现在学到了一些东西,谢谢@Matthew!我的案例相当复杂,我需要仔细阅读一下
    git checkout-p
    ,但即使在混合更改的部分违规提交中,这种方法也完全按照我的需要工作。