为什么在合并第 2 级后将第 3 级分支合并到 master 时会发生冲突

Why I'm getting conflicts when I merge the 3rd level branch to master after merging the 2 second level

当我在工作中遇到这种情况时,我总是遇到问题

0 <- 1 <- 2 <----------- 9 <--- master
           \            /
            3 <- 4 <- 5 <------ Feature/A
                       \
                        6 <- 7 <- 8   <-- HEAD=Feature/B

所以我们有一个 master,我们从 master 创建了新的 feature/A 后来我们从 feature/A

创建了另一个特征 feature/B

现在 Feature/A5

合并到 master

我们也需要合并 Feature/B 来掌握,但是我们无缘无故地遇到了很多冲突。

请问是什么原因造成的,我该如何避免?

编辑

将B合并到master I中运行

git merge master

Feature B 我 运行 git merge-base --all HEAD master 结果是 2

这是 releae/1.14.1,您可以在下一张图表中更详细地看到它

我的图形日志命令:

git log --graph --oneline master feature/member feature/fund-test

因为feature/member是特征A

feature/fund-test 是特征 B

releae/1.14.1 是 feature/A 开始的地方,即 2

7640e46aa 是 9

|\
| * c354b9142 update claims upon registering.
|/
*   7640e46aa Merge branch 'feature/members' into 'master'
|\
| * 43ea27cb2 Feature/Members
|/
| *   ef276ed89 (HEAD -> fund-test, origin/fund-test) Merge branch 'minor-changes-fundraising-v3.1' into 'feature/fundraising-3.1'
| |\
| | * 952cfe3a9 (origin/add-missing-changes) Add changes resolve by git.
| |/
| * e924e1fc3 fixed changelog
| *   1d6eadffe Merge remote-tracking branch 'origin/feature/members' into feature/fundraising-3.1
| |\
| | * 76d3f1aa4 (origin/feature/members, feature/members) Update data service comments
| | * 5b8cdf931 Update NuGet packages
| | *   cf978c86b Merge branch 'master' into feature/members
| | |\
| |_|/
|/| |
* | |   2754d5127 Merge branch 'releae/1.14.1' into 'master'
|\ \ \
| * | | d67a38076 Update changelogs
|/ / /
| | *   aa16154e4 Merge branch 'remove/context' into 'feature/members'

编辑:鉴于哈希 ID 7640e46aa 是您绘制为 9 的提交,我们查看 7640e46aa 的两个父项。他们是:

43ea27cb2 Feature/Members

(这是 第二个 父级,因为 git log --graph 总是把那个画在右边)并且:

2754d5127 Merge branch 'releae/1.14.1' into 'master'

(这是 第一个 父级,就在您称为 2 的提交下方。所以图表的第一行是正确的。但是,提交 43ea27cb2 Feature/Members 对应于您称为 5 的提交:它是一个独立的提交,以 2754d5127 作为其(单个)父级。也就是说,而不是:

0 <- 1 <- 2 <----------- 9 <--- master
           \            /
            3 <- 4 <- 5 <------ Feature/A
                       \
                        6 <- 7 <- 8   <-- HEAD=Feature/B

我们得到的是这样的:

0--1--2------------9   <-- master
       \___       /
        \  `---345   <-- Feature/Members
         \
          3--4--5   <-- Feature/A
                 \
                  6--7--8   <-- Feature/B

其中提交 345 是 运行 宁 git checkout -b Feature/Members <hash-of-2> && git merge --squash Feature/A 而不是 git checkout master && git merge Feature/A 的结果。然后将压缩在一起的 345 与常规合并合并到 master,并删除分支名称 Feature/Members(注意大写)。因此,该分支与 feature/members(注意小写)分支无关,并且提交 345 与提交 345.[= 冲突65=]

你现在的主要选择是合并(尽可能使用真正的合并!)和解决冲突,或者使用 git rebase --onto 将提交 6-7-8 复制到三个新提交.使用 rebase 的好处是工作会更容易。缺点是 6-7-8 的三个替换提交必须用作当前具有这三个提交的 每个克隆 中的替换。

(线下原答案)


假设您的绘图是准确的,提交 89 的合并基础是 5。为了验证这一点,运行:

git merge-base --all HEAD master

这应该只打印那个提交的哈希 ID。

将出现冲突 if/when 从 58 的差异中出现的变化与从 58 的差异中出现的变化重叠或邻接9。也就是说,已经获得合并基的哈希ID(单数),运行:

git diff --find-renames <hash-of-5> feature/B > /tmp/ours
git diff --find-renames <hash-of-5> master > /tmp/theirs

比较差异列表以查看可能发生冲突的位置。

由于 9 处的合并据说是由 git checkout master && git merge --no-ff feature/A 完成的,并且 之间没有提交 9 及其第一个父级 2,此处显示的从 59 的更改应该正是沿 3-4-5 所做的更改小路。这意味着在 /tmp/theirs 中从 59 的差异应该是 。空 diff 不会产生冲突(非空 空 diff),因此:

git checkout master && git merge feature/B

或:

git checkout feature/B && git merge master

应该没有冲突。因此我得出结论,这里至少有一个假设是错误的。最有可能出错的是假设您的简化提交图绘制是正确的。考虑编辑您的问题以包含 git log --graph --oneline master feature/A feature/B 的输出(如有必要,可能会删除一些提交消息的主题行)。然而,另一种可能性是简化图形绘制 正确的,但是 9 处的合并是一个邪恶的合并:参见 Evil merges in git? 在这种情况下 /tmp/theirs diff 将是非空的。

(我自己的猜测是提交 9 是一个 squash 合并 ,并且没有 link 回到提交 5,所以合并基础实际上是提交 2.)