如何管理与 git 子模块的冲突?

我有一个 git 超级项目,它引用了几个子模块,我正试图锁定一个工作流程,让其他项目成员在其中工作。

对于这个问题,假设我的超级项目叫做 supery,子模块叫做 subby。(然后是对我要做的事情的简化... ... 我实际上并没有使用分支来实现版本,但是我认为将它作为一个问题进行布局是最容易的。)

我的 supery主分支将 git 项目 subby的标记 v1.0作为子模块引用。supery的分支称为 one.one,并将子模块的引用更改为指向 subby的标记 v1.1

我可以毫无障碍地在每个分支中工作,但是如果我尝试用 master分支的更改来更新 one.one分支,我会收到一些冲突,而且我不知道如何解决它们。

基本上,在 subby分支中运行 git pull . master之后,它看起来像是创建了额外的子模块。

在拉取/合并之前,我从 one.one分支得到了所需的 git submodule响应:

$ git checkout master
$ git submodule
qw3rty...321e subby (v1.0)
$ git checkout one.one
$ git submodule
asdfgh...456d subby (v1.1)

但是在提取之后,当我运行 git submodule时,它会添加额外的子模块:

$ git pull . master
Auto-merged schema
CONFLICT (submodule): Merge conflict in subby - needs qu3rty...321e
Automatic merge failed; fix conflicts and then commit the results.


$ git submodule
qw3rty...321e subby (v1.0)
asdfgh...456d subby (v1.1)
zxcvbn...7890 subby (v1.1~1)

如何删除/忽略不需要的子模块引用并提交冲突和更改?或者有一个参数,我可以使用我的原来的 git pull,将忽略我的子模块?

167672 次浏览

嗯,它在技术上没有管理子模块的冲突(即: 保持这个,但不是那个) ,但是我找到了一种继续工作的方法... 我所要做的就是注意我的 git status输出并重置子模块:

git reset HEAD subby
git commit

这会将子模块重置为预拉提交。在这种情况下,这正是我想要的。在其他需要对子模块应用更改的情况下,我将使用标准的子模块工作流(签出主机、下拉所需的标记等)处理这些更改。

我以前从没见过这么精确的错误。但我对你遇到的麻烦有个猜测。这看起来像是因为 superymasterone.one分支包含 subby子模块的不同参考文献,当您合并来自 master git 的更改时,不知道 superyone.one分支应该保留和跟踪哪个参考文献—— v1.0v1.1

如果是这种情况,那么您需要选择所需的 ref 并提交更改以解决冲突。这正是您使用 重置命令所做的事情。

在项目的不同分支中跟踪子模块的不同版本是一个棘手的问题。但是子模块 ref 就像项目的任何其他组件一样。如果两个不同的分支在连续的合并之后继续跟踪相同的子模块引用,那么 git 应该能够在将来的合并中不引起合并冲突地解决这个模式。另一方面,如果你频繁切换子模块参考,你可能不得不忍受大量的冲突解决。

首先,找到要引用子模块的散列。然后运行

~/supery/subby $ git co hashpointerhere
~/supery/subby $ cd ../
~/supery $ git add subby
~/supery $ git commit -m 'updated subby reference'

它使我能够将子模块转换为正确的散列引用,并继续我的工作,而不会产生任何进一步的冲突。

我对这个问题的答案有些纠结,对于 类似的职位的答案也没有多少运气。所以这就是对我有用的东西——记住在我的案例中,子模块是由不同的团队维护的,所以冲突来自于 master 中不同的子模块版本,以及我正在进行的项目的本地分支:

  1. 运行 git status-记录有冲突的子模块文件夹
  2. 将子模块重置为上次在当前分支中提交的版本:

    git reset HEAD path/to/submodule

  3. 现在,您已经拥有了子模块的无冲突版本,现在可以在子模块的存储库中更新到最新版本:

    cd path/to/submodule
    git submodule foreach git pull origin SUBMODULE-BRANCH-NAME
  4. And now you can commit that and get back to work.

我有这个问题与 git rebase -i origin/master的一个分行。我想获取子模块 ref 的 master 版本,所以我就这么做了:

git reset master path/to/submodule

然后

git rebase --continue

解决了我的问题。

从这次讨论中得到了帮助。 对我来说

git reset HEAD subby
git commit

为我工作:)

在我的父母目录中我看到:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)

所以我就这么做了

git reset HEAD linux

如果你想使用上游版本:

rm -rf <submodule dir>
git submodule init
git submodule update

以上这些对我来说都不管用。 我把子模块放在“未合并路径”下面,然后我被卡住了..。

经过多次尝试,最终奏效的方法是: 手动删除子模块中的合并冲突文件,而不是主回购中的合并冲突文件:

git restore --staged submodule_path

(这将其移动到“ Changes not stage for commit:”)

 git clean -df

那么

Git 子模块更新—— init