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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26617838/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 10:29:54  来源:igfitidea点击:

How to resolve git submodule conflict if submodule is not initialized

gitgit-submodules

提问by MrTux

I have two branches Aand B. Both contain a submodule (in the folder sub), however at different commits (which do not fast-forward from one to another).

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

A  B
| /
BASE

I've checked out A, but the submodule isn't initialized yet. Now I merge Band I get a conflict on the submodule.

我已签出A,但子模块尚未初始化。现在我合并B并在子模块上发生冲突。

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

        both modified:   sub

Issuing git checkout --ours subdoes nothing (if the submodule is initialized it works, also git checkout-index -f --stage=2 -- subdoes not work). git add subcauses the error error: pathspec 'sub' did not match any file(s) known to git..

发出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 -- subdoes nothing. Also git submodule update --init --force -- subdoes not work: Skipping unmerged submodule sub.

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

So, how can I resolve this submodule conflict (without aborting the merge and retry after initializing the submodule)?

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

回答by user3188445

What makes your situation kind of annoying is that git won't let you initialize an unmerged submodule, so the ordinary advice of just setting the submodule to the state you want within the submodule then running git addwon't work. What you can do is to update the index directly, without going through the working tree.

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

One way to update the index is with git reset. If you know a commit in which the submodule is in a state you want, you can use that. For example, any of the following might be what you want:

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

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

The other option is to update the index directly using the plumbing command git update-index. To do that, you need to know that an object of type gitlink (i.e., directory entry in a parent repository that points to a submodule) is 0160000. There's no way to figure that out from first principles, but you can figure it out from git ls-files -sor the following reference (see "1110 (gitlink)" under 4-bit object type): https://github.com/gitster/git/blob/master/Documentation/technical/index-format.txt

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

To use that approach, figure out the hash you want to set the submodule to, then run, e.g.:

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

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

回答by jthill

This works just like an ordinary merge: you have to supply the correct content at that path so git can commit it. Submodule content is stored as its current commit id, so you have to add the submodule's path to project (just like you add any file's path) when it has the right content, which here means its HEADreferences the right commit. Usually you get that with an ordinary checkout.

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

In your case, you can't have both the correct merge result's content at the submodule path and no content at all. The only thing necessaryis to have a repo at that path with the right commit id in HEAD. The containing repo really couldn't care less where the submodule repo at that path came from, the only thing that matters at this point is that commit id in HEAD.

在您的情况下,您不能在子模块路径中同时拥有正确的合并结果内容,也不能完全没有内容。唯一需要的是在该路径上有一个 repo 并在HEAD. 包含的 repo 真的不在乎那个路径上的子模块 repo 来自哪里,此时唯一重要的是提交 id in HEAD.