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

时间:2019-08-23 20:23:20

标签: git git-merge git-submodules git-merge-conflict

我有两个git分支,分别进行开发和重新设计。我有一个称为库的子模块,开发人员正在跟踪该库的更新。当我运行'git merge'时,即使我没有碰到库子模块,也都说库已被两者修改。当我在VS Code中单击库以查看冲突的更改时,我看到以下内容:

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

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

3 个答案:

答案 0 :(得分:1)

问题在于,library 在两个分支中都已针对基于合并的提交进行了修改。这里的技巧是了解“修改”子模块的含义。

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

同时,回到超级项目:此存储库是一个普通的Git存储库。它有提交。每个提交的真实名称是一些哈希ID,尽管通常您会git checkout一些分支名称。分支名称将解析为某些特定的哈希ID,并且您的超级项目Git将通过该分支名称(例如develop)检出该提交,现在处于某个特定的提交(例如a123456...)。因此,假设您正在提交a123456

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

因此:超级项目中的每个提交都有一个名为library的“文件”,它实际上是一个gitlink,并存储一些哈希ID。您现在已经运行:

git checkout develop
git merge redesign

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

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

  • 一个差异说,从合并基础中的gitlink X开始,用哈希ID Y替换该gitlink。
  • 另一个差异表示从合并基础中的X开始,将其替换为Z

这两个指令(用Y替换,并用Z替换)相互冲突。 Git不知道哪一个是正确的(如果实际上任何一个是正确的)。

为了解决此特定的合并冲突,您的工作是为子模块选择正确的哈希ID。一旦知道正确的哈希ID(如何),就可以由您决定 2 ,您只需暂时更改为子模块Git存储库并运行git checkout hash,然后返回到超级项目并运行git add library。您的超级项目Git现在将新的哈希ID记录在gitlink中,它将进入合并提交,并解决了合并冲突。

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

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


1 跳过了一些技术细节,通过这些细节可能发现此子模块存储库位于某些超级项目中。重要的是,大多数Git都没有意识到这些细节:子模块认为像过去一样是独立的。此外,典型的子模块Git repo是其他Git repo的克隆,而 other Git repo 完全不知道克隆,因此即使克隆—子模块您正在使用-我们知道它是一个子模块, origin仍然不知道。

2 用于查找正确的哈希ID的典型示例方法始于:

cd library

之后是各种git log和/或git show和/或git checkout命令,或者gitk --all或您喜欢用来查看Git存储库的任何命令。最终,您发现一些看起来不错的哈希ID并在其上运行git checkout,以便更新此存储库中的工作树,然后cd退出子模块并构建并测试项目。此过程自然会将子模块留在正确的提交上,因此您不必重新git checkout正确的哈希ID。

答案 1 :(得分:0)

我解决了这个问题。我从此答复中找到了类似的StackOverflow问题的答案:https://stackoverflow.com/a/29971977/2026659。当我运行Sheet2到库并提交时,问题就消失了。我团队中的另一位开发人员更改了与库子模块关联的哈希。

答案 2 :(得分:0)

在子模块中使用vscode:UI可以很好地处理大多数事情。

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

所需要做的就是在cli中运行它:

git add submodule-name