【问题标题】:Why do I get conflicts when I do git revert?为什么在执行 git revert 时会发生冲突?
【发布时间】:2018-02-26 17:47:45
【问题描述】:

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

【问题讨论】:

  • "...创建一个与哈希码中的过去提交相同的新提交" - 这是不正确的。 Revert 创建一个新的提交,该提交撤消在该提交中引入的更改。
  • “我知道:git revert &lt;hash-code&gt; 用于创建一个新的提交,它与哈希码中的过去提交相同。” 不,那是@987654321 @.
  • 不,那也不是git cherry-pick

标签: git git-revert


【解决方案1】:

这实际上 不是 revert 所做的。 Revert 不会“带你回到”那个提交并假装后续的提交没有发生。它对单个提交应用逻辑否定 - 单独提交 - 将后续提交留在原地。

假设您有一些文件的初始提交 - 为简单起见,我们将其称为提交 #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 

【讨论】:

  • 如果我有大量的提交要恢复(而不是重置),其中包括单独的冲突,但放在一起时不包括冲突怎么办?换句话说,假设我想恢复最近的 100 次提交,所以我做git revert 531a..HEAD。我如何进行如此大的还原并避免 git 希望我按顺序解决的虚假冲突?
【解决方案2】:

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

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

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

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,假设清除三个,即 HEAD 提交没有修改),git 将

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

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

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 并与我们正在还原其更改的提交的父级(提交1)冲突(提交2)

【讨论】:

  • 您的第二个示例和@Edward 的第一个没有冲突的示例有什么区别?
【解决方案3】:

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

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

git add -u
git commit

【讨论】:

  • 不,这个错误是因为revert 引起冲突。如果你一开始就有冲突,revert 甚至会拒绝开始,并会给你一个错误消息“Reverting is not possible because you have unmerged files”。
猜你喜欢
  • 2019-02-24
  • 2018-07-28
  • 2019-03-06
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 2016-04-07
相关资源
最近更新 更多