问题描述
我的用例是:我有一个包含子模块的仓库的两个分支.我想设置这两个分支的自动集成.但是,只要两个分支上都有子模块更新,我的自动集成脚本就会因子模块上的冲突而失败.有没有办法让git在合并过程中忽略子模块指针中的更改?还是为给定的子模块提供类似 merge = ours
的内容?
My usecase is:I have a two branches of a repo containing submodules.I want to set up auto-integrate of these two branches. But whenever there are submodule updates on both branches, my auto integrate script fails with conflicts on submodules. Is there way to ask git to ignore the changes in submodule pointers during the merge?Or provide something like merge=ours
for the given submodules?
我已经在 此处阅读了此内容.
I've read this here.
我在上一页中针对这样的子模块文件夹尝试了合并策略(但仅适用于文件)
I tried the merge strategies in the above page for submodule folder like this (but it only works for files)
submodule-name merge=ours
推荐答案
老实说,我也感到惊讶,但是文档快速解释了正在发生的事情:
To be honest, I was surprised too, but the documentation quickly explains what is happening:
我猜答案是为什么合并策略不起作用?"?是:因为不同子模块版本之间没有合并过程.如果您需要进行实际的合并,则文档建议的方法仍然没有那么复杂,但是对于合并"而言,它甚至更容易".根据您的情况.
I guess the answer to the question "why don't merging strategies work?" is: because there is no merging process between different submodules versions. The approach suggested by the doc is still not that complex if you need to do an actual merge, but it is even "easier" in your case.
假设您在 master
上,并且要在其中合并 my_branch
.有3种情况:
Suppose you are on master
and you want to merge my_branch
in it. There are 3 scenarios:
我已经链接的文档对此进行了很好的解释,因此没有理由重复我的说明.我仍然建议您阅读它,因为您可能会遇到意想不到的情况.我在答案的结尾告诉了你.
This is very well explained by the documentation I already linked, so there is no reason why I should repeat it. I still suggest you to read it because you could end up in an unexpected situation. I am telling you about it at the end of the answer.
我不知道这是否是解决此问题的正确方法,但是有一个非常简单的快捷方式可以清除子模块上的所有冲突.因为git在子模块版本上不执行任何合并操作,所以它仅告诉您不同版本.因此,如果您查看索引,您仍然会发现3向合并产生的3个版本
I would not know if this is a correct way to solve this, but there is a very simple shortcut to clear any conflict on submodules. Because git does not do any merge operation on submodule versions, it only tells you about the diverging versions. So, if you look at the index, you still find the 3 versions coming from the 3-way merge
( git ls文件-s
的输出)
100644 acbc19aafbf0c14e67f9a437d465351a7e96388b 0 .gitmodules
100644 3da4fcc7b3a9bc886b50977dc35e10f48a42416b 0 your_files
160000 e826e1b762a17dbc7225b36db4a9f7f6c08774ad 1 submod
160000 fef2abfb901d20ba1f4d1023ba384bbc6afbc392 2 submod
160000 cd5caa8674fe078e0fb875861bb075ccb60cfee0 3 submod
第一个(e826e1b)是合并库,但是您对索引为2的库感兴趣.不幸的是,我认为您不能使用通用 :2:../submod
而 add
将其设为索引,因为它不是真实路径.我告诉你的简单捷径就是这个:)
The first one (e826e1b) is the merge base, but you are interested on the one with index 2. Unfortunately, I think you cannot refer to the submodule revision with the common :2:./submod
while add
ing it to the index because it is not a real path. The easy shortcut I told you about is this one :)
git add submod
然后您可以提交
.它会自动保留 master
子模块的版本,但这并不是最好的方法,因为在某些将来的git版本中,行为可能会改变.我将向您展示下一种情况的另一种方式.
And then you can commit
. It automatically keeps the master
submodule version, but it is not the best way of course, since the behaviour could change in some future versions of git. I will show you the other way for the next scenario.
事情变得复杂:我们不能使用上述技巧(简单的 add
现在默认为 master
子模块修订版),因为现在我们需要带索引的修订版3,即:3:./submod
与 add
命令不兼容.
Here things get complicated: we cannot use the above trick (simple add
that for now defaults to the master
submodule revision), because now we need the revision with index 3, which is :3:./submod
that does not work with the add
command.
您还可以使用管道命令 update-索引
并传递原始的缓存信息条目,例如:
You can also update the index with the plumbing command update-index
and pass a raw cache-info entry, like:
git update-index --cacheinfo 160000,cd5caa8674fe078e0fb875861bb075ccb60cfee0,submod
mode 160000
是用于子模块(更具体地说是git链接)的一种, cd5caa86 ...
是我们要添加到索引的对象,而 submod
是路径.奇怪的是,在这里放置子模块名称是可行的.如果您需要编写脚本,显然不能在其中放置硬编码对象,但是可以使用
mode 160000
is the one used for submodules (more specifically for git links), cd5caa86...
is the object we want to add to the index, and submod
is the path. Here, strangely, putting the submodule name works.If you need to script this, you cannot obviously put a hard-code object there, but you can retrieve it with
git rev-parse :3:./submod
最后,这是运行以保留子模块其
版本的命令:
In the end, this is the command to run to keep theirs
version of submodule:
git update-index --cacheinfo 160000,$(git rev-parse :3:./submod),submod
相反,要保留我们的
版本,请将:3:
替换为:2:
.
Instead, to keep ours
version, replace :3:
with :2:
.
此部分在参考中也作了很好的解释,但您需要非常小心.总之,git不会尝试合并您的子模块,除非:
Also this part is very well explained in the reference, but you need to be very careful. In summary, git does not try to merge your submodules, unless:
- 可以使用快速转发策略解决合并,在这种情况下,它使用最新的提交,或
- 用于冲突的子模块修订版的合并已经在子模块存储库中,因此git只会将该合并提交添加到索引中(而不是
ours
或theirs
)./li>
以我的拙见,git团队应该添加一个选项,使我们可以更好地控制如何处理这些情况.顺便说一句,您始终可以允许提交,然后-修改
,或者在使用 git merge --no-commit
提交之前对其进行修复.在这两种情况下,您都不能使用索引修订版(例如:2:./submod
),但是不能使用索引修订版中的 HEAD ^ 1
和 HEAD ^ 2
第一种情况为 MERGE_HEAD
.如果这是非常不可能的情况,请跳过它,否则我会提交并-amend
(如果可以接受的话).
In my humble opinion, git team should add an option to give us more control on how we want to handle these situations. By the way, you can always allow the commit and then --amend
it, or fix it before committing using git merge --no-commit
. In both cases you cannot use the index revisions (like :2:./submod
), but HEAD^1
and HEAD^2
in the first case, and the MERGE_HEAD
in the second case. If this is a very unlikely scenario, just skip it, otherwise I would commit and --amend
if it is acceptable.
我希望有一种更简便的方法来合并具有不同子模块修订版的分支,因此不要将此答案视为唯一且唯一的可能性.而且,合并之后,您可能需要 deinit
并重新初始化(或重新 sync
)您的子模块,但是就此而言,这不是一个真正的问题.如果您是我,我将创建一个包含所有这些操作的别名.
I hope there is an easier way to merge branches with different submodule revisions, so do not consider this answer as the one and only possibility. Moreover, after the merge you may need to deinit
and reinitialize (or resync
) your submodule, but as far as this is scriptable, this is not a real issue. If I were you, I would create an alias containing all these operations.
这篇关于是否有任何git merge-strategys来忽略提交或分支合并到目标分支中的子模块更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!