假设我有一个文件a.txt
。有一天,我删除了它,承诺并推送了它。Git还原已删除的文件并保留文件历史记录
第二天,我想恢复上次提交,将a.txt
带回。我尝试使用git revert
,但是当我做了git blame
时,所有行都显示了恢复提交哈希。原来的责备历史已经失传。
我可以恢复文件并保留文件历史记录吗?就好像文件还没有被删除过?请注意,我不能在提交被推送时更改历史记录。
谢谢!
假设我有一个文件a.txt
。有一天,我删除了它,承诺并推送了它。Git还原已删除的文件并保留文件历史记录
第二天,我想恢复上次提交,将a.txt
带回。我尝试使用git revert
,但是当我做了git blame
时,所有行都显示了恢复提交哈希。原来的责备历史已经失传。
我可以恢复文件并保留文件历史记录吗?就好像文件还没有被删除过?请注意,我不能在提交被推送时更改历史记录。
谢谢!
您可以通过使用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
。他已经删除了文件并推送到上游,此时'git reset'不适用于他。 – shengy
与-C
选项运行git怪指定三次:
git blame -C -C -C
这将导致git blame
查找从文件在以前提交复制的内容。
the documentation for git blame
来自:
-C|<num>|
除了
-M
,检测线移动或从其它文件复制的 是在相同的修改提交。当您重新组织 并在代码中移动代码时,这非常有用。当这个选项是 给出两次时,该命令另外在创建该文件的提交中查找来自其他 文件的副本。当这个选项被给予 三次时,该命令另外在任何提交中查找来自其他 文件的副本。
<num>
是可选的,但它是下界上GIT中必须检测 文件之间作为移动/复制为它与母提交这些线相关联的字母数字 字符数。 默认值为40.如果给出的选项不止一个-C
,则最后的-C
的参数<num>
将生效。
你确定这有效吗?我试过类似'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 commit -m“Commit 3”''git revert HEAD''git blame -C -C -C a.txt' and这两行显示恢复提交... – fushar
@fushar我敢肯定,你需要多个单词让git注册你移动了一些东西,文档中说最少有40个字符,我在我的回答中编辑了引用 – Ajedi32
我只是想表明你的解决方案在最简单的例子中不起作用,实际上它并不适用于我的真实项目(我删除的文件内容远远大于40)。 - 'git blame -C1 -C1 -C1 a.txt'不幸也不适用于'a.txt'的例子。 – fushar
您CAN做到这一点!方法如下:
git merge <sha> -s ours
合并。git diff <sha>^..<sha> | git apply
重新应用更改到你的工作副本。git checkout -p
可能适合您)。这产生了两个分支的历史;其中一个文件被删除,其中一个它从未被删除。因此,git能够跟踪文件历史,而不诉诸于诸如-C -C -C
这样的英雄。 (事实上,即使使用-C -C -C
,该文件也不会被“恢复”,因为git会看到的是,一个新文件被创建为作为先前存在文件的副本。使用此技术,您将重新引入相同的文件)。
作品像一种享受,我现在学到了东西,谢谢@Matthew!我的情况相当复杂,我需要阅读一下'git checkout -p',但即使在部分违规提交中进行了混合更改,此方法也完全按照我需要的方式工作。 – bossi
您的意思是说您无法对上游进行强制推送? – shengy
Git不会跟踪文件历史记录;它只跟踪整个根目录的历史记录。因此,在请求查看历史记录时,重建文件历史记录是一个问题,而不是在恢复文件时。 – Nayuki
@shengy不,我不能 – fushar