我的用例是:我有一个包含子模块的仓库的两个分支。我想设置这两个分支的自动集成。但是,每当两个分支上都有子模块更新时,我的自动集成脚本就会失败,并且子模块会发生冲突。有没有办法让 git 在合并期间忽略子模块指针的变化?或者为merge=ours
给定的子模块提供类似的东西?
我在这里读过这个。
我在上面的页面中为这样的子模块文件夹尝试了合并策略(但它只适用于文件)
submodule-name merge=ours
我的用例是:我有一个包含子模块的仓库的两个分支。我想设置这两个分支的自动集成。但是,每当两个分支上都有子模块更新时,我的自动集成脚本就会失败,并且子模块会发生冲突。有没有办法让 git 在合并期间忽略子模块指针的变化?或者为merge=ours
给定的子模块提供类似的东西?
我在这里读过这个。
我在上面的页面中为这样的子模块文件夹尝试了合并策略(但它只适用于文件)
submodule-name merge=ours
老实说,我也很惊讶,但文档很快解释了发生了什么:
如果子模块的历史已经分道扬镳,并致力于在一个超级项目中分叉分支,[...] Git 不会为您尝试哪怕是微不足道的合并。
我猜“为什么合并策略不起作用? ”这个问题的答案是:因为不同子模块版本之间没有合并过程。如果您需要进行实际合并,则文档建议的方法仍然不是那么复杂,但在您的情况下它甚至“更容易”。
假设你在master
并且你想合并my_branch
它。有3种情况:
git merge my_branch
我已经链接的文档很好地解释了这一点,所以我没有理由重复它。我仍然建议您阅读它,因为您可能会遇到意想不到的情况。我在答案的最后告诉你。
git merge -Xours my_branch
我不知道这是否是解决此问题的正确方法,但是有一个非常简单的快捷方式可以清除子模块上的任何冲突。因为 git 不对子模块版本做任何合并操作,它只会告诉你不同的版本。因此,如果您查看索引,您仍然会发现来自 3-way 合并的 3 个版本
(的输出git ls-files -s
)
100644 acbc19aafbf0c14e67f9a437d465351a7e96388b 0 .gitmodules
100644 3da4fcc7b3a9bc886b50977dc35e10f48a42416b 0 your_files
160000 e826e1b762a17dbc7225b36db4a9f7f6c08774ad 1 submod
160000 fef2abfb901d20ba1f4d1023ba384bbc6afbc392 2 submod
160000 cd5caa8674fe078e0fb875861bb075ccb60cfee0 3 submod
第一个(e826e1b)是合并基础,但您对索引为 2 的那个感兴趣。不幸的是,我认为您不能在将其添加到索引时引用带有 common 的子模块修订,:2:./submod
因为add
它不是真正的路径。我告诉你的最简单的捷径就是这个:)
git add submod
然后你就可以了commit
。它会自动保留master
子模块版本,但这当然不是最好的方法,因为行为可能会在 git 的某些未来版本中发生变化。我将向您展示下一个场景的另一种方式。
git merge -Xtheirs my_branch
这里事情变得复杂了:我们不能使用上面的技巧(简单add
,现在默认为master
子模块修订版),因为现在我们需要索引为 3 的修订版,这:3:./submod
不适用于add
命令。
您还可以使用管道命令更新索引update-index
并传递原始缓存信息条目,例如:
git update-index --cacheinfo 160000,cd5caa8674fe078e0fb875861bb075ccb60cfee0,submod
mode160000
是用于子模块的模式(更具体地说是用于 git 链接),cd5caa86...
是我们要添加到索引中的对象,submod
也是路径。奇怪的是,在这里放置子模块名称是可行的。如果你需要编写脚本,你显然不能在那里放置一个硬编码对象,但你可以用它来检索它
git rev-parse :3:./submod
最后,这是运行以保持theirs
子模块版本的命令:
git update-index --cacheinfo 160000,$(git rev-parse :3:./submod),submod
相反,要保留ours
版本,请替换:3:
为:2:
.
这部分在参考资料中也得到了很好的解释,但你需要非常小心。总之,git 不会尝试合并您的子模块,除非:
ours
or theirs
)。在我看来,git 团队应该添加一个选项,让我们更多地控制我们想要如何处理这些情况。顺便说一句,您总是可以先允许提交,然后再提交--amend
,或者在提交之前使用git merge --no-commit
. 在这两种情况下,您都不能使用索引修订(如:2:./submod
),但在第一种情况下和HEAD^1
在第二种情况下使用。如果这是一个非常不可能的情况,请跳过它,否则我会提交并且如果它是可以接受的。HEAD^2
MERGE_HEAD
--amend
我希望有一种更简单的方法可以将具有不同子模块修订的分支合并,因此不要将此答案视为唯一的可能性。此外,在合并之后,您可能需要deinit
重新初始化(或重新sync
)您的子模块,但只要这是可编写脚本的,这不是一个真正的问题。如果我是你,我会创建一个包含所有这些操作的别名。
即使这是一个旧帖子,只是为像我这样的懒人发表评论:P
基本上,如果您的子模块历史记录与您要合并的分支不同,您就会遇到此问题。
试试这种方式,如果也可以帮助你。
由于子模块历史记录不匹配,请尝试通过拉/恢复/转移到其他分支来匹配它们并提交这些子模块引用,这对我有用。希望它也适合你。