【问题标题】:Git will not init/sync/update new submodulesGit 不会初始化/同步/更新新的子模块
【发布时间】:2011-03-21 04:51:22
【问题描述】:

这是我的.gitmodules 文件的部分内容:

[submodule "src/static_management"]
        path = src/static_management
        url = git://github.com/eykd/django-static-management.git
[submodule "external/pyfacebook"]
        path = external/pyfacebook
        url = http://github.com/sciyoshi/pyfacebook.git

但是,.git/config 只包含第一个:

[submodule "src/static_management"]
        url = git://github.com/eykd/django-static-management.git

第二个子模块 (external/pyfacebook) 是由另一个开发人员在功能分支中添加的。我现在继承了开发,并检查了功能分支。但是,Git 不会为我拉取子模块。我试过了:

  • git submodule init
  • git submodule update
  • git submodule update --init
  • git submodule sync
  • .git/config 中删除所有子模块定义并运行git submodule init。它只复制先前存在的子模块并忽略新的子模块。
  • .git/config 中手动输入新的子模块定义并运行git submodule update。只有以前存在的子模块才需要更新。

各种组合,但git根本不会根据.gitmodules的新内容更新.git/config,也不会创建external/pyfacebook文件夹并拉取子模块的内容。

我错过了什么?是否真的需要手动干预(手动向.git/config 添加子模块条目),为什么?

编辑:手动干预不起作用。手动将新的子模块条目添加到 .git/config 不会做任何事情。新的子模块被忽略。

【问题讨论】:

标签: git git-submodules


【解决方案1】:

这意味着子模块没有正确设置,必须执行git submodule add 命令。 子模块如何工作的详细解释:

如果子模块没有被正确添加:

如果子模块没有正确提交,并且子模块及其对应的文件夹还没有记录在索引中,那么首先.gitmodules文件中的每个子模块都需要通过git submodule add单独添加才能继续。

  • 注意:如 here 所述,Git 目前没有命令对 .gitmodules 文件中存在的多个子模块同时执行此操作。

git submodule add 有什么作用?

当一个带有子模块的 repo 已经正确设置并且有人已经执行了 git submodule add 命令时,该命令做了以下事情:

  1. 如果子模块不存在,则为子模块创建一个文件夹
  2. 将项目克隆为子模块
  3. 可共享 .gitmodules 文件中设置子模块参数
  4. 在您的 private .git/config 文件中设置子模块参数
  5. 在超级项目的私有 .git/modules 文件夹中为子模块创建一个 .git 文件夹
  6. 还有:在超级项目的索引中记录每个子模块将驻留在哪个文件夹中,以及它应该处于什么状态(子模块的哈希提交代码。)

3点和6点在你克隆超级项目时是相关的,点6表示git submodule add是否已经正确执行,被承诺。 您可以通过查看子模块应该驻留的文件夹是否已经存在并且为空来检查点 6注意:这不需要 .keep 或 .gitignore 机制来就位,因为这是 Git 机制的一部分。)克隆超级项目后,您还可以执行 git submodule 以查看预期的子模块。

然后您可以继续:

  • git submodule

    将显示树中存在的子模块及其相应的提交哈希码,可以作为初始检查以查看预期的子模块

  • git submodule init

    将 repo 的 .gitmodules 文件中的子模块参数复制到您的私有 .git/config 文件(点 4

  • git submodule update

    将子模块克隆到由超级项目确定的提交,并在超级项目的 .git/modules/ 文件夹下创建子模块的 .git 文件夹(点 25

  • git submodule update --remote

    与更新相同,但将子模块设置为远程仓库可用的分支上的最新提交,类似于之后进入每个子模块的文件夹并执行git pull

  • 或: git submodule update --init --remote

    以上都是综合的。

或者,当 repo 设置正确时,您还可以使用 --recursive 标志执行 git clone 以将子模块包含在 init 中并自动对其执行更新。 p>

【讨论】:

    【解决方案2】:

    请检查您的子模块目录。

    如果里面只有一个.git文件,那就删除吧。

    现在执行git submodule update --remote --init

    【讨论】:

      【解决方案3】:

      下面的同步命令解决了这个问题:

      git submodule sync
      

      【讨论】:

      • 它什么都不做。
      【解决方案4】:

      只是分享对我有用的东西:

      git clone --recurse-submodules <repository path>
      

      这会克隆已经包含子模块的远程存储库。这意味着您无需在克隆后运行 git submodule update 或 init。

      【讨论】:

        【解决方案5】:

        对我来说问题是,repo 的前一个开发人员将submodules/thing 文件夹作为普通文件夹提交,这意味着当我尝试运行git submodule add ... 时,它会失败:'submodules/thing' already exists in the index,但试图更新子模块也会失败,因为它发现路径不包含子模块。

        要修复,我必须删除 submodules/thing 文件夹,提交删除,然后运行 ​​git submodule add 命令将其正确添加回来:

        git submodule add --force --name thing https://github.com/person/thing.git submodules/thing
        

        【讨论】:

          【解决方案6】:

          我遇到了同样的问题,但上述解决方案都没有帮助。 .gitmodules 和 .git/config 中的条目是正确的,但命令 git submodules update --init --recursive 什么也没做。我还删除了子模块目录并运行 git submodules update --init --recursive 并取回了子模块目录,但提交与以前完全相同。

          我在page 上找到了答案。命令为:git submodule update --remote

          【讨论】:

          • 这对我来说也是正确的解决方案。我正在运行 git submodule update 而不是 git submodule update --remote
          【解决方案7】:

          认为手动设置.gitmodules 就足够了错误

          撰写本文时我的本地 git version 2.22.0

          所以我来到这个帖子想知道为什么git submodule init 不工作;我设置了.gitmodules 文件并继续执行git submodule init ...

          重要

          1. git submodule add company/project.git includes/project必需的(第一次添加模块时),这将:

            • 将配置添加到.git/config
            • 更新.gitmodules文件
            • 跟踪子模块位置(本例中为includes/project)。
          2. 必须然后在添加子模块后git commit,这将提交.gitmodules 和跟踪的子模块位置。

          当项目再次被克隆时,它将具有.gitmodules 和空的子模块目录(例如,本例中的includes/project)。此时.git/config 还没有子模块配置,直到git submodule init 运行,记住这只是因为.gitmodulesincludes/project 在主git repo 中被跟踪。

          另请参阅:

          【讨论】:

            【解决方案8】:
            • .git/config 中删除子模块
            • 运行git submodule init 命令
            • 转到您的子模块目录并运行git pull origin master

            现在应该可以使用了

            【讨论】:

              【解决方案9】:

              记录在案:
              我通过添加一个 empty repository 作为子模块来创建相同的问题。在这种情况下,子模块没有可用的参考哈希,导致原始发布者描述的错误。

              在提交后强制添加存储库解决了问题(如 Arvids 帖子中所述)
              git submodule add --force git@my-repo.git destination

              【讨论】:

                【解决方案10】:

                子模块也有类似的问题。它只是不想被克隆/拉取/更新/无论如何。

                当尝试使用git submodule add git@my-repo.git destination 重新添加子模块时,我得到了以下输出:

                A git directory for 'destination' is found locally with remote(s):
                  origin        git@my-repo.git
                If you want to reuse this local git directory instead of cloning again from
                  git@my-repo.git
                use the '--force' option. If the local git directory is not the correct repo
                or you are unsure what this means choose another name with the '--name' option.
                

                所以,我尝试执行添加命令
                git submodule add --force git@my-repo.git destination

                这在我的情况下有效。

                【讨论】:

                  【解决方案11】:

                  答案似乎(也)有很多混乱。

                  git submodule init 不是旨在神奇地在 .git/config 中生成东西(来自 .gitmodules)。它的目的是在克隆父项目之后在一个完全空的子目录中设置一些东西,或者拉一个添加以前不存在的子模块的提交。

                  换句话说,您通过git submodule update --init --recursive 关注具有子模块的项目的git clone(通过克隆签出 .gitmodules 文件这一事实您会知道)。

                  您确实git submodule add ... 之后使用git submodule init(或git submodule update --init),这是不应该的。事实上,如果一切正常,添加将已经更新适当的 .git/config。

                  编辑

                  如果以前不存在的 git 子模块被其他人添加,并且您对该提交执行了git pull,那么该子模块的目录将完全为空(当您执行 git submodule status 时,新子模块的哈希应该可见,但前面会有一个-。)在这种情况下,您需要在git pull 后面加上git submodule update --init(加上--recursive,当它是子模块中的子模块时)才能获得新的、以前不存在的子模块已签出;就像在一个带有子模块的项目的初始克隆之后(显然你之前没有这些子模块)。

                  【讨论】:

                  • 这很有趣,因为git help submodule 对 init 这么说:“init: 通过将子模块名称和 url 从 .gitmodules 复制到 .git 来初始化索引中记录的子模块(在其他地方添加和提交) /配置。”所以它确实 听起来 应该完全按照您所说的去做...?是时候更新 git 文档了吗?
                  • @brad 我不认为我说过 - 但我为那个具体案例添加了一个澄清。谢谢。
                  • @CarloWood 知道为什么 git 子模块的作者决定需要 --init 来获取新的子模块(而不是在 update 上自动获取它们)?似乎更新您的存储库应该抓住一切必要的东西,除非它会破坏数据。使用--init,它迫使您知道可能已经创建了新的子模块,或者每次都发出--init,在这种情况下,它似乎应该默认启用。
                  • @Catskul 显然我不知道为什么 git 子模块的作者会做出任何决定,但我的猜测是“update”是为更新已经存在的东西而保留的,而“init”是用来创建一些东西的(本地)新的。在引擎盖下,两者可能存在显着差异,足以保证不同的命令。
                  【解决方案12】:

                  如果在git submodule add ... 之前存在,则删除子模块目录及其内容(“external/pyfacebook”文件夹)可能会解决问题。

                  【讨论】:

                  • 这对我来说是个问题。有人将“子模块”文件夹作为普通文件夹提交,这意味着当我尝试运行“git submodule add ...”时,它会失败:“'vendor/mobx-state-tree'已经存在于索引中” ,但尝试更新子模块也会失败,因为它看到路径不包含子模块)。要修复,我必须删除文件夹,提交删除,然后运行 ​​git add 命令将其正确添加回来。
                  【解决方案13】:

                  我今天遇到了同样的问题,发现因为我输入了git submodule init,然后我的.git/config 中有这些行:

                  [submodule]
                     active = .
                  

                  我删除了它并输入了:

                  git submodule update --init --remote
                  

                  一切都恢复正常了,我的子模块照常在其子目录中更新。

                  【讨论】:

                    【解决方案14】:

                    git 版本 2.7.4。此命令更新本地代码 git submodule update --init --force --remote

                    【讨论】:

                    • 什么都不为我做。
                    • 关于 git-submodule [documentation)(git-scm.com/docs/git-submodule#git-submodule---remote) 上述命令应该更新子模块的本地分支。
                    • 您可以使用git submodule update --init --force --remote &lt;module-name&gt;更新单个模块。
                    【解决方案15】:

                    遇到同样的问题,当 git 忽略 initupdate 命令时,什么也不做。

                    如何解决

                    1. 您的子模块文件夹应该提交到 git repo 中
                    2. 它不应该在 .gitignore 中

                    如果满足这些要求,它将起作用。否则,所有命令都将在没有任何消息和结果的情况下执行。

                    如果你做了所有这些,它仍然不起作用:

                    1. 手动添加子模块,例如git submodule add git@... path/to
                    2. git submodule init
                    3. git submodule update
                    4. 提交并推送所有文件 - .gitmodules 和您的模块文件夹(注意,文件夹的内容不会提交)
                    5. 删除本地 git 存储库
                    6. 克隆一个新的
                    7. 确保.git/config 还没有任何子模块
                    8. 现在,git submodule init - 您将看到模块已注册的消息
                    9. git submodule update - 将获取模块
                    10. 现在查看.git/config,您会发现已注册的子模块

                    【讨论】:

                    • 我相信子模块的路径可以在 .gitignore 中。至少我是按照@DaveJamesMiller 的回答让它工作的。没有其他东西对我有用。
                    • 我在.gitignore 中有子模块文件夹,但没有.gitmodules。第一个是意外,第二个是故意的。所以我在删除ignore et voila中的行之后做了git submodule add ..
                    【解决方案16】:

                    我遇到了同样的问题 - 结果证明 .gitmodules 文件已提交,但实际的子模块提交(即子模块的提交 ID 的记录)没有。

                    手动添加似乎可以解决问题 - 例如:

                    git submodule add http://github.com/sciyoshi/pyfacebook.git external/pyfacebook
                    

                    (即使没有从 .git/config 或 .gitmodules 中删除任何内容。)

                    然后提交它以正确记录ID。

                    为这个工作答案添加一些进一步的 cmets:如果 git submodule init 或 git submodule update 不起作用,那么如上所述 git submodule add url 应该可以解决问题。可以通过

                    交叉检查
                     git config --list
                    

                    并且应该得到一个你想要拉入 git config --list 命令结果的子模块的条目。如果配置结果中有你的子模块条目,那么现在通常的 git submodule update --init 应该拉你的子模块。要测试此步骤,您可以手动重命名子模块,然后更新子模块。

                     mv yourmodulename yourmodulename-temp
                     git submodule update --init
                    

                    要查看子模块中是否有本地更改,可以通过 git status -u (如果您想查看子模块中的更改)或 git status --ignore-submodules (如果您不想看到子模块的变化)。

                    【讨论】:

                    • external/pyfacebook 是干什么用的?
                    • @IgorGanapolsky 这是您的子模块的目标路径。
                    • 这对我有帮助,非常感谢!我可以补充一点,如果目标路径已经存在(由于尝试了其他命令,它对我来说是这样的),则会收到以下消息,这只会增加混乱:'your/local/path' already exists and is not a valid git repo
                    • 一个用于在“git config --list”中读取条目的衬垫:git config --list | grep submodule | sed -e "s/submodule\.//" -e "s/\(.*\)\.url=\(.*\)/git submodule add --force \2 \1/" | bash
                    【解决方案17】:

                    有点神奇,但今天我跑了git submodule init,然后是 git submodule sync 后跟 git submodule update 开始了 拉我的子模块......魔术?可能!这确实是最 令人讨厌的 Git 体验……

                    从头开始。我实际上是通过git submodule update --init --recursive 让它工作的。希望这会有所帮助。

                    PS:确保你在 git 根目录下,而不是子模块的目录下。

                    【讨论】:

                    • 不,这对我没有任何作用。
                    • @IgorGanapolsky 我用对我有用的方法编辑了上面的答案。让我知道它是否有效!
                    • 我尝试了您的新命令,但它们也没有执行任何操作。
                    【解决方案18】:

                    当我今天看到这个时,一个开发人员已经将树的一部分移动到一个新的子目录中,看起来他的 git 客户端没有在树中记录更新的子项目规则,而是它们只是被核弹了,留下了 @ 987654321@ 指的是陈旧的位置和当前树中不再存在的子项目。

                    重新添加子模块,并将子模块的提交 shas 与 git show $breaking_commit_sha 中找到的内容进行比较(搜索与正则表达式 ^-Subproject 匹配的行)以根据需要进行调整。

                    【讨论】:

                      【解决方案19】:

                      和你一样,我发现 git submodule sync 并没有按照你的预期去做。 只有在再次执行显式 git submodule add 后,子模块 url 才会更改。

                      所以,我把这个脚本放在~/bin/git-submodule-sync.rb

                      https://gist.github.com/frimik/5125436

                      我还在一些接收后的 git deploy 脚本上使用了相同的逻辑。

                      我现在需要做的就是编辑.gitmodules,然后运行这个脚本,它终于可以像我认为的git submodule sync 那样工作了。

                      【讨论】:

                      • 这似乎只发生在一些回购......可能是由于 Git 中的一些错误。我很久没有在 新创建的存储库上发生这种情况了
                      【解决方案20】:

                      我遇到了同样的问题。

                      .gitmodules 有子模块,但在git submodule init 命令之后它不在.git/config 中。

                      原来添加子模块的开发者也将子模块目录添加到.gitignore文件中。这行不通。

                      【讨论】:

                        【解决方案21】:

                        根据 Dave James Miller 的回答,我可以确认它对我有用。这里重要的是提交子项目的提交 ID。仅仅在 .gitmodules 中有条目是不够的。

                        这是一个适当的提交:

                        https://github.com/dirkaholic/vagrant-php-dev-box/commit/d5f4c40bdbd80eefbb5ac6029823733f591435ae

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2012-01-06
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2013-06-30
                          • 2012-04-10
                          • 2014-08-29
                          相关资源
                          最近更新 更多