2014-10-28 1104 views
10

我有两个分支AB。两者都包含一个子模块(在文件夹sub中),但是在不同的提交中(不会从一个快速前进到另一个)。如果子模块未初始化,如何解决git子模块冲突

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

那么,如何解决此子模块冲突(在初始化子模块后不中止合并并重试)?

回答

12

什么让你的情况有点恼人的是,git不会让你初始化一个未装入的子模块,所以只需将submodule设置为子模块所需的状态然后运行git add将不起作用。你可以做的是直接更新索引,而不需要通过工作树。

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

git reset master -- sub 
git reset [email protected]{upstream} -- sub 
git reset HEAD -- sub 
git reset MERGE_HEAD -- sub 

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

要使用这种方法,找出你要设置的子模块,然后运行哈希值,例如:

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

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

就你而言,你不能在子模块路径上同时拥有正确的合并结果的内容,并且根本没有内容。 必要唯一的事情是在HEAD的正确提交ID在该路径有一个回购。包含repo真的不在乎那个路径上的子模块repo的来源,唯一重要的是在HEAD中提交id。

+2

那么“这工作就像普通的合并”,但是'git checkout --ours'和'git add'不起作用。如何“在该路径上提供正确的内容”? - “唯一需要的是在HEAD中用正确的提交ID在该路径上进行回购” - 但是,如何初始化子模块无法实现? – MrTux 2014-10-29 13:37:10

+0

子模块只是一个回购。 “唯一需要的是在这条路上有一个**回购**。” 'git clone u:// r/l -b $ yourbranch path/to/repo; git add path/to/repo; git commit -m done'。 – jthill 2014-10-29 14:53:58

+0

此选项适用于我。我只是在子模块位置克隆了缺失回购的正确版本,然后合并就完成了。 – 2018-03-06 00:16:36