无法解决与 git 子模块文件夹的合并冲突

Can't resolve merge conflict with git submodule folder

我有两个 git 分支,开发和重新设计我需要合并。我有一个名为 library 的子模块,develop 正在跟踪它的更新。当我 运行 'git merge' 它说库已经被两者修改,即使我没有触及库子模块。当我在 VS Code 中单击库以查看冲突的更改时,我看到了这个:

diff --cc library
index 749618f9,589a7ae5..00000000
--- a/library
+++ b/library

我尝试在重新设计分支中删除库文件夹和 运行ning 'git submodule update',然后合并没有成功。我在重新设计时将 ignore = all 添加到 .gitmodules 文件,但没有用。如何摆脱与此子模块的合并冲突?

问题是 library 已在两个分支中修改 ,关于合并基础提交。这里的技巧是理解子模块 "modified".

的含义

请记住,任何子模块的本质是您的超级项目 引用 其他一些 Git 存储库。另一个 Git 存储库 - 被用作 作为 子模块的存储库 - 不知道它被用作子模块。它只是一个普通的旧 Git 存储库。1 它有提交。任何一次提交的真实名称是它的哈希 ID。 使用这个子模块运行s Git的超级项目命令子模块告诉它git checkout一些特定的提交 by 哈希 ID,这导致子模块 Git 处于 分离 HEAD 模式。

同时,回到超级项目:这个存储库是一个普通的 Git 存储库。它有承诺。每个提交的真实名称是一些哈希 ID,但通常你会 git checkout 一些分支名称。分支名称将解析为某个特定的哈希 ID,并且您的超级项目 Git 将通过该分支名称检查该提交——例如,develop——现在在某个特定的提交上,例如,a123456....假设您正在提交 a123456.

提交a123456的某处,有一个类似文件的对象,它实际上不是一个文件,而是一个gitlink。提交中的这个 gitlink 对象包含子模块中存在的某个提交的原始哈希 ID。在您的情况下,此 gitlink 是名称 library 的条目,它包含 589a7ae5。那是 子模块的 提交:如果你 运行 git submodule update,你的超级项目 Git 将进入子模块 Git 并命令它 git checkout 589a7ae5.

因此:超级项目中的每个提交都有一个名为 library 的 "file",它实际上是一个 gitlink,并且存储了一些哈希 ID。您现在 运行:

git checkout develop
git merge redesign

(或者反之亦然)。 git merge 命令找到了由分支名称 developredesign 指定的提交,以及第三个提交,即这些提交的 合并基础 其他两个提交。

所有这三个提交都有(或缺少:你的一个是 00000000)一个名为 library 的 gitlink 条目。这gitlink中的三个hash ID都是不同的。 Git 现在正在尝试合并两个差异:

  • 一个差异说从合并基中的gitlink X开始,将gitlink替换为哈希ID Y.
  • 另一个 diff 说 从合并基中的 X 开始,将其替换为 Z

replace with Y和replace with Z这两个指令相互冲突。 Git 不知道哪一个是正确的(如果事实上其中一个是正确的)。

为了解决这个特定的合并冲突,您的工作是为子模块选择正确 哈希 ID。一旦你知道了正确的散列 ID——如何 你会发现这取决于你2——你只需暂时更改到子模块 Git存储库和 运行 git checkout <em>hash</em>,然后 return 到超级项目和 运行 git add library。您的超级项目 Git 现在将新的哈希 ID 记录在 gitlink 中,它将进入合并提交,并且合并冲突已解决。

当您解决了所有合并冲突(包括普通文件冲突,如果有)并准备提交合并时,运行 git merge --continuegit commit 完成合并。合并提交将具有您添加的哈希 ID,如 its gitlink for library

(如果正确的做法是完全停止使用子模块,您可以 git rm library 而不是首先检查正确的子模块哈希,然后 git add 输入名称。)


1这跳过了一些技术细节,通过这些细节可以发现这个子模块存储库位于某个超级项目中。重要的是大多数 Git 幸福地没有意识到这些细节:子模块 认为 它是独立的,可以说是。此外,典型的子模块 Git 回购是其他一些 Git 回购的克隆,而 other Git 回购 完全不知道克隆,所以即使克隆——你正在使用的子模块——知道它是一个子模块,its origin 仍然不会请注意。

2查找正确散列 ID 的典型示例方法开头为:

cd library

后跟各种 git log and/or git show and/or git checkout 命令,或者 gitk --all 或者任何你喜欢用来查看的东西Git 存储库。最终,你发现一些看起来不错的散列 ID 和 运行 git checkout 在上面,以便更新这个存储库中的工作树,然后 cd 退出子模块并构建和测试项目。这个过程自然地使子模块处于正确的提交状态,因此您不必重新git checkout 正确的哈希 ID。

我解决了这个问题。我从这个对类似 Whosebug 问题的回复中找到了答案:。当我 运行 'git add' 到库并提交它时,问题就消失了。我团队中的另一位开发人员更改了与库子模块关联的哈希值。

将 vscode 与子模块一起使用:UI 可以很好地处理大多数事情。

但是,由于子模块合并冲突,我找不到解决方法。

所需要的只是在 cli 中 运行 这个:

git add submodule-name