我们正在使用git子模块来管理几个大型项目,这些项目依赖于我们开发的许多其他库。每个库都是作为子模块带入相关项目的单独的存储库。在开发过程中,我们经常只想获取每个依赖子模块的最新版本。
git有内置命令可以做到这一点吗?如果不是,那么可以执行Windows批处理文件或类似文件?
我们正在使用git子模块来管理几个大型项目,这些项目依赖于我们开发的许多其他库。每个库都是作为子模块带入相关项目的单独的存储库。在开发过程中,我们经常只想获取每个依赖子模块的最新版本。
git有内置命令可以做到这一点吗?如果不是,那么可以执行Windows批处理文件或类似文件?
Answers:
如果这是您第一次签出回购协议,则需要先使用--init
:
git submodule update --init --recursive
对于git 1.8.2或更高版本,--remote
添加了该选项以支持更新到远程分支的最新提示:
git submodule update --recursive --remote
这样做有一个额外的好处,.gitmodules
即.git/config
可以遵守or 文件中指定的任何“非默认”分支(如果碰巧有默认分支,则默认为origin / master,在这种情况下,此处的其他一些答案也可以使用)。
对于git 1.7.3或更高版本,您可以使用(但以下有关更新的陷阱仍然适用):
git submodule update --recursive
要么:
git pull --recurse-submodules
如果您想将子模块拉到最新的提交,而不是当前的提交,则仓库指向该提交。
见混帐子模块(1)了解详细信息
git submodule update --recursive
现在应该使用。
git submodule foreach "(git checkout master; git pull)&"
origin master
如果您的某些子模块跟踪该特定子模块的不同分支或位置名称,则盲目地粘贴在此命令的末尾可能会产生意外结果。对某些人很明显,但可能对每个人都不是。
git submodule update --recursive
会查看父存储库为每个子模块存储了哪个修订,然后在每个子模块中检出该修订。它不拉的最新提交的每个子模块。git submodule foreach git pull origin master
或者git pull origin master --recurse-submodules
如果您打算将每个子模块从其原始存储库更新到最新版本,则是您想要的。只有这样,您才能在父存储库中获得待处理的更改,并带有子模块的更新的修订哈希。检查那些就可以了。
git pull --recurse-submodules --jobs=10
git在1.8.5中首次学习的功能。
在错误修复之前,您第一次需要运行
git子模块更新--init --recursive
git pull --recurse-submodules
也git submodule update --recursive
不会不初始化新添加的子模块。要初始化它们,您需要运行git submodule update --recursive --init
。引自手册:如果尚未初始化子模块,而您只想使用存储在.gitmodules中的设置,则可以使用--init选项自动初始化子模块。
git submodule update --recursive --remote
该提示还会将子模块更新为远程最新版本,而不是存储的SHA-1。
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目录中,最适合我。
这将拉动所有最新的包括子模块。
注意:这是从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
内部没有此命令。为此,您需要确定子模块的真正含义是什么。那可能很简单master
最新分支,等等。
之后,创建一个简单的脚本,该脚本执行以下操作:
git submodule status
“修改后的”存储库。输出行的第一个字符表明了这一点。如果修改了子仓库,您可能不想继续。git checkout master && git pull
。检查错误。我想提一下,这种样式并不是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
无需任何脚本。
git submodule init
在第一次拉动之后执行该操作,其中包括子模块,以便一切都能正常工作。
以下在Windows上对我有用。
git submodule init
git submodule update
编辑:
在评论中(由philfreo指出),需要最新版本。如果有任何嵌套子模块需要最新版本:
git submodule foreach --recursive git pull
-----以下过时的评论-----
这不是官方的方式吗?
git submodule update --init
我每次都用它。到目前为止没有问题。
编辑:
我刚刚发现您可以使用:
git submodule foreach --recursive git submodule update --init
这也将递归地拉动所有子模块,即依赖关系。
git submodule update --init --recursive
git submodule foreach --recursive git pull
可能会发生子模块的默认分支不是 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'
克隆和初始化子模块
git clone git@github.com:speedovation/kiwi-resources.git resources
git submodule init
在开发过程中,只需拉出并更新子模块
git pull --recurse-submodules && git submodule update --recursive
git submodule foreach git pull origin master
git submodule update --remote --merge
注意:最后两个命令具有相同的行为
git submodule update
把戏。现在,我正在下载克隆第一步中缺少的子模块数据。谢谢。我不太擅长git:C
我不知道这是从哪个版本的git开始工作,但这就是您要搜索的内容:
git submodule update --recursive
我也使用它git pull
来更新根存储库:
git pull && git submodule update --recursive
上面的答案很好,但是我们使用git-hooks使其更容易,但事实证明,在git 2.14中,可以将其设置git config submodule.recurse
为true,以使子模块在拉到git存储库时得以更新。
但是,如果所有子模块都在分支上,这将产生推动所有子模块更改的副作用,但是如果您已经需要这种行为,则可以完成此工作。
可以使用以下方法完成:
git config submodule.recurse true
git submodule init
是,即使您的子模块尚未初始化,仍需要手动使用。
从仓库的顶层:
git submodule foreach git checkout develop
git submodule foreach git pull
这将切换所有分支机构以开发并拉动最新的
git submodule foreach git pull origin master
必须追加我要提取的分支。除此之外,效果很好。
将其与git集成[alias]
...
如果您的父项目在中具有以下内容.gitmodules
:
[submodule "opt/submodules/solarized"]
path = opt/submodules/solarized
url = git@github.com:altercation/solarized.git
[submodule "opt/submodules/intellij-colors-solarized"]
path = opt/submodules/intellij-colors-solarized
url = git@github.com:jkaving/intellij-colors-solarized.git
在您的.gitconfig中添加类似的内容
[alias]
updatesubs = "!sh -c \"git submodule init && git submodule update && git submodule status\" "
然后,要更新您的子模块,请运行:
git updatesubs
备注:不太容易,但是可行,并且它有自己独特的优点。
如果只想克隆HEAD
一个版本库和HEAD
它的所有子模块中的一个(即检出“ trunk”),则可以使用以下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) then
io.stderr:write('can\'t clone repository from ' .. module_url .. ' to ' .. module .. '\n')
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 .. '\n')
return 1
end
path = nil
submodule_url = nil
end
end
end