merge=ours
的东西?我已经在这里阅读了这个文档。 我尝试按照上面页面上的合并策略来处理子模块文件夹(但它只适用于文件)。
submodule-name merge=ours
merge=ours
的东西?submodule-name merge=ours
我想回答“为什么合并策略不起作用?”的问题是:因为不同子模块版本之间不存在合并过程。 如果需要进行实际合并,则文档建议的方法仍然不那么复杂,但在您的情况下,还更加“容易”。如果子模块的历史记录已经分叉,并且在超级项目中提交到不同的分支中,则...Git 将不会为您尝试甚至微不足道的合并。
master
分支上,并想在其中合并 my_branch
。有三种情况:
git merge my_branch
git merge -Xours my_branch
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的那个感兴趣。不幸的是,我认为您无法在将其添加到索引时使用通用的子模块修订版本 :2:./submod
,因为它不是实际路径。我告诉过您的简便方法是这样的:
git add submod
然后您可以提交commit
。它会自动保留master
子模块版本,但这当然不是最好的方法,因为行为可能会在某些未来版本的Git中发生改变。我将向您展示下一个场景的另一种方式。
git merge -Xtheirs my_branch
在这里事情变得复杂:我们无法使用上述技巧(简单的add
,暂时默认为master
子模块修订版本),因为现在我们需要索引3的修订版本,即:3:./submod
,该修订版本不能与add
命令一起使用。
您还可以使用plumbing命令update-index
更新索引,并传递原始缓存信息条目,例如:
git update-index --cacheinfo 160000,cd5caa8674fe078e0fb875861bb075ccb60cfee0,submod
160000
模式用于子模块(更具体地说是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
或theirs
)。在我看来,git团队应该添加一个选项,以便我们更多地控制如何处理这些情况。顺便说一句,您始终可以允许提交,然后使用--amend
进行修改,或者在提交之前使用git merge --no-commit
进行修复。在这两种情况下,您都不能使用索引修订(例如:2:./submod
),而是在第一种情况下使用HEAD^1
和HEAD^2
,在第二种情况下使用MERGE_HEAD
。如果这是一个非常不可能的情况,那就跳过它,否则我会提交并使用--amend
。
我希望有一种更简单的方法来合并具有不同子模块修订的分支,因此不要将此答案视为唯一的可能性。此外,在合并之后,您可能需要deinit
并重新初始化(或重新同步)您的子模块,但只要这是可脚本化的,这就不是真正的问题。如果我是您,我会创建一个包含所有这些操作的别名。
my_branch
重置为master
的reset --hard
操作,这实际上就是我的脚本所做的事情,直到有人运行它却没有强制推送权限,因此不允许更改历史记录;) 上述结构复制了reset --hard
到master
的效果,并用一个新提交代替旧提交,因此可以使用更少的权限来完成。 - SvenS-s ours
)并不意味着真正的合并,因为你只是重用 HEAD
树来创建新的提交树,最终也会丢弃 my_branch
中任何没有产生冲突的更改。如果这正是你所需要的,那么这是一个非常聪明的解决方法 :) - Marco Luzzarareset --hard
,因为它会丢弃 my_branch 上的所有提交。解决方案非常特定于我的用例,因为 my_branch 只包含由相同脚本进行的更改,该脚本现在正在尝试根据最新的 master 进行类似的更改。这也是为什么我的解决方法没有得到奖励的原因 ;) - SvenS虽然这是一篇旧帖子,但我只是为像我这样的懒人留言 :P
基本上,如果您的子模块历史记录与您想要合并的分支不同,则会出现此问题。
尝试以下方法,它可能也能帮助您:
由于子模块历史记录不匹配,请尝试通过拉取/还原/切换到其他分支来匹配它们,并提交这些子模块引用,这对我有用。希望对您也有用。