为什么我执行 git revert 时会出现冲突?

问题描述 投票:0回答:4

我使用 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 获取“第一次提交”并将其复制到第二次提交之上。我该怎么办?

git git-revert
4个回答
45
投票

这实际上不是恢复的作用。 恢复不会“带您回到”该提交并假装后续提交没有发生。 它应用单个提交的逻辑否定 - 以及 单独提交 - 保留后续提交。

假设您对某个文件进行了一些初始提交 - 为了简单起见,我们将其称为提交#1 - 文件如下所示:

One
Two
Three
Four

现在假设您有一个提交 #2 更改了一行:

One
2
Three
Four

最后,提交 #3 更改不同的行:

One
2
Three
4

如果您尝试恢复提交 #2,它将仅撤消该提交中更改的行,并保留提交 #3 中引入的更改,因此结果将是:

One
Two
Three
4

现在,如果后续提交更改了与您尝试恢复的提交相同的行,那么您将遇到冲突。 例如,假设您有一个提交#4,它也更改了第二行:

One
TWO
THREE
4

现在,如果您的 HEAD 是提交#4,并且您尝试恢复提交#2,则会发生冲突。 Revert 期望收回第二行 - 撤消提交 #2 中所做的更改。 因此,它预计第二行当前为

2
,然后将其恢复为上一次提交中的内容,将其设置为
Two

然而,这个期望是无效的,因为提交#4已经改变了它。 所以你们之间有冲突。

如果您的目标根本不是恢复,而是返回到提交#1并忽略从那时起发生的所有更改,那么您需要

reset
而不是
revert

git reset --hard 1 

8
投票

我正在补充@Edward的答案。首先,恢复命令要求“您的工作树是干净的(没有来自 HEAD 提交的修改)”(请参阅文档此处)。 revert 命令将恢复给定提交的更改,并将您当前的状态与您要恢复其更改的提交的父级状态进行比较。如果当前状态与 PARENT 冲突,git 会指出这一点。如果没有,你就不会发生冲突。

这是一个基于@Edward 的示例:

假设您有 3 个修改文件的提交:

commit1:

One
Two

commit2

One
2       # < we introduced this changed in commit 2

commit3

One
2
three   # < we introduced this change in commit 3

如果您从当前状态恢复提交 2 引入的更改(提交 3,假设清除 3,即 HEAD 提交没有修改),git 会

  1. 删除
    commit 2
    引入的修改,将
    2
    更改回
    two
  2. 保留
    three
    中介绍的线
    commit 3
    。不会发生冲突,因为当前状态 (
    commit 3
    ) 与我们要恢复其更改的提交的父级 (
    commit 1
    ) 不冲突 (
    commit 2
    )

现在,假设您有不同的情况:

commit1:

One
Two
three

commit2

One
2       # < we introduced this changed in commit 2
three

commit3

One
2
3   # < we introduced this change in commit 3

如果您从当前状态恢复

commit 2
引入的更改(
commit 3
,假设清除三个,即 HEAD 提交没有修改),git 会

  1. 删除该提交 2 引入的修改,将
    2
    更改回 2`
  2. commit 3
    中引入的行与
    commit 2
    的父行进行比较并指示冲突:行
    three
    更改为
    3
    并与我们要恢复其更改的提交(提交 2)的父行(提交 1)冲突

0
投票

很可能您的索引中已经存在未解决的冲突,可能是因为中间留下了某些合并,或者恢复本身导致了冲突。无论如何,您需要解决冲突并提交。

git status
# You would find files with conflicts
# resolve the commits

git add -u
git commit

0
投票

我在尝试从许多相邻删除的线性历史记录中恢复提交时发现了这个问题。 Git 拒绝执行

git revert
并建议执行冲突解决。但我知道这只是删除,而且它们可以安全地恢复。它是配置文件,所以我可以将行放回到与其他行相关的任何行上。

我的解决方案:

git show 458d9d0a7b | patch --fuzz=999 -p1 -R

(魔法在于

--fuzz=999
,458d9d0a7b 是用于反转的提交哈希)。

补丁将行放在稍微不同的位置(因为原始的“位置”被删除),但对于我的配置文件来说,这是可以的。

© www.soinside.com 2019 - 2024. All rights reserved.