"git submodule foreach git pull origin master"和"git pull origin master --recurse-submodules"有什么区别?

Che*_*hev 6 git recursion git-submodules

我有一个dotfiles存储库,其中我的所有vim插件都存储为子模块,因此它们在更改时很容易更新.我认为这两个命令做了同样的事情,但我注意到情况绝对不是这样.

我知道我有几个子模块的更新,所以我git pull origin master --recurse-submodules从父存储库的根目录运行.它似乎迭代每个子模块,但只从其原始存储库获取更新.

当我运行时,git submodule foreach git pull origin master它实际上git pull origin master在每个存储库中运行,同时执行提取和合并.

有什么用--recurse-submodules?我对它实际上要做的事情感到有点困惑,谷歌对我发现的东西有点神秘.我想也许你聪明的人会有一个更简单的解释.

Von*_*onC 7

这种选择主要是为了获取所有的子模块承诺,不只是拉母版一个特定分支,在以下两个提交详细原因:
(注意,是固定在Git中2.11的错误,看到这个答案的末尾)

因为git pull,这个选项已经引入(commit 7dce19d,2010年11月,git 1.7.4-rc0):

fetch/ pull:添加--recurse-submodules选项

到目前为止,你不得不调用" git submodule update"(没有-N|--no-fetch选项)或类似" git submodule foreach git fetch"来从远程中获取填充子模块中的新提交.

这可能导致" (commits not present)"消息中的输出" git diff --submodule(其用于通过"," git gui"和" gitk提取或在上层项目拉动新提交后"),并且是用于实施子模块的递归结帐的障碍.
此外," git submodule update"在断开连接时无法获取更改,因此很容易忘记在断开连接之前获取子模块更改,以便稍后发现它们是必需的.

此补丁添加" --recurse-submodules"选项,以递归方式从.git/config每个" git fetch" 结尾的子模块中配置的url 或git pull超级项目中的" " 期间获取每个填充的子模块.子模块路径取自索引.


Commit 88a2197(2011年3月,git 1.7.5-rc1)解释了一下:

fetch/ pull:必要时递归到子模块

为了能够访问超级项目引用的所有已填充子模块的提交,只有git fetch当超级项目中提取的新提交记录新提交时,才能将" "递归到子模块中.

  • 当使用" --submodule"选项" git diff"(这是git gui"和" gitk自1.6.6以来的")时,提交这些提交非常有用,因为可以访问创建描述性输出所需的所有子模块提交.
  • 同时合并子模块承诺(在1.7.3添加)取决于子模块犯问题存在工作.
  • 最后但并非最不重要的是,这会在使用子模块时启用断开操作,因为成功" git submodule update -N" 所需的所有提交都将自动获取.

因此我们选择此模式作为fetch和pull的默认模式.


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

第一个应该拉,而不仅仅是取,并等同于第二个.也许这是一个参数订单问题:

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

但是,不建议更新给定分支的子模块:请参阅以下部分.


请注意,从master实际提取的正确方法是将主分支注册到子模块,使子模块跟踪主模块:

git config -f .gitmodules submodule.<path>.branch <branch>
Run Code Online (Sandbox Code Playgroud)

那么简单git submodule update --remote --recursive就足够了.
并且要获取/拉取的分支记录在父仓库中(在.gitmodules文件中),因此您甚至不必记住您希望子模块更新的分支.


更新Git 2.11(2011年第4季度)

有一个子模块的" .git"存储库以某种方式被破坏导致一些递归到子模块的命令永远循环.

请参阅Junio C Hamano()提交的10f5c52(2016年9月1日).(由Junio C Hamano合并- -提交293c232,2016年9月12日)gitster
gitster