我使用Git,我知道:
git revert <hash-code>
用于创建与散列代码中的过去提交相同的新提交。
例如,我有以下提交:
1f74a0e second commit
e72d8b8 first commit
我想恢复第一次提交,所以我使用:
git revert 1f74a0e
但是,我还是得到了以下错误:
错误:无法还原1f74a0e...第一个提交提示:解决冲突后,标记正确的路径提示:使用'git add '或'git rm '提示:然后使用'git commit'提交结果
至于冲突,我键入:
$ git diff --name-only --diff-filter=U
file.txt
当我打开file.txt时,我没有看到冲突的迹象。
当然会有冲突。我希望git接受“第一次提交”并将其复制到第二次提交之上。我该怎么做?
4条答案
按热度按时间mkshixfv1#
这实际上不是revert所做的。Revert不会“带你回到”那个提交,并假装后续的提交没有发生。它应用单个提交的逻辑否定-以及 that commit alone -将后续提交保留在适当位置。
假设你有一些文件的初始提交-为了简单起见,我们称之为提交#1-文件看起来像这样:
现在让我们假设你有一个提交#2,它改变了一行:
最后,提交#3,更改另一行:
如果你尝试恢复提交#2,它只会撤消在该提交中更改的行,并保留在提交#3中引入的更改,因此结果将是:
现在,如果有一个后续的提交更改了与您试图恢复的提交相同的行,那么您将遇到冲突。例如,假设你有一个提交#4,它也改变了第二行:
现在如果你的HEAD是commit #4,而你试图恢复commit #2,你会有一个冲突。Revert期望将第二行收回-以撤销在提交#2中所做的更改。因此,它期望第二行当前为
2
,然后将其恢复为上一次提交中的状态,将其设置为Two
。然而,这个期望是无效的,因为提交#4也改变了它。所以你有冲突。
如果你的目标根本不是恢复,而是回到提交#1并忽略 * 所有 * 从那时起发生的更改,那么你应该使用
reset
而不是revert
。zpqajqem2#
我在补充@Edward的回答。首先,revert命令要求“你的工作树是干净的(没有来自HEAD提交的修改)”(参见文档here)。revert 命令将恢复给定提交的更改,并将您的当前状态与您正在恢复的更改的提交的PARENT进行比较。如果当前状态和PARENT冲突,git会指出。如果没有,你就不会有冲突。
下面是一个基于@Edward's的例子:
假设你有三次提交修改了一个文件:
commit1:
commit2
commit3
如果你从当前状态(提交3,假设清除3,也就是说,没有修改HEAD提交)恢复提交2引入的更改,git将
1.删除
commit 2
引入的修改,将2
改回two
1.保留
commit 3
中引入的行three
。不会发生冲突,因为当前状态(commit 3
)与我们正在恢复的提交(commit 2
)的父状态(commit 1
)不冲突。现在,假设你有一个不同的情况:
commit1:
commit2
commit3
如果从当前状态恢复
commit 2
引入的更改(commit 3
,假设清除3,即HEAD提交没有修改),git将1.删除提交2引入的修改,将
2
改回21.将
commit 3中引入的行与
commit 2的父行进行比较,并指出冲突:行
three更改为
3`,并与我们正在恢复其更改的提交(提交2)的父提交(提交1)冲突icnyk63a3#
很可能您的索引中已经存在未解决的冲突,这可能是因为在两者之间留下了某些合并,或者还原本身导致了冲突。在任何情况下,您都需要解决冲突并提交。
dy2hfwbg4#
我在尝试从许多相邻删除的线性历史中还原提交时发现了这个问题。Git拒绝做
git revert
,并建议做冲突解决。但我知道这只是删除,他们是安全的恢复。它是配置文件,所以我很好将行放回与其他行相关的任何行。我的解决方案:
(魔术是用
--fuzz=999
,458d9d0a7b是用于反转的提交哈希)。补丁已经把行放在了一个稍微不同的位置(因为原来的'位置'被删除),但对于我的配置文件的情况下,这是好的。