题 轻松获取最新的git子模块


我们使用git子模块来管理一些依赖于我们开发的许多其他库的大型项目。每个库都是作为子模块引入依赖项目的单独repo。在开发过程中,我们经常想要抓住每个依赖子模块的最新版本。

git有内置命令来执行此操作吗?如果没有,那么Windows批处理文件或类似文件怎么办呢?


1379
2018-06-23 01:05


起源


混帐深 应该有所帮助。 - bluejamesbond
@Brad是否要将子模块的副本更新为主项目中指定的提交转速;或者你想从每个子模块中提取最新的HEAD提交?这里的大部分答案都针对前者;很多人都想要后者。 - chrisinmtown


答案:


对于 git 1.8.2 或以上选项 --remote 添加以支持更新远程分支的最新提示:

git submodule update --recursive --remote

这具有额外的好处,即尊重在中指定的任何“非默认”分支 .gitmodules 要么 .git/config 文件(如果您碰巧有任何,默认是origin / master,在这种情况下,其他一些答案也适用)。

对于 git 1.7.3 或以上你可以使用(但下面的问题围绕什么更新仍然适用):

git submodule update --recursive

要么:

git pull --recurse-submodules

如果你想把你的子模块拉到repo指向的最新提交intead。

注意:如果那样的话 第一次 你签出一个你需要使用的仓库 --init 第一:

git submodule update --init --recursive

对于 年长的,git 1.6.1 或以上你可以使用类似的东西(修改为适合):

git submodule foreach git pull origin master

看到 GIT-子模块(1) 详情


1756
2018-06-23 13:42



可能你应该使用 git submodule update --recursive 如今。 - Jens Kohl
性能改进: git submodule foreach "(git checkout master; git pull)&" - Bogdan Gusiev
update会将每个子模块更新为指定的版本,而不是将其更新为该存储库的最新版本。 - Peter DeWeese
只是添加,盲目坚持 origin master 如果某些子模块正在跟踪该特定子模块的不同分支或位置名称,则在此命令结尾处可能会出现意外结果。一些人明显,但可能不是每个人。 - Nathan Hornby
只为每个人澄清一下。 git submodule update --recursive 查看父存储库为每个子模块存储的修订版本,然后在每个子模块中检出该修订版本。确实如此 不 拉出每个子模块的最新提交。 git submodule foreach git pull origin master 要么 git pull origin master --recurse-submodules 如果您打算将每个子模块更新为其原始存储库中的最新子模块,那么这就是您想要的。只有这样,您才能在子仓库中获得有关子模块的更新修订版哈希值的挂起更改。检查那些,你很好。 - Chev


如果你需要将子模块的东西拉到你的子模块库中使用

git pull --recurse-submodules

一个功能git首先在1.7.3中学到了。

但是这不会检查子模块中的正确提交(主存储库指向的提交)

要检查子模块中的正确提交,您应该在使用后更新它们

git submodule update --recursive --remote

567
2017-11-10 18:07



upvoted,我用这个:alias update_submodules ='git pull --recurse-submodules && git submodule update' - Stephen C
如果子模块已经被拉出至少一次但是对于从未被检出过的子模块,这是有效的,请参阅下面的gahooa答案。 - Matt Browne
这将拉到顶部repo指定的版本;它不会拉头。例如,如果TopRepo为SubRepo指定了HEAD后面的版本2,那么将使用该版本落后2的SubRepo。这里的其他答案在SubRepo中拉HEAD。 - Chris Moschini
请注意,都没有 git pull --recurse-submodules 也不 git submodule update --recursive 不 不 初始化新添加的子模块。要初始化它们,您需要运行 git submodule update --recursive --init。引用自 手册: 如果子模块尚未初始化,并且您只想使用存储在.gitmodules中的设置,则可以使用--init选项自动初始化子模块。 - patryk.beza
也许添加一个提示 git submodule update --recursive --remote 它还将子模块更新为远程最新版本,而不是存储的SHA-1。 - Hanno S.


注意:这是从2009年开始的,可能还不错,但现在有更好的选择。

我们用这个。它被称为 git-pup

#!/bin/bash
# Exists to fully update the git repo that you are sitting in...

git pull && git submodule init && git submodule update && git submodule status

只需将其放在合适的bin目录(/ usr / local / bin)中。如果在Windows上,您可能需要修改语法才能使其工作:)

更新:

在回应原作者关于提取所有子模块的所有HEAD的评论时 - 这是一个很好的问题。

我很确定 git 在内部没有这个命令。为此,您需要确定HEAD对子模块的真正含义。这可能就像说的那么简单 master 是最新的分支等...

在此之后,创建一个执行以下操作的简单脚本:

  1. git submodule status 用于“修改”的存储库。输出行的第一个字符表示这一点。如果修改了子仓库,您可能不想继续。
  2. 对于列出的每个repo,cd进入它的目录并运行 git checkout master && git pull。检查错误。
  3. 最后,我建议你打印一个显示给用户,以指示子模块的当前状态 - 也许提示他们添加all并提交?

我想提一下,这种风格并不是git子模块的设计用途。通常情况下,您想说“LibraryX”的版本为“2.32”并保持这种状态,直到我告诉它“升级”。

也就是说,从某种意义上说,你正在用所描述的脚本做什么,但更自动。需要护理!

更新2:

如果您使用的是Windows平台,则可能需要使用Python来实现脚本,因为它在这些方面非常强大。如果您使用的是unix / linux,那么我建议只使用一个bash脚本。

需要澄清吗?只需发表评论。


295
2018-06-23 01:50



我认为这不是我想要的。这不会拉动超级项目最后提交的子模块的版本。我想拉出所有子模块的头部版本。 - Brad Robinson
这非常有用,不仅可以更新子模块,还可以在第一次获取子模块,如果这是你需要的。 - Matt Browne
我刚刚收到“当前分支没有跟踪信息。请指定要合并的分支。”无论我尝试什么:/ - Nathan Hornby
为什么不为它创建别名? git config --global alias.pup '!git pull && git submodule init && git submodule update && git submodule status' 然后用它作为 git pup 没有任何脚本。 - fracz
谢谢你,出于某种原因,即使我有git 1.9.1,我还是要表演 git submodule init 在第一次拉动后,包含子模块,这样一切都会开始正常工作。 - Ben Usman


在init上运行以下命令:

git submodule update --init --recursive

从git repo目录中,对我来说效果最好。

这将拉出所有最新的包括子模块。

解释

git - the base command to perform any git command
    submodule - Inspects, updates and manages submodules.
        update - Update the registered submodules to match what the superproject
        expects by cloning missing submodules and updating the working tree of the
        submodules. The "updating" can be done in several ways depending on command
        line options and the value of submodule.<name>.update configuration variable.
            --init without the explicit init step if you do not intend to customize
            any submodule locations.
            --recursive is specified, this command will recurse into the registered
            submodules, and update any nested submodules within.

在此之后你可以运行:

git submodule update --recursive

从git repo目录中,对我来说效果最好。

这将拉出所有最新的包括子模块。

解释

git - the base command to perform any git command
    submodule - Inspects, updates and manages submodules.
        update - Update the registered submodules to match what the superproject
        expects by cloning missing submodules and updating the working tree of the
        submodules. The "updating" can be done in several ways depending on command
        line options and the value of submodule.<name>.update configuration variable.
            any submodule locations.
            --recursive is specified, this command will recurse into the registered
            submodules, and update any nested submodules within.

290
2017-12-11 19:38



是的 - 最高的投票答案是在09年做到这一点的最佳方式,但现在这种方式肯定更简单,更直观。 - Michael Scott Cuthbert
@MichaelScottCuthbert谢谢,我相信在另外3年里这个命令也会疯狂 - abc123
然而,这不会检查子模块的最新修订,只检查父项跟踪的最新修订。 - Nathan Osman
@NathanOsman这是你想要的......你最终会因为不遵循父母版本跟踪而破坏代码。如果您是父母的维护者,您可以自己更新并提交它们。 - abc123
是的,但根据我的理解,这不是OP想要的。 - Nathan Osman


亨里克走在正确的轨道上。 'foreach'命令可以执行任意shell脚本。拉最新的两种选择可能是,

git submodule foreach git pull origin master

和,

git submodule foreach /path/to/some/cool/script.sh

这将遍历所有 初始化 子模块并运行给定的命令。


151
2018-06-23 14:21





以下在Windows上为我工作。

git submodule init
git submodule update

138
2017-07-22 13:12



这显然不是OP所要求的。它只会更新到关联的子模块提交而不是最新的。 - Patrick
然而,这是我第一次检查回购时,这个页面上唯一让git拉出子模块的东西 - theheadofabroom
也可以使用:git submodule update --init --recursive(特别是如果有问题的子模块是来自新克隆的RestKit) - HCdev


编辑

在评论中指出(通过 philfreo )需要最新版本。如果有任何嵌套子模块需要在其最新版本中:

git submodule foreach --recursive git pull

-----下面的过时评论-----

这不是官方的做法吗?

git submodule update --init

我每次都用它。到目前为止没问题。

编辑:

我发现你可以使用:

git submodule foreach --recursive git submodule update --init 

这也将递归地拉出所有子模块,即依赖性。


33
2018-04-05 16:23



你的答案没有回答OP的问题,但要做你提出的建议,你可以说 git submodule update --init --recursive - philfreo
我知道,需要最新版本。如果有嵌套的子模块,这可能是有用的:git submodule foreach --recursive git pull - antitoxic
我不能让任何这些实际下载任何东西 - “git submodule update --init --recursive”但对我有用。 - BrainSlugs83


因为可能发生了子模块的默认分支   master,这就是我自动化完整Git子模块升级的方法:

git submodule init
git submodule update
git submodule foreach 'git fetch origin; git checkout $(git rev-parse --abbrev-ref HEAD); git reset --hard origin/$(git rev-parse --abbrev-ref HEAD); git submodule update --recursive; git clean -dfx'

30
2017-12-04 08:58