Git中子模块冲突的原因是什么,如何解决?

13

我们正在使用子模块,并且对git不太熟悉。

我们经常看到子模块本身存在合并冲突,没有文件冲突,只有子模块。 git submodule summary 的输出中列出了多个版本。 我们通过在超级项目中运行git add <submodule>来解决它们。
但是今天,一位开发人员在使用这种方式解决冲突时,丢失了子模块的提交。
运行 git add 是否选择远程版本?子模块的内容不应该合并吗?如果她在子模块中进行了更改并提交了它们(我看到了),那么为什么她运行拉取并解决冲突后那次提交会消失呢?

3个回答

12

您本地的子模块和远程的子模块已经分叉。

git checkout --theirs submodulename

或者适用于您的版本:

git checkout --ours submodulename

然后使用git add和commit提交更改。

注意:如果你使用tab键自动补全,你的shell可能会在submodulename后添加一个尾随斜杠,因为它也是一个子目录。如果出现这种情况,你需要删除它,否则会出现以下错误:

error: pathspec 'submodulename/' did not match any file(s) known to git.

4
这对我不起作用:上游更改了模块,在合并他们的更改时,我尝试了'git checkout --theirs ios_src',但在'git diff origin/dev_ios .'中,我仍然看到我的本地oid标记为“-dirty”,而新的oid没有标记为脏。我期望看到我的本地行成为带有“-dirty”标记的新oid。提交后也仍然是我的oid。进入模块并显式检出根目录,然后再添加它可以解决问题,但这很繁琐。 - android.weasel

11

文件冲突和子模块冲突都会在你当前的分支和你想要合并到的分支发生了分歧时出现

这仅意味着存在一种不确定的情况--在任何给定情况下,您都可以合理地希望其中之一获胜。因此,虽然它可能看起来很“烦人”,但它们只是强调您丰富的选项,以指定您想要的内容(而且您必须指定您想要的内容)。 (每天所有程序员所做的就是详细说明。)

看起来像是git-add-the-submodule-on-the-superproject应该能够工作。 然而,您也有立即在超级项目上进行git-checkout的选项。 此链接中提到了这一点(解决子模块冲突),讨论了文件冲突和子模块冲突之间的区别以及如何解决它们:

http://pacific.mpi-cbg.de/wiki/index.php/Git_Conflicts


7
我认为链接目前无法使用。WebArchive 来拯救:http://web.archive.org/web/20100925080451/http://pacific.mpi-cbg.de/wiki/index.php/Git_Conflicts - Ricardo Sanchez-Saez
git checkout --theirs <submodule> 或者对于您的版本: git checkout --ours <submodule> - Andrew Wagner
1
对您初始陈述的澄清:潜在的冲突文件/子模块必须在两个分叉路径中都发生更改。仅仅是一个分支分叉并不意味着你会遇到冲突。 - void.pointer

0

至少 Git 2.38(2022 年第三季度)在合并子模块时提供了更详细的帮助信息,特别是在合并冲突的情况下。

查看提交 565577e, 提交 34ce504, 提交 a5834b7 (2022年8月18日) 由Elijah Newren (newren)提交。
查看提交 4057523 (2022年8月4日) 由Calvin Wan (CalvinWan0101)提交。
(由Junio C Hamano -- gitster --合并于提交 df3c129, 2022年8月25日)

子模块合并:更新冲突错误消息

签名作者:Calvin Wan

当尝试合并具有冲突子模块指针的超级项目时,如果无法快进或轻松解决,则合并失败,Git会打印一个准确描述失败的错误消息,但不提供用户解决错误的步骤。Git处于冲突状态,需要用户执行以下操作: 1. 合并子模块或将子模块更新到反映合并的现有提交 2. 将子模块更改添加到超级项目中 3. 完成合并超级项目
对于新的子模块用户来说,这些步骤并不明显,他们很难根据错误消息找出解决方法,git submodule status(man)git status(man)也没有提供任何有用的指针。
更新错误消息以提供解决子模块合并冲突的步骤。虽然消息很长,但它还具有需要合并的子模块提交的ID,这对用户可能是有用的信息。
此外,已更新了5个导致早期返回的合并失败,以反映合并的状态。 1. 空合并基础(null o):添加了CONFLICT_SUBMODULE_NULL_MERGE_BASE作为新的冲突类型,并将打印更新的错误消息。 2. 空合并侧a(null a):BUG()。请参见discussion 3. 空合并侧b(null b):BUG()。请参见for discussion 4. 子模块未签出:添加了NEEDSWORK位 5. 子模块提交不存在:添加了NEEDSWORK位。带有NEEDSWORK位的错误需要更详细地解释如何解决。请参见here for more context

现在您已经掌握了解决子模块合并冲突的建议。

第一个参数是子模块名称,第二个参数是需要合并的缩写ID。
例如:

go to submodule (mysubmodule), and either merge commit abc1234
or update to an existing commit which has merged those changes

另外,新消息:

Recursive merging with submodules currently only supports trivial cases.

Please manually handle the merging of each conflicted submodule.
This can be accomplished with the following steps:

sub1:
- come back to superproject and run:"
  git add sub1
to record the above merge or update"
- resolve any other conflicts in the superproject
- commit the resulting index in the superproject

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接