拉取所有git子模块的最新更改

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

如何获取所有git子模块的最新更改?

1527065 次浏览

注意:这是从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. 对于列出的每个存储库,cd进入它的目录并运行git checkout master && git pull。检查错误。
  3. 最后,我建议您打印一个显示给用户,以指示子模块的当前状态——也许会提示他们添加所有并提交?

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

也就是说,从某种意义上说,您正在使用所描述的脚本做什么,但只是更自动。需要小心!

更新2:

如果您在windows平台上,您可能希望使用Python来实现脚本,因为它在这些领域非常强大。如果您在unix/linux上,那么我建议使用bash脚本。

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

我认为你必须编写一个脚本来做到这一点。老实说,我可能会安装python来做到这一点,这样你就可以对每个目录使用os.walkcd并发出适当的命令。使用python或其他一些脚本语言,而不是批处理,将允许您轻松添加/删除子项目,而无需修改脚本。

如果它是第一次,您需要先使用--init来签出存储库:

git submodule update --init --recursive

对于git1.8.2或更高版本,添加了选项--remote以支持更新到远程分支的最新提示:

git submodule update --recursive --remote

这还有一个额外的好处,即尊重.gitmodules.git/config文件中指定的任何“非默认”分支(如果您碰巧有任何分支,默认值是原始/主,在这种情况下,这里的其他一些答案也可以)。

对于git1.7.3或以上,您可以使用(但以下关于更新仍然适用的问题):

git submodule update --recursive

或:

git pull --recurse-submodules

如果您想将子模块拉取到最新提交,而不是repo指向的当前提交。

详情见g it-子模块(1)

亨利克走在正确的道路上.git submodule foreach命令可以执行任意外壳脚本。提取最新版本的两个选项可能是:

git submodule foreach git pull origin master

和:

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

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

编辑

在注释中指出(由Philfreo)需要最新版本。如果有任何嵌套的子模块需要在其最新版本中:

git submodule foreach --recursive git pull

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

这不是官方的做法吗?

git submodule update --init

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

编辑:

我发现你可以使用:

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

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

以下内容适用于Windows。

git submodule initgit submodule update

我不知道这是哪个版本的git,但这就是你正在寻找的:

git submodule update --recursive

我也将它与git pull一起使用来更新根存储库:

git pull && git submodule update --recursive
git pull --recurse-submodules --jobs=10

git在1.8.5中首次学习的功能。

bug修复之前,您第一次需要运行

git子模块更新

由于您的子模块的默认分支可能是没有master,这就是我自动化完整Git子模块升级的方式:

git submodule initgit submodule updategit 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'

在init上运行以下命令:

git submodule update --init --recursive

从git repo目录中,最适合我。

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

解释

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

在此之后,您可以运行:

git submodule update --recursive

从git repo目录中,最适合我。

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

第一次

克隆和初始化子模块

git clone git@github.com:speedovation/kiwi-resources.git resourcesgit submodule init

休息

在开发过程中,只需拉取和更新子模块

git pull --recurse-submodules  && git submodule update --recursive

更新Git子模块到最新的提交

git submodule foreach git pull origin master

首选方式应该在下面

git submodule update --remote --merge

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

这是从所有git存储库中提取的命令行,无论它们是否是子模块:

ROOT=$(git rev-parse --show-toplevel 2> /dev/null)find "$ROOT" -name .git -type d -execdir git pull -v ';'

如果您在顶级git存储库中运行它,您可以将"$ROOT"替换为.

备注:不是太简单的方法,但可行,它有自己独特的优点。

如果只想克隆一个仓库的HEAD版本和所有子模块的HEAD版本(即签出“主干”),那么可以使用下面的lua脚本。有时简单的命令git submodule update --init --recursive --remote --no-fetch --depth=1会导致不可恢复的git错误。在这种情况下,需要清理.git/modules目录的子目录并使用git clone --separate-git-dir命令手动克隆子模块。唯一的复杂性是找出url,子模块目录.git的路径和超级项目树中的子模块路径。

备注:该脚本仅针对https://github.com/boostorg/boost.git存储库进行测试。其特点:所有子模块托管在同一主机上,.gitmodules仅包含相对的url

-- mkdir boost ; cd boost ; lua ../git-submodules-clone-HEAD.lua https://github.com/boostorg/boost.git .local module_url = arg[1] or 'https://github.com/boostorg/boost.git'local module = arg[2] or module_url:match('.+/([_%d%a]+)%.git')local branch = arg[3] or 'master'function execute(command)print('# ' .. command)return os.execute(command)end-- execute('rm -rf ' .. module)if not execute('git clone --single-branch --branch master --depth=1 ' .. module_url .. ' ' .. module) thenio.stderr:write('can\'t clone repository from ' .. module_url .. ' to ' .. module .. '\n')return 1end-- cd $module ; git submodule update --init --recursive --remote --no-fetch --depth=1execute('mkdir -p ' .. module .. '/.git/modules')assert(io.input(module .. '/.gitmodules'))local lines = {}for line in io.lines() dotable.insert(lines, line)endlocal submodulelocal pathlocal submodule_urlfor _, line in ipairs(lines) dolocal submodule_ = line:match('^%[submodule %"([_%d%a]-)%"%]$')if submodule_ thensubmodule = submodule_path = nilsubmodule_url = nilelselocal path_ = line:match('^%s*path = (.+)$')if path_ thenpath = path_elsesubmodule_url = line:match('^%s*url = (.+)$')endif submodule and path and submodule_url then-- execute('rm -rf ' .. path)local git_dir = module .. '/.git/modules/' .. path:match('^.-/(.+)$')-- execute('rm -rf ' .. git_dir)execute('mkdir -p $(dirname "' .. git_dir .. '")')if not execute('git clone --depth=1 --single-branch --branch=' .. branch .. ' --separate-git-dir ' .. git_dir .. ' ' .. module_url .. '/' .. submodule_url .. ' ' .. module .. '/' .. path) thenio.stderr:write('can\'t clone submodule ' .. submodule .. '\n')return 1endpath = nilsubmodule_url = nilendendend

Windows2.6.3的git:

git submodule update --rebase --remote

上面的答案是好的,但是我们使用git挂钩来使这变得更容易,但事实证明,在git2.14中,您可以将#0设置为true,以使子模块在您拉到git存储库时更新。

然而,如果它们在分支上,这将产生推送所有子模块更改的副作用,但如果您已经需要该行为,这可以完成工作。

可以通过使用:

git config submodule.recurse true

所有你需要做的是一个简单的git checkout

只需确保通过此全局配置启用它:git config --global submodule.recurse true

从repo的顶层开始:

git submodule foreach git checkout developgit submodule foreach git pull

这会切换所有分支去开发拉取最新

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

git pullgit submodule foreach --recursive git checkout mastergit submodule foreach --recursive git pull

希望这个更快。

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

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可能不会更新到. gitmods中定义的远程分支的最新提交。

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

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

git submodule update --recursive- or -git pull --recurse-submodules --jobs=X

如果“最新”表示主要中的最新版本,则可以这样做:

git submodule foreach "git checkout main && git pull"

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

我研究了这个简单的外壳脚本,它对我来说很好。

#!/bin/bash
#git initgit init
#git clone repo including submodulesgit clone --recurse-submodules https://github.com/username/project.git
#change directory -repocd project
#update the remote ie tag/commitsgit submodule update --remote
#add commitgit commit -a -m "commit in submodule"
#git pushgit push -u origin