git - 无法解决与 git 子模块文件夹的合并冲突
问题描述
我有两个 git 分支,需要合并开发和重新设计。我有一个名为 library 的子模块,develop 正在跟踪它的更新。当我运行 ' git merge
' 时,它说库已被两者修改,即使我没有触及库子模块。当我单击 VS Code 中的库以查看冲突更改时,我看到:
diff --cc library
index 749618f9,589a7ae5..00000000
--- a/library
+++ b/library
git submodule update
在合并之前,我尝试在重新设计分支中删除库文件夹并运行“ ”,但没有成功。我在重新设计时将 ignore = all 添加到 .gitmodules 文件中,但没有用。如何摆脱与此子模块的合并冲突?
解决方案
问题在于,关于合并基础提交,这两个分支library
都已被修改。这里的诀窍是理解“修改”子模块意味着什么。
请记住,任何子模块的本质是您的超级项目正在引用其他 Git 存储库。另一个 Git 存储库——被用作子模块的那个——不知道它被用作子模块。它只是一个普通的旧 Git 存储库。1 它有提交。任何一次提交的真实名称都是其哈希 ID。使用这个子模块的超级项目在子模块中运行 Git 命令,通过哈希 ID告诉它git checkout
某个特定的提交,这导致子模块 Git 处于分离的 HEAD模式。
同时,回到超级项目:这个仓库是一个普通的 Git 仓库。它有提交。每个提交的真实名称是一些哈希 ID,但通常您会使用git checkout
一些分支名称。分支名称将解析为某个特定的哈希 ID,并且您的超级项目 Git 将通过该分支名称检查该提交——例如,develop
——并且现在处于某个特定的提交上,例如,a123456...
. 所以假设你在 commit a123456
。
在commit的某个地方a123456
,有一个类似文件的对象,它实际上不是一个文件,而是一个gitlink。提交中的这个 gitlink 对象包含子模块中存在的某些提交的原始哈希 ID。在您的情况下,此 gitlink 是名称的条目,library
它包含,例如589a7ae5
. 那是子模块的提交:如果你运行,你的超级项目 Git 将git submodule update
输入子模块 Git 并命令它到git checkout 589a7ae5
.
所以:超级项目中的每个提交都有一个名为“文件” library
,它实际上是一个 gitlink,并且存储了一些哈希 ID。您现在已经运行:
git checkout develop
git merge redesign
(或者反之亦然)。该git merge
命令已找到由分支名称develop
和指定的提交,以及作为其他两个提交的合并基础redesign
的第三个提交。
所有这三个提交都有(或缺少:你的一个是00000000
)一个名为 .gitlink 的 gitlink 条目library
。这些 gitlink 中的三个哈希 ID 都是不同的。Git 现在正在尝试合并两个差异:
- 一个差异说从合并库中的 gitlink X 开始,用哈希 ID Y 替换那个 gitlink。
- 另一个差异表示从合并基础中的 X 开始,将其替换为 Z。
这两个指令——用 Y 代替,用 Z 代替——相互冲突。Git 不知道哪一个是正确的(如果事实上任何一个都是正确的)。
为了解决这个特定的合并冲突,您的工作是为子模块选择正确的哈希 ID。一旦你知道了正确的哈希 ID——<em>如何找到这取决于你2——你只需暂时更改到子模块 Git 存储库并运行,然后返回超级项目并运行。您的超级项目 Git 现在在 gitlink 中记录了新的哈希 ID,它将进入合并提交,并且合并冲突已解决。git checkout hash
git add library
当您解决了所有合并冲突(包括普通文件冲突(如果有))并准备好提交合并、运行git merge --continue
或git commit
完成合并时。合并提交将具有您添加的哈希 ID作为其gitlink for 。library
(如果正确的做法是完全停止使用子模块,您可以git rm library
先检查正确的子模块哈希,然后再git add
输入名称。)
1这会跳过一些技术细节,通过这些细节可以发现这个子模块存储库存在于某个超级项目中。重要的是,大多数 Git 完全没有意识到这些细节:子模块认为它是独立的,就像它本来的样子。此外,一个典型的子模块 Git 存储库是其他 Git 存储库的克隆,而其他Git 存储库完全不知道克隆,所以即使克隆(您正在使用的子模块)知道它是一个子模块,它的 origin
仍然不会意识到。
2查找正确哈希 ID 的典型示例方法如下:
cd library
后面是各种git log
和/或git show
和/或git checkout
命令,或者可能gitk --all
是你喜欢用来查看 Git 存储库的任何东西。最终,您会发现一些看起来不错的哈希 ID 并git checkout
在其上运行,以便更新此存储库中的工作树,然后cd
退出子模块并构建和测试项目。这个过程自然而然地将子模块留在正确的提交上,这样您就不必重新git checkout
设置正确的哈希 ID。
推荐阅读
- javascript - 具有平滑高度的Vue JS褪色动画
- javascript - 我无法在 req mongoDB 的 json 中引入新元素 con JS (nodeJS)
- graphql - 有没有办法从 Apollo 请求中获取哈希值
- javascript - 如何让 rollup.js 在安装时构建一个反应库(yarn add ssh://git@my-repo-url)
- android - RTL模式下RecyclerView中MaterialCardView被截断
- c# - 如何在c#中从一个值读取文件中的文本到另一个值
- python - 如何在pygame中更改文本?
- javascript - if 语句中未清除的清除间隔 [javascript]
- javascript - 通过更新变量来更新 Json 值
- php - 在 Laravel foreach 循环中设置变量