21

我在 Git 合并时遇到了这个奇怪的问题,我无法解释或分类。是否缺少提交。是不是合并出错了?是数据损坏了吗?这是存储库历史的样子:

master----\----commit A----cherry-picked changesets from topic---commit B--\----commit C----merge---
           \                                                                \              /
            topic-----------------------------------------------------------merge---------/

现在,我的问题是,当master合并到topic分支中时(使其与提交 A 和 B 保持同步),提交 B 引入的变更集不存在!如果提交 B 正在修改文件foo& bar,即使得到很多也不会显示这些文件随着合并而更改。文件中甚至没有任何冲突,foo并且bar

现在,当我topic 重新合并到时master,提交 B 被有效地反转,没有任何日志或反转的痕迹!

可能出了什么问题?

4

2 回答 2

12
master----\----commit A----cherry-picked changesets from topic---commit B--\----commit C----merge---
           \                                                                \              /
            topic-----------------------------------------------------------merge---------/
                                                                            ~~~~~
                                                                              ^
                                                                              + here you merged B in topic

主题中已经有一个以提交 B 作为父级的合并。所以 B 完全合并到主题中,不会再合并到任何地方。

由于您没有主题更改,因此您显然在合并本身或后续提交中将它们还原为主题。这种反转是合并算法的常规提交,它不会合并到主控中。因此,当您将 topic 合并到 master 时,此提交的更改将被合并,恢复提交 B。

要从 B 取回更改,您必须:

  • 查找并还原 B 对主题的更改的逆转。
  • 选题B ( git cherry-pick B)。
  • 重做合并,在新合并后重新设置主题并忘记原始分支,但由于这涉及倒带,您只能在控制所有具有该分支的存储库时执行此操作。

在你没有意识到的情况下,这些变化是如何被逆转的?如果您正在合并并遇到冲突,您可能会草率地使用“本地”解决它们,认为您还不需要这些更改。但是从 Git(或任何其他版本控制系统;3 路合并在所有这些系统中的工作方式相同)的角度来看,您已经看到了更改并拒绝了它们,所以您永远不会再得到它们,除非您手动重新应用它们。

冲突可能很容易由早期的樱桃挑选引起。虽然如果双方看起来相同,则算法不会声明冲突,因此如果您选择而不是合并,如果您修改一侧的樱桃选择代码,它将声明冲突。假设你有:

----\-- A -------- B' -- B2 --\
     \                         \
      D -- B -- E -----------merge

whereB'选择BB2修改相同的代码B。在这种情况下,合并将看到一侧做B了,另一侧做了B2,因为樱桃选择被隐藏了,因此会声明andB2之间的冲突。如果你不仔细查看历史,你可能很容易解决这个错误。如果在选择提交时小心地将目标分支合并到源分支,则可以避免该问题,如下所示:BB2

----\-- A --------\- B' -\- B2 --\
     \             \      \       \
      D -- B -- E --m1-----m2----merge

哪里m1是正常合并,不涉及樱桃挑选,并m2用本地版本解决,因为它只有远程挑选的变化。这将确保进一步的合并将正常工作。

实际上应该可以为 git 编写一个合并策略来自动执行此操作。

于 2012-11-20T08:04:55.427 回答
2

不知道为什么B不存在,但我建议重新topic设置基础master而不是合并mastertopic.

您精心挑选的提交被复制到master中,并且在合并到已经存在相同提交master的分支 ( ) 时效果不佳。 当您在 :之上重新设置基准时,情况会有所不同:不会重播任何重复的提交。topic
topicmaster

当然,rebase 的问题在于更改topicSHA1,如果您已经推topic送到上游仓库(并且其他人已经拉取topic),这将是有问题的。

一般来说,如“什么是具有共享功能分支的正确 git 工作流? ”中所示,您会希望避免“反向合并”(masterto topic)并主要仅以一种方式(topicto )使用合并master

于 2012-11-20T07:06:03.530 回答