是否有任何git merge-strategys来忽略提交或分支合并到目标分支中的子模块更新? [英] Are there any git merge-strategies for ignoring submodule updates on a commit or branch merge into target branch?

查看:102
本文介绍了是否有任何git merge-strategys来忽略提交或分支合并到目标分支中的子模块更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的用例是:我有一个包含子模块的仓库的两个分支.我想设置这两个分支的自动集成.但是,只要两个分支上都有子模块更新,我的自动集成脚本就会因子模块上的冲突而失败.有没有办法让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:

如果子模块的历史有所分歧,并致力于使一个超级项目中的分支分歧,则Git甚至不会为您进行琐碎的合并.

If the submodule histories have diverged and are committed to diverging branches in a superproject, [...] Git will not attempt even a trivial merge for you.

我猜答案是为什么合并策略不起作用?"?是:因为不同子模块版本之间没有合并过程.如果您需要进行实际的合并,则文档建议的方法仍然没有那么复杂,但是对于合并"而言,它甚至更容易".根据您的情况.

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的库感兴趣.不幸的是,我认为您不能使用通用

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 adding 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来忽略提交或分支合并到目标分支中的子模块更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆