如果未初始化子模块,如何解决git子模块冲突

时间:2014-10-28 20:25:11

标签: git git-submodules

我有两个分支AB。两者都包含一个子模块(在文件夹sub中),但是在不同的提交中(不会从一个快进到另一个)。

A  B
| /
BASE

我已检出A,但子模块尚未初始化。现在我合并了B,我在子模块上遇到了冲突。

$ git status
Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:   sub

发布git checkout --ours sub什么都不做(如果子模块初始化它有效,那么git checkout-index -f --stage=2 -- sub也不起作用)。 git add sub导致错误error: pathspec 'sub' did not match any file(s) known to git.

$ git diff sub
diff --cc sub
index 533da4e,ab2af77..0000000
--- a/sub
+++ b/sub
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit 533da4ea00703f4ad6d5518e1ce81d20261c40c0
 -Subproject commit ab2af775ec467ebb328a7374653f247920f258f3
++Subproject commit 0000000000000000000000000000000000000000

git submodule init -- sub什么也没做。另外git submodule update --init --force -- sub不起作用:Skipping unmerged submodule sub

那么,如何解决这个子模块冲突(在不初始化子模块的情况下不中止合并并重试)?

2 个答案:

答案 0 :(得分:19)

是什么让你的情况有点烦人的是git不会让你初始化一个未合并的子模块,所以普通的建议只是将子模块设置为子模块中所需的状态然后运行git add不会工作。你可以做的是直接更新索引,而无需通过工作树。

更新索引的一种方法是使用git reset。如果您知道子模块处于所需状态的提交,则可以使用该提交。例如,以下任何一个可能是您想要的:

git reset master -- sub
git reset master@{upstream} -- sub
git reset HEAD -- sub
git reset MERGE_HEAD -- sub

另一个选项是使用管道命令git update-index直接更新索引。要做到这一点,你需要知道gitlink类型的对象(即父存储库中指向子模块的目录条目)是0160000.没有办法从第一原则中找出它,但是你可以从中找出它git ls-files -s或以下引用(请参阅4位对象类型下的“1110(gitlink)”):https://github.com/gitster/git/blob/master/Documentation/technical/index-format.txt

要使用该方法,请找出要将子模块设置为的散列,然后运行,例如:

git update-index --cacheinfo 0160000,533da4ea00703f4ad6d5518e1ce81d20261c40c0,sub

答案 1 :(得分:1)

这就像普通合并一样:你必须在该路径上提供正确的内容,以便git可以提交它。子模块内容存储为其当前提交ID,因此当它具有正确的内容时,您必须将子模块的路径添加到项目中(就像添加任何文件的路径一样),这意味着它的HEAD引用了正确的提交。通常你会通过普通的结账来获得。

在您的情况下,您不能在子模块路径中同时拥有正确的合并结果内容,也不能拥有任何内容。 必要唯一的事情就是在HEAD中使用正确的提交ID在该路径上拥有一个repo。包含repo真的不在乎那条路径上的子模块repo来自何处,此时唯一重要的是HEAD中的commit id。