修复被推送的 'backwards' git 合并

Fixing 'backwards' git merge that was pushed

我 运行 在我的 git 分支之间遇到了一个问题,我不确定如何处理。假设我正在处理的每个版本都有单独的分支。例如,我有 'Release-1' 和 'Release-2' 作为我的分支。这些版本本质上是顺序的,即 'Release-2' 包含 'Release-1,' 中的所有内容,但反之则不然。就我而言,我不小心将 'Release-2' 合并到 'Release-1' 并在没有意识到我的错误的情况下推送了它。一个我意识到我犯了一个错误,我继续发布:

git revert -m 1 <sha-of-bad-merge-commit>

这似乎解决了所有问题; 'Release-2' 代码中的 none 在 'Release-1' 中并且全部显示正确。我把它推到我的上游,认为它已经解决了。快进到今天。我在 'Release-1' 分支中应用了错误修复。现在,我想将 'Release-1' 合并到 'Release-2,' 中,但我 运行 陷入冲突。 Git 认为从之前的还原中所做的更改应该合并到 'Release-2.' 本质上,git 想删除 'Release-2' 中意外引入 [=28] 的更改=] 来自 'Release-2' 当我尝试合并时。

我已经尝试研究解决方案,但没有找到。我发现最接近的应用是过早合并、恢复,然后在稍后尝试再次合并。解决方案是还原还原,然后再次进行合并。我不认为这在这种情况下会起作用,因为那会重新将更改引入 'Release-1' 中,而这些更改不应该在 'Release-1.'

除了逐行查看每个受影响的文件以 select 正确的更改集之外,是否有更好的 'git-based' 方法来处理此问题?我不想简单地从存在冲突的 'Release-2' 分支中获取更改,因为其中一些可能是 legitimate。另外,我考虑过将 bug 修复分支合并到 'Release-2,' 但是这个问题将来可能会再次出现。我想防止这种情况发生。

粗略的情况如下:

(Release-2) ---A----B----C---x---x---------*D*
                          \               /
(Release-1) ---x----Y------M---x---^M----Z

假设 A、B 和 C 是我想要 'Release-2.' 的正常提交 'Release-1' 的提示是 Y 并且仅包含 'Release-1' 工作。 Commit 'M' 是我在 'Release-1' 分支中不小心合并了 commit 'C' 和 commit 'Y' 的地方。在某些时候,我注意到我的错误并恢复合并(提交'^M')。提交 'Z' 然后在其中包含我的修补程序。此时我想将 'Release-1' 合并回 'Release-2.' 我这样做并最终在 'D.' 这就是我遇到问题的地方。本质上,我在 'D' 的合并告诉它要删除我不想要的 'A,' 'B,' 和 'C,' 中所做的所有更改。由于合并还原,其他文件显示为冲突。例如,我在 'Release-2' 中想要的一些文件在我进行还原时在 'Release-1' 中被删除了。现在,'D,' git 告诉我存在合并冲突,因为一个分支删除了文件而另一个分支修改了文件。

如果有人有任何建议,我将不胜感激。谢谢!

(我将把你的 ^M 提交称为 Mrevert,因为 ^ 字符在后面的一些命令中有特殊含义。)

执行 git merge --abort 放弃创建提交的尝试 D

由于您有一系列提交 x--Mrevert--Z,并且您需要引入 xZ 的更改,而不是 Mrevert 的更改,您需要一个三步过程:

  1. 使用 git merge Mrevert^ 提取到 Mrevert 为止的所有更改。 (c^ 语法表示 "the parent of commit c"。)
  2. 使用 git merge -s ours Mrevert 告诉 git 来自 ^M 恢复提交的更改已经在您的分支中。 -s ours 意味着保留我们的(即 Release-2 的)版本的树,而不用担心任何真实的 "merging".
  3. 使用 git merge Z 合并来自 Z 的更改。

这将生成如下提交图:

(Release-2) ---A----B----C---x---x---M1-----M2------M3
                          \         /      /       /
(Release-1) ---x----Y------M-------x---Mrevert----Z

如果您这样做 git diff M1 M2,您会看到 M2 不会将任何更改引入 Release-2。