如何识别子模块引用中的合并冲突?

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

我正在尝试构建一个脚本来在某些条件下自动处理合并冲突。 我发现在不进行合并的情况下识别子模块引用中的合并冲突具有挑战性。

我的意思是,我想找到一种简单的方法来在进行合并之前识别两个分支之间子模块引用中的合并冲突(即使未提交)。

当我说子模块引用时,我并不是指子模块内的冲突。相反,我的意思可以用一个例子来解释,如果分支 A 中的子模块(在我的父存储库中)指向引用 X,而分支 B 中的相同子模块(在我的父存储库中)指向引用 Y。这将导致如果两个分支中的子模块引用均已更新,则发生冲突,并且在 SourceTree 中如下所示:

如您所见,一个子模块引用 PNG_ND_Drivers 没有冲突,而另一个子模块引用 EmbeddedSW_UnitTests 确实存在冲突。这些变化似乎具有相同的性质。无法从文件中的更改来识别是否存在冲突。那么在合并之前如何识别它呢?

注意:我可以使用 --no-commit 标志进行合并,然后使用 git status --short 查看文件的状态并在下面找到

未合并的路径:
两者均已修改:EmbeddedSW-UnitTests

而其他子模块出现在:

未暂存提交的更改:
修改:PNG_ND_Drivers(新提交)

所以我可以通过这种方式识别冲突。但我需要进行合并,然后中止并丢弃它。看起来太麻烦了,所以想问问大家有没有更有效的方法。

git git-submodules
1个回答
0
投票

首先,我们需要了解Git Merge是如何工作的。当我们合并两个分支

A
B
时,Git将为每个文件执行三向合并。基本上,它的工作原理是这样的:

  1. 如果文件在两个分支上具有相同的内容,它将在合并提交中使用
  2. 如果分支
    A
    上的文件内容与
    A
    B
    之间的共同祖先上的内容相同,则
    B
    中的内容将用于合并提交
  3. 如果分支
    B
    上的文件内容与
    A
    B
    之间的共同祖先上的内容相同,则
    A
    中的内容将用于合并提交
  4. 如果
    A
    B
    以及
    A
    B
    之间的共同祖先上的文件内容不同,那么我们就会发生冲突。如果它是纯文本文件,那么如果更改不冲突,Git 将尝试在内部合并。

这也是 Git 在合并子模块时所做的事情,但它不是比较文件的内容,而是比较子模块在每个分支上指向的提交和共同祖先。所以,你可以手动检查一下:

  1. git rev-parse A:path_to_submodule
    git rev-parse B:path_to_submodule
    将返回子模块在
    A
    B
    上指向的提交的哈希值(示例中
    X
    Y
    的哈希值)。如果它们相同,那么就不会有冲突
  2. git merge-base A B
    将为您提供
    A
    B
  3. 之间共同祖先的哈希值
  4. git rev-parse <hash from step 2>:path_to_submodule
    将返回子模块在共同祖先上指向的提交的哈希值。将其与步骤 1 中的两个哈希值进行比较。如果两者都不同,则存在冲突

这可能有效:

x=$(git rev-parse A:path_to_submodule)
y=$(git rev-parse B:path_to_submodule)
common=$(git merge-base A B)
z=$(git rev-parse $common:path_to_submodule)
[ "$x" != "$y" ] && [ "$z" != "$x" ] && [ "$z" != "$y" ]
conflict=$?

如果想了解更多相关内容,我写了这篇文章来解释 Git 如何合并子模块:https://lucasoshiro.github.io/posts-en/2022-03-12-merge-submodule/

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