Git子模块合并冲突:如何可视化?

6

最近我发现了一件令我非常高兴的事情:

git submodule summary

这个命令可以显示当前子模块所检出的提交相对于仓库中引用的提交是超前还是落后。

但是,在处理子模块冲突合并时,同样的命令就无法提供有用的输出。此时我需要在主树中繁琐地执行一系列操作,包括使用gitk查看分支、进入子模块、获取并在其中使用gitk比较sha1值等等。

有没有更方便的方法来了解冲突的情况呢?

2个回答

2
你可以编写一个脚本。以下是这样一个脚本的核心部分:
 git --git-dir=submodulepath/.git diff \
    $(git ls-tree HEAD submodulepath | cut -c 15-54) \
    $(git ls-tree MERGE_HEAD submodulepath | cut -c 15-54)

你可以使用diff或其他命令来查看更改内容。如果是快进合并,你可以在不合并子模块的情况下快速解决冲突。此外,gitslave也可以帮助你解决这些问题。希望这能帮到你。

+1 对于提到 gitslave 的赞同!但是诚实的广告宣传,gitslave 在处理 git 子模块方面并没有帮助,除非它是 git 子模块的完全替代品。然而,替换 git 子模块对于您的心理健康非常有帮助。 - Seth Robertson
很棒的插件,Seth ;) 我希望能为git的子模块做出贡献。我不确定在git项目中所有可用的内容中,是否子树合并是答案。 - Adam Dymitruk
我真的不太理解那个命令行的意思。"$(git ls-tree ...)" 评估为类似于 "cfa69f5 . 8b7cc2b . 4871 . 6133e C 8e9bfd" 的东西(当然是完整的SHA1 ID)。这怎么可能是 "git diff" 的有效参数呢?无论如何,对我来说都不起作用,我得到的是:usage: git diff... - chrisxxx
请确保指定的子模块路径与 git submodule 输出或 .gitmodules 文件内容中列出的路径相同。如果您指定了包含目录,则会得到您正在获取的输出。 - Adam Dymitruk
我添加了另一个答案,它使用索引而不是ls-tree和cut。 - robinst

0

Adam的答案相同,但使用索引而不是切片:

sub="path/to/submodule"
git --git-dir="$sub/.git" diff \
    $(git rev-parse ":2:$sub") \
    $(git rev-parse ":3:$sub")

解释:

当存在冲突时,Git会将有关其的信息存储在索引中。它存储了几个不同的版本,称为阶段。第1阶段是“基础”版本(共同祖先),第2阶段是“我们”的版本,第3阶段是“他们”的版本。

在文件冲突的情况下,索引包含不同版本的blob对象ID。在子模块的情况下,它是子模块提交ID。在上面的命令中,:2:$sub指的是路径为$sub的子模块的第2阶段(ours)。

请注意,您可以使用git ls-files --stage查看具有阶段的索引条目列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接