Py学习  »  Git

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

mdailey77 • 5 年前 • 2196 次点击  

我有两个git分支,开发和重新设计我需要合并。我有一个称为library的子模块,它的更新被development跟踪。当我跑的时候 git merge 它说,尽管我没有触及library子模块,但这两个模块都修改了library。当我在VS代码中单击library以查看冲突的更改时,我看到:

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

我试过删除库文件夹并运行' git submodule update “在重新设计分支合并之前没有成功。我在重新设计中向.gitmodules文件添加了ignore=all,但没有成功。如何消除与此子模块的合并冲突?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/52269
 
2196 次点击  
文章 [ 2 ]  |  最新文章 5 年前
mdailey77
Reply   •   1 楼
mdailey77    5 年前

我解决了这个问题。我找到了类似StackOverflow问题的答案: https://stackoverflow.com/a/29971977/2026659 . 当我跑的时候 'git add' 把它交给图书馆,问题就解决了。我团队中的另一个开发人员更改了与库子模块关联的哈希。

torek
Reply   •   2 楼
torek    5 年前

问题是 library 已在两个分支中修改,与合并基提交相关。这里的技巧是理解子模块被“修改”的含义。

记住,任何子模块的本质都是您的超级项目 其他一些Git存储库。另一个Git存储库 作为 子模块不知道它被用作子模块。它只是一个普通的旧Git存储库。 1个 它有承诺。任何一个提交的真实名称都是它的哈希ID 使用 此子模块运行Git命令 在里面 告诉它的子模块 git checkout 一些特别的承诺 通过 哈希ID,导致子模块Git位于 分离头 模式。

同时,回到超级项目:这个存储库是一个普通的Git存储库。它有承诺。每个提交的真实名称都是一些散列ID,不过通常 git签出 某个分支名称。分支名称将解析为某个特定的hash ID,您的超级项目Git将通过分支名称检查提交,例如。, develop 现在做一些特别的事情,例如。, a123456... . 所以假设你是在承诺 a123456 .

某处 在里面 犯罪 a123456号 ,有一个类似文件的对象实际上不是文件,而是 gitlink公司 . 提交中的这个GITLink对象包含子模块中存在的一些提交的原始哈希ID。在您的例子中,这个gitlink是名称的条目 图书馆 它可以保存,例如。, 589a7ae5 . 那是 子模块的 承诺:如果您运行 git submodule update ,输入子模块Git并命令它 git checkout 589a7ae5 .

因此:超级项目中的每个提交都有一个名为 图书馆 这确实是一个gitlink,它存储了一些散列ID。现在您可以运行:

git checkout develop
git merge redesign

(或者反之亦然)。这个 git merge 命令已找到由分支名称指定的提交 发展 redesign ,以及第三次提交 合并基 其他两项犯罪。

这三件事都有(或缺:你有一件是 00000000 )名为 图书馆 . 这些gitlinks中的三个hash id都是不同的。Git正在尝试合并两个差异:

  • 有人说 从合并基中的gitlink X开始,用hash ID Y替换该gitlink .
  • 另一个人说 从合并基中的X开始,替换为Z .

这两个方向用Y代替,用Zconflict代替。Git不知道哪一个是正确的(如果事实上任何一个都是正确的)。

为了解决这个特殊的合并冲突,您的工作是选择 对的 子模块的哈希ID。一旦你知道正确的散列ID 怎样 你发现这取决于你 2个 您只需临时切换到子模块Git存储库并运行 git checkout hash ,然后返回超级项目并运行 git add library . 您的超级项目Git现在在gitlink中记录将进入合并提交的新散列ID,合并冲突得到解决。

当您解决了所有合并冲突(包括普通文件冲突)并准备提交合并时,请运行 git merge --continue git commit 完成合并。合并提交将具有 它的 的gitlink 图书馆 ,添加的哈希ID。

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


1个 这跳过了一些技术细节,通过这些细节可以发现这个子模块存储库位于某个超级项目中。重要的是,大多数Git都没有意识到这些细节:子模块 思考 它是独立的。此外,典型的子模块Git repo是其他Git repo的克隆,并且 其他 Git回购 完全不知道克隆,所以即使你使用的克隆子模块知道它是一个子模块, 它的 origin 仍然不知道。

2个 查找正确散列ID的典型示例方法开始于:

cd library

接着是各种各样的 git log 和/或 git show 和/或 git签出 命令,或者 gitk --all 或者您想用来查看Git存储库的任何东西。最后,你发现了一些看起来不错的散列ID并运行 git签出 在它上,以便更新此存储库中的工作树,然后 cd 退出子模块并构建和测试项目。这个过程自然会让子模块处于正确的提交状态,这样您就不必重新- git签出 正确的哈希ID。