轻松获取最新的git子模块

Bra*_*son 1748 git git-submodules

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

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

Hen*_*son 2325

对于git 1.8.2或更高版本,--init添加了该选项以支持更新远程分支的最新提示:

git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)

这有额外的好处是尊重--remote.gitmodules文件中指定的任何"非默认"分支(如果你碰巧有任何,默认是origin/master,在这种情况下,这里的一些其他答案也可以工作).

对于git 1.7.3或更高版本,你可以使用(但下面有关于更新仍然适用的问题):

git submodule update --recursive --remote
Run Code Online (Sandbox Code Playgroud)

要么:

git submodule update --recursive
Run Code Online (Sandbox Code Playgroud)

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

注意:如果这是您第一次签出仓库,则需要先使用.git/config:

git pull --recurse-submodules
Run Code Online (Sandbox Code Playgroud)

对于较旧的git 1.6.1或更高版本,你可以使用类似的东西(修改为适合):

git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅git-submodule(1)

  • 可能你现在应该使用`git submodule update --recursive`. (292认同)
  • 性能提升:`git submodule foreach"(git checkout master; git pull)&"` (35认同)
  • 只为每个人澄清一下.`git submodule update --recursive`查看父存储库为每个子模块存储的修订版,然后在每个子模块中检出该修订版.它不会**为每个子模块提取最新的提交.`git submodule foreach git pull origin master`或`git pull origin master --recurse-submodules`是你想要的每个子模块从他们的原始存储库更新到最新的子模块.只有这样,您才会在子仓库中获得有关子模块的更新修订版哈希值的挂起更改.检查那些,你很好. (30认同)
  • 只是添加,如果您的某些子模块正在跟踪该特定子模块的不同分支或位置名称,则在此命令末尾盲目地粘贴`origin master`可能会产生意外结果.有些人很明显,但可能并不是每个人都有. (21认同)
  • update会将每个子模块更新为指定的版本,而不是将其更新为该存储库的最新版本. (17认同)
  • 现在这里有一个问题:你能做到这一点,所以它是递归的吗?即`git submodule foreach`也会在每个子模块中运行EDIT:nvm,只需使用`--recurse-submodules` (6认同)
  • 正如它所说,您需要修改执行的命令以满足您的需要.我已将其设置为获取当前分支正在跟踪的任何内容并将其重新绑定到当前分支上,这是设置的一个非常方便的事情:) (4认同)
  • 您可以在添加它们时按照http://git-scm.com/docs/git-submodule添加`git submodule add -b <branch>`添加分支信息,或者稍后通过添加`branch = <branch>行手动添加`到`.gitmodules`中的模块部分.当指定每个模块的分支时,`git submodule foreach git pull`应该在没有`... origin master`的情况下工作. (3认同)
  • 如果只有*某些*子模块尚未启动,运行“git submodule update --init --recursive”是否安全? (3认同)
  • `--init` 答案部分应该移到顶部,因为这就是人们想知道的。 (3认同)
  • @cowlinator:自从我写下最初的回复以来,在过去的 10 年里,这个答案已经被多人编辑过。厨师太多了,也许:) 我把初始化位移到了顶部。还删除了自 9 年前上次 1.6 版本以来的 1.6 信息。 (3认同)
  • 有没有办法做类似的事情: `git submodule foreach "(git checkout &lt;currentbranch&gt;; git pull)&amp;"` (2认同)
  • 这个命令对我不起作用,子模块代码没有拉. (2认同)
  • 我在 git 2.11.0 上尝试了这个答案,它导致子模块中的 HEAD 分离,远远落后于之前检查的分支。它的工作原理正如 @Chev 在上面的评论中所描述的那样,因此 *不* 回答 OP 的问题。 (2认同)
  • 需要指出的是,答案中有关首次检查存储库的注释适用于 1.7.3+ 和 1.8.2+。答案的格式使这一点不清楚。 (2认同)
  • @Friedrich,这可能意味着存储库的主分支不是“master”。现在 Github 的默认值是 `main`。它有点打破了这个流程。 (2认同)

Ale*_*osh 617

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

git pull --recurse-submodules --jobs=10
Run Code Online (Sandbox Code Playgroud)

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

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

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

git pull --recurse-submodules --jobs=10
Run Code Online (Sandbox Code Playgroud)

  • upvoted,我用这个:alias update_submodules ='git pull --recurse-submodules && git submodule update' (29认同)
  • 请注意,`git pull --recurse-submodules`和`git submodule update --recursive`都不会**初始化新添加的子模块.要初始化它们,您需要运行`git submodule update --recursive --init`.引自[手册](https://git-scm.com/docs/git-submodule):*如果子模块尚未初始化,并且您只想使用存储在.gitmodules中的设置,则可以自动初始化带有--init选项的子模块.* (11认同)
  • 这将拉到顶部repo指定的版本; 它不会拉头.例如,如果TopRepo为SubRepo指定了HEAD后面的版本2,那么这将使该版本落后2的SubRepo.这里的其他答案在SubRepo中拉HEAD. (7认同)
  • 如果子模块已经被拉过至少一次但是对于从未检查过的子模块,这是有效的,请参阅下面的gahooa答案. (3认同)
  • 可能会向`git submodule update --recursive --remote` 添加一个提示,它还会将子模块更新为远程最新版本,而不是存储的 SHA-1。 (2认同)

abc*_*123 375

在init上运行以下命令:

git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)

从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.
Run Code Online (Sandbox Code Playgroud)

在此之后你可以运行:

git submodule update --recursive
Run Code Online (Sandbox Code Playgroud)

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

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

解释

git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)

  • 是的 - 最高的投票答案是09年最好的回答方式,但现在肯定更简单,更直观. (10认同)
  • 尽管如此,这并不会检查子模块的最新修订版本,只会检查父级正在跟踪的最新修订版本. (4认同)
  • @NathanOsman这就是你想要的......你最终会因为不遵循父母版本跟踪而破坏了代码.如果您是父母的维护者,您可以自己更新并提交它们. (3认同)
  • @MichaelScottCuthbert谢谢,我相信在另外3年里这个命令也会疯狂 (2认同)
  • 是的,但根据我的理解,这不是OP想要的. (2认同)

gah*_*ooa 302

注意:这是从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
Run Code Online (Sandbox Code Playgroud)

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

更新:

回应原作者关于拉入所有子模块的所有HEAD的评论 - 这是一个很好的问题.

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

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

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

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

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

更新2:

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

需要澄清吗?刚发表评论.

  • 为什么不为它创建别名?`git config --global alias.pup'!git pull && git submodule init && git submodule update && git submodule status'`然后将它用作`git pup`而不用任何脚本. (8认同)
  • 这非常有用,不仅可以更新子模块,还可以在第一次获取子模块,如果这是你需要的. (3认同)

mtu*_*tte 157

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

git submodule foreach git pull origin master
Run Code Online (Sandbox Code Playgroud)

和,

git submodule foreach /path/to/some/cool/script.sh
Run Code Online (Sandbox Code Playgroud)

这将迭代所有初始化的子模块并运行给定的命令.


zac*_*eat 142

以下在Windows上为我工作.

git submodule init
git submodule update
Run Code Online (Sandbox Code Playgroud)

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

ant*_*xic 33

编辑:

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

git submodule foreach --recursive git pull
Run Code Online (Sandbox Code Playgroud)

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

这不是官方的做法吗?

git submodule update --init
Run Code Online (Sandbox Code Playgroud)

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

编辑:

我发现你可以使用:

git submodule foreach --recursive git submodule update --init 
Run Code Online (Sandbox Code Playgroud)

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

  • 你的答案没有回答OP的问题,但要做你提出的建议你可以说'git submodule update --init --recursive` (5认同)
  • 我知道,需要最新版本.如果有嵌套的子模块,这可能是有用的:`git submodule foreach --recursive git pull` (2认同)

Seb*_*tte 33

因为它可能会发生,你的子模块的默认分支是不是 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'
Run Code Online (Sandbox Code Playgroud)


Yas*_*ash 28

第一次

克隆和初始化子模块

git clone git@github.com:speedovation/kiwi-resources.git resources
git submodule init
Run Code Online (Sandbox Code Playgroud)

休息

在开发过程中,只需拉动并更新子模块即可

git pull --recurse-submodules  && git submodule update --recursive
Run Code Online (Sandbox Code Playgroud)

将Git子模块更新为最新的原始提交

git submodule foreach git pull origin master
Run Code Online (Sandbox Code Playgroud)

首选方式应在下面

git submodule update --remote --merge
Run Code Online (Sandbox Code Playgroud)

注意:最后两个命令具有相同的行为


Jen*_*ohl 20

我不知道从哪个版本的git开始工作,但这就是你要搜索的内容:

git submodule update --recursive
Run Code Online (Sandbox Code Playgroud)

我也用它git pull来更新根存储库:

git pull && git submodule update --recursive
Run Code Online (Sandbox Code Playgroud)


小智 17

根据从远程提取每个子模块的“最新”代码的现有答案来澄清一些事情。

如果“ latest ”表示已签入的子模块指针,则务必使用:

git submodule update --recursive
  - or -
git pull --recurse-submodules --jobs=X
Run Code Online (Sandbox Code Playgroud)

如果“ latest ”意味着main的最新版本,那么这样的事情就可以工作:

git submodule foreach "git checkout main && git pull"
Run Code Online (Sandbox Code Playgroud)

不幸的是,这意味着没有“--jobs”选项,因此我们无法并行运行它。我见过的最接近并行运行的方法是使用pfs python 代码。


Bin*_* Ho 15

我经常使用这个命令,到目前为止它有效。

git pull
git submodule foreach --recursive git checkout master
git submodule foreach --recursive git pull
Run Code Online (Sandbox Code Playgroud)

希望这更快。


Von*_*onC 11

正如抗毒剂回答所述,简单的git submodule foreach --recursive git pull就足够了。

弗朗西斯·培根的答案可能git pull --recurse-submodules有所不同。

您可以测试一下,看看使用详细选项会发生什么情况:

git pull -v --recurse-submodules
Run Code Online (Sandbox Code Playgroud)

但为此,您将需要 Git 2.40(2023 年第一季度)。

git pull -v --recurse-submodules( man )尝试-v向下传递给底层( man ),但底层不理解请求并被拒绝:这已在 Git 2.40 (Q1 2023) 中得到纠正。git submodule update

请参阅Sven Strickroth ( )的提交 6f65f84(2022 年 12 月 10 日)。(由Junio C Hamano 合并 -- --提交 b3b9e5c中,2022 年 12 月 28 日)csware
gitster

submodule:接受-v更新命令

签署人:Sven Strickroth

由于a56771a(“ builtin/pull:尊重子模块中的详细设置”,2018-01-25,Git v2.17.0-rc0 -合并批#3中列出),“ git pull -v --recurse-submodulesman将传播-v到子模块命令,但因为后者命令不理解该选项,它会呕吐。

教“ git submodule update男人接受修复它的选项。

不再“呕吐”(即显示用法“ git submodule foreach [--quiet] [--recursive] [--] <command>”),因为这-v是 的未知选项git submodule


Jam*_*esD 8

上面的答案很好,但是我们使用git-hooks使其更容易,但事实证明,在git 2.14中,可以将其设置git config submodule.recurse为true,以使子模块在拉到git存储库时得以更新。

但是,如果所有子模块都在分支上,这将具有推动所有子模块更改的副作用,但是如果您已经需要这种行为,则可以完成此工作。

可以使用以下方法完成:

git config submodule.recurse true
Run Code Online (Sandbox Code Playgroud)


小智 6

请参阅http://lists.zerezo.com/git/msg674976.html,其中介绍了--track参数

  • 目前还没有在git 1.7.1中实现这一点. (2认同)

seo*_*oul 6

适用于 Windows 2.6.3 的Git :

git submodule update --rebase --remote


Sra*_*rta 5

从存储库的顶层:

git submodule foreach git checkout develop
git submodule foreach git pull
Run Code Online (Sandbox Code Playgroud)

这将切换所有分支以开发并拉取最新版本


Fra*_*con 5

对我来说,git 2.24.03,更新到 .gitmoodule 中定义的远程分支的最新提交。

git submodule update --recursive --init

git submodule update --recursive --remote

git 版本 2.24.3 (Apple Git-128)

请注意: 有人说这 git pull --recurse-submodulesgit submodule update --recursive --remote. 但是从我的测试来看,git pull --recurse-submodules可能无法更新到 .gitmoodule 中定义的远程分支的最新提交。