【问题标题】:How do I manage conflicts with git submodules?如何管理与 git 子模块的冲突?
【发布时间】:2010-10-24 00:37:34
【问题描述】:

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

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

supery 的主分支有 git 项目 subby 的标签 v1.0 作为子模块引用。 supery的分支叫one.one,将子模块的引用改为指向subby的标签v1.1

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

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

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

$ 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,它会忽略我的子模块?

【问题讨论】:

    标签: git branch git-submodules conflict


    【解决方案1】:

    以上所有对我都不起作用... 我在“未合并路径”下有子模块,我被卡住了......

    经过多次尝试,最终奏效的是: 从子模块中手动删除合并冲突文件而不是在主仓库中:

    git restore --staged submodule_path
    

    (这将其移至“未暂存提交的更改:”)

     git clean -df
    

    然后

    git 子模块更新 --init

    【讨论】:

      【解决方案2】:

      如果你想使用上游版本:

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

      【讨论】:

        【解决方案3】:

        嗯,在我的父目录中,我看到了:

        $ 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
        

        【讨论】:

          【解决方案4】:

          我在这个问题的答案上有些挣扎,也对a similar SO post 中的答案不太满意。所以这对我有用 - 请记住,在我的情况下,子模块是由不同的团队维护的,所以冲突来自 master 和我正在处理的项目的本地分支中的不同子模块版本:

          1. 运行git status - 记下存在冲突的子模块文件夹
          2. 将子模块重置为当前分支最后提交的版本:

            git reset HEAD path/to/submodule

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

            cd 路径/到/子模块
            git submodule foreach git pull origin SUBMODULE-BRANCH-NAME
          4. 现在您可以commit 重新开始工作了。

          【讨论】:

            【解决方案5】:

            从这个讨论中得到帮助。 就我而言

            git reset HEAD subby
            git commit
            

            为我工作:)

            【讨论】:

              【解决方案6】:

              我遇到了 git rebase -i origin/master 到分支的问题。我想获取子模块 ref 的 master 版本,所以我只是做了:

              git reset master path/to/submodule

              然后

              git rebase --continue

              这解决了我的问题。

              【讨论】:

              • 这对我有用。我还在想他们做了什么来破坏子模块
              【解决方案7】:

              我以前没有见过那个确切的错误。但我猜测你遇到的麻烦。看起来是因为superymasterone.one 分支包含subby 子模块的不同引用,当您合并来自master 的更改时,git 不知道哪个引用-v1.0v1.1 -应由superyone.one 分支保存和跟踪。

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

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

              【讨论】:

              • 感谢您对这个问题有所了解。现在这对我来说完全有意义,并且重置命令非常适合我上面的情况。但是从主分支接受子模块引用并将引用丢弃到当前分支的子模块的命令是什么?我知道如何处理正常的冲突,但是在网上搜索了三天后,我找不到除了 rm -r 之外的代码示例。我开始认为这些例子不存在是有原因的;到目前为止,子模块从超级项目中抽象出来,您必须管理每个转换。
              • 终于!一个答案!我在git status 中有added by us: ../Mono.Cecil,但git addgit rmMono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any files 失败,因为它只是一个空文件夹,git 只真正处理文件。 git checkout 给了我Mono.Cecil: needs merge, error: you need to resolve your current index firstgit submodule update 给了Skipping unmerged submodule Mono.Cecilgit checkout master Mono.Cecil 终于修好了。基本问题:git status 的建议是错误的,所以选择一个分支并使用checkout 获取文件夹的副本!
              • @IBBoard 的命令帮助我解决了这种情况——我尝试了git checkout --ours SUBMODgit add SUBMOD 以及其他人,但最终通过git checkout master SUBMOD 解决了冲突。该评论可能应该是一个答案,而不是评论... :)
              【解决方案8】:

              首先,找到您希望子模块引用的哈希值。然后运行

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

              这对我来说很有效,可以让我的子模块获得正确的哈希引用并继续我的工作,而不会发生任何进一步的冲突。

              【讨论】:

              • 或者你可以做一个 git checkout --theirs (or --ours) subby
              • @Bachi: git checkout --theirs 和 --ours 对子模块没有影响。
              • 虽然这确实解决了冲突,但要确定 并不容易。我不知道有一种简单的方法可以查看在冲突的每一侧签出的子模块提交。您在 subby 中签出的任何提交都可能与合并的任一侧不同,这在合并提交中是不合适的。
              • @nilbus 这是真的。我们已经放弃了使用 git 子模块,因为这是我们所担心的问题之一,并且很难判断你真正想要哪个提交。我们使用 composer (php) 作为包管理器,我真的很喜欢它,因为它创建了一个锁定文件,将 repos 锁定到某个哈希值。然而,由于我们在多个 repos 中使用 node_modules,我们会在这里和那里遇到冲突的模块。从那以后,我们改用 npm 来管理这些东西,但这也是另一种蠕虫。
              【解决方案9】:

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

              git reset HEAD subby
              git commit
              

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

              【讨论】:

              • 对我来说,这似乎只是将冲突模块的状态从“均已修改”更改为“已删除”。
              • 您可能希望保留合并分支的子模块: git reset subby
              • 按照答案中的规定为我工作.. git reset HEAD path/to/submodule/dir
              猜你喜欢
              • 1970-01-01
              • 2014-07-31
              • 2018-08-14
              • 2022-09-27
              • 1970-01-01
              • 2017-08-16
              • 2012-06-29
              • 2020-04-28
              • 1970-01-01
              相关资源
              最近更新 更多