我们正在使用git子模块来管理一些依赖于我们开发的许多其他库的大型项目。每个库都是作为子模块引入依赖项目的单独repo。在开发过程中,我们经常想要抓住每个依赖子模块的最新版本。
git是否有内置命令来执行此操作?如果没有,Windows批处理文件或类似的文件怎么样呢?
答案 0 :(得分:2113)
如果 第一次您结帐了一个回购,则需要先使用--init
:
git submodule update --init --recursive
对于 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指向的最新提交内容。
有关详细信息,请参阅git-submodule(1)
答案 1 :(得分:594)
如果需要将子模块的内容拉入子模块库,请使用
git pull --recurse-submodules
首次在1.7.3中学习的功能git。
但是这不会检查子模块中正确的提交(主存储库指向的提交)
要检查子模块中的正确提交,您应该在使用
后进行更新git submodule update --recursive --remote
答案 2 :(得分:366)
git submodule update --init --recursive
这将包括所有最新的包括子模块。
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 - 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.
答案 3 :(得分: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
只需将其放在合适的bin目录(/ usr / local / bin)中。如果在Windows上,您可能需要修改语法才能使其工作:)
<强>更新强>
回应原作者关于提取所有子模块的所有HEAD的评论 - 这是一个很好的问题。
我很确定git
内部没有此命令。为此,您需要确定HEAD对于子模块的真正含义。这可能就像说master
是最新的分支等一样简单......
在此之后,创建一个执行以下操作的简单脚本:
git submodule status
是否有“已修改”的存储库。输出行的第一个字符表示这一点。如果修改了子仓库,您可能不想继续。git checkout master && git pull
。检查错误。我想提一下,这种风格并不是git子模块的设计用途。通常情况下,您想说“LibraryX”的版本为“2.32”并保持这种状态,直到我告诉它“升级”。
从某种意义上说,就是你正在用所描述的脚本做什么,但更自动。需要小心!
更新2:
如果您使用的是Windows平台,则可能需要使用Python来实现脚本,因为它在这些方面非常强大。如果您使用的是unix / linux,那么我建议只使用一个bash脚本。
需要澄清吗?只需发表评论。
答案 4 :(得分:153)
亨里克走在正确的轨道上。 'foreach'命令可以执行任何任意shell脚本。拉最新的两个选项可能是,
git submodule foreach git pull origin master
和
git submodule foreach /path/to/some/cool/script.sh
这将迭代所有初始化的子模块并运行给定的命令。
答案 5 :(得分:143)
以下在Windows上为我工作。
git submodule init
git submodule update
答案 6 :(得分:33)
修改强>:
在评论中指出(通过 philfreo )需要最新版本。如果有任何嵌套子模块需要在其最新版本中:
git submodule foreach --recursive git pull
-----下面的过时评论-----
这不是官方的做法吗?
git submodule update --init
我每次都用它。到目前为止没问题。
修改强>
我刚发现你可以使用:
git submodule foreach --recursive git submodule update --init
还将递归拉出所有子模块,即依赖。
答案 7 :(得分:31)
由于子模块的默认分支可能是而不是 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'
答案 8 :(得分:25)
克隆和初始化子模块
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
注意:最后两个命令具有相同的行为
答案 9 :(得分:18)
我不知道从哪个版本的git开始工作,但这就是你要搜索的内容:
git submodule update --recursive
我将它与git pull
一起使用来更新根存储库:
git pull && git submodule update --recursive
答案 10 :(得分:6)
查看介绍--track参数的http://lists.zerezo.com/git/msg674976.html
答案 11 :(得分:4)
Git for windows 2.6.3 :
git submodule update --rebase --remote
答案 12 :(得分:3)
上面的答案很好,但我们使用git-hooks来简化这一点,但事实证明,在 git 2.14 中,您可以将git config submodule.recurse
设置为true以启用子模块当你拉到你的git存储库时更新。
如果它们在分支上,这会产生推动所有子模块发生变化的副作用,但是如果你已经需要这种行为,那么这可以完成这项工作。
可以使用:
完成git config submodule.recurse true
答案 13 :(得分:3)
我是通过调整gahooa&#39; s answer above:
来做到这一点的将它与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
答案 14 :(得分:2)
对我来说,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-submodules
与 git submodule update --recursive --remote
相同。但是根据我的测试,git pull --recurse-submodules
可能不会更新到 .gitmoodule 中定义的远程分支的最新提交。
答案 15 :(得分:2)
我经常使用此命令,到目前为止,它仍然有效。
git pull
git submodule foreach --recursive git checkout master
git submodule foreach --recursive git pull
希望更快。
答案 16 :(得分:2)
这是从所有git存储库中提取的命令行,无论它们是否是子模块:
ROOT=$(git rev-parse --show-toplevel 2> /dev/null)
find "$ROOT" -name .git -type d -execdir git pull -v ';'
如果您在顶级git存储库中运行它,则可以将"$ROOT"
替换为.
。
答案 17 :(得分:1)
备注:不是太简单的方式,但可行,并且它有自己独特的专业人士。
如果想要仅克隆存储库的HEAD
版本并且只复制其所有子模块的HEAD
(即结帐&#34; trunk&#34;),那么可以使用以下 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
答案 18 :(得分:1)
您现在要做的只是一个简单的git checkout
只需确保通过以下全局配置启用它:git config --global submodule.recurse true
答案 19 :(得分:1)
从回购的顶层开始:
git submodule foreach git checkout develop
git submodule foreach git pull
这将切换所有分支以开发并获取最新版本
答案 20 :(得分:1)
我认为你必须写一个脚本才能做到这一点。说实话,我可能会安装python来执行此操作,以便您可以对每个目录使用os.walk
cd
并发出相应的命令。除了批处理之外,使用python或其他一些脚本语言将允许您轻松添加/删除子项目而无需修改脚本。