Easy way to pull latest of all git submodules
我们使用git子模块来管理几个大型项目,这些项目依赖于我们开发的许多其他库。每个库都是一个单独的repo,作为子模块引入到依赖项目中。在开发过程中,我们通常只想获取每个依赖子模块的最新版本。
Git有内置的命令吗?如果不是,那么可以用Windows批处理文件或类似的文件来完成呢?
对于git 1.8.2或更高版本,增加了选项
1 | git submodule update --recursive --remote |
这还有一个额外的好处,那就是尊重
对于Git 1.7.3或更高版本,您可以使用(但下面的内容仍然适用于更新的内容):
1 | git submodule update --recursive |
或:
1 | git pull --recurse-submodules |
如果你想把你的子模块拉到回购所指向的最新提交集成上。
注:如果这是您第一次签出回购,您需要先使用
1 | git submodule update --init --recursive |
对于较旧的Git 1.6.1或更高版本,您可以使用类似于(修改为适合)的内容:
1 | git submodule foreach git pull origin master |
详见Git子模块(1)
如果需要将子模块的内容拉入子模块存储库,请使用
1 | git pull --recurse-submodules |
a feature git first learned in 1.7.3.
但这不会在子模块中签出正确的提交(主存储库指向的提交)。
要检查子模块中的正确提交,应在使用
1 | git submodule update --recursive --remote |
在init上运行以下命令:
1 | git submodule update --init --recursive |
从git repo目录中,对我来说最有效。
这将拉动所有最新的子模块。
解释1 2 3 4 5 6 7 8 9 10 | 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. |
在此之后,您可以运行:
1 | git submodule update --recursive |
从git repo目录中,对我来说最有效。
这将拉动所有最新的子模块。
解释1 2 3 4 5 6 7 8 9 | 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. |
注意:这是从2009年开始的,那时可能很好,但现在有更好的选择。
我们用这个。叫
1 2 3 4 | #!/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上,您可能需要修改语法以使其正常工作:)
更新:
为了回应原作者关于拉入所有子模块的所有头部的评论,这是一个很好的问题。
我敢肯定,江户十一〔一〕内部并没有这方面的命令。为了做到这一点,您需要确定子模块的头部到底是什么。这可以简单地说,
然后,创建一个执行以下操作的简单脚本:
我想说的是,这种风格并不是专为Git子模块设计的。通常,您想说"libraryx"的版本是"2.32",在我告诉它"升级"之前,它将一直保持这种状态。
从某种意义上说,这就是您使用所描述的脚本所做的,但更自动地说。需要小心!
更新2:
如果您使用的是Windows平台,那么您可能需要考虑使用python来实现脚本,因为它在这些方面非常有能力。如果您使用的是UNIX/Linux,那么我建议您只使用bash脚本。
需要澄清吗?发表评论。
亨利走对了。"foreach"命令可以执行任意shell脚本。最新的两个选择可能是:
1 | git submodule foreach git pull origin master |
而且,
1 | git submodule foreach /path/to/some/cool/script.sh |
它将遍历所有初始化的子模块并运行给定的命令。
以下是我在窗户上的作品。
1 2 | git submodule init git submodule update |
编辑:
在评论中指出(菲尔弗雷奥)需要最新版本。如果有任何嵌套子模块需要在其最新版本中:
1 | git submodule foreach --recursive git pull |
-----下面过时的注释-----
这不是正式的方式吗?
1 | git submodule update --init |
我每次都用它。到目前为止没有问题。
编辑:
我发现你可以使用:
1 | git submodule foreach --recursive git submodule update --init |
它还将递归地拉动所有子模块,即依赖关系。
由于您的子模块的默认分支可能不是
1 2 3 | 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' |
第一次
克隆和初始化子模块
1 2 | git clone [email protected]:speedovation/kiwi-resources.git resources git submodule init |
休息
在开发过程中,只需拉动和更新子模块
1 | git pull --recurse-submodules && git submodule update --recursive |
将git子模块更新为源站上的最新提交
1 | git submodule foreach git pull origin master |
首选方式应低于
1 | git submodule update --remote --merge |
注意:最后两个命令具有相同的行为
我不知道这是哪个版本的Git,但这是你要搜索的:
1 | git submodule update --recursive |
我也将它与
1 | git pull && git submodule update --recursive |
查看http://lists.zerezo.com/git/msg674976.html,其中引入了--track参数
适用于Windows 2.6.3的Git:
上面的答案很好,但是我们使用了Git钩子来简化这个过程,但是在Git2.14中,您可以将
但是,如果所有子模块都在分支上,那么这将产生推动所有子模块更改的副作用,但是如果您已经需要这种行为,那么这就可以完成工作了。
可通过以下方式完成:
1 | git config submodule.recurse true |
我是通过调整gahooa的回答来做到这一点的:
与Git
如果您的父项目在
1 2 3 4 5 6 | [submodule"opt/submodules/solarized"] path = opt/submodules/solarized url = [email protected]:altercation/solarized.git [submodule"opt/submodules/intellij-colors-solarized"] path = opt/submodules/intellij-colors-solarized url = [email protected]:jkaving/intellij-colors-solarized.git |
在.gitconfig中添加类似的内容
1 2 | [alias] updatesubs ="!sh -c "git submodule init && git submodule update && git submodule status"" |
然后,要更新子模块,请运行:
1 | git updatesubs |
我在环境设置报告中有一个例子。
以下是从所有Git存储库中提取的命令行,无论它们是否为子模块:
1 2 | ROOT=$(git rev-parse --show-toplevel 2> /dev/null) find"$ROOT" -name .git -type d -execdir git pull -v ';' |
如果在顶级Git存储库中运行它,可以将
从回购协议的顶层:
1 2 | git submodule foreach git checkout develop git submodule foreach git pull |
这将切换所有分支以开发和提取最新的
备注:方法不太简单,但可行,有自己独特的优点。
如果只想克隆存储库的
备注:该脚本仅针对
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | -- 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) then io.stderr:write('can\'t clone repository from ' .. module_url .. ' to ' .. module .. ' ') return 1 end -- cd $module ; git submodule update --init --recursive --remote --no-fetch --depth=1 execute('mkdir -p ' .. module .. '/.git/modules') assert(io.input(module .. '/.gitmodules')) local lines = {} for line in io.lines() do table.insert(lines, line) end local submodule local path local submodule_url for _, line in ipairs(lines) do local submodule_ = line:match('^%[submodule %"([_%d%a]-)%"%]$') if submodule_ then submodule = submodule_ path = nil submodule_url = nil else local path_ = line:match('^%s*path = (.+)$') if path_ then path = path_ else submodule_url = line:match('^%s*url = (.+)$') end if 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) then io.stderr:write('can\'t clone submodule ' .. submodule .. ' ') return 1 end path = nil submodule_url = nil end end end |
你现在需要做的只是一个简单的
只需确保通过以下全局配置启用:
我想你得写个剧本才能做到这一点。老实说,我可能会安装python来实现这一点,这样您就可以对每个目录使用