有没有办法让git pull自动更新子模块?


203

有没有一种方法可以自动拥有git submodule update(或最好git submodule update --initgit pull完成后立即调用?

寻找一个git config设置或一个git别名来帮助解决这个问题。



1
为什么git别名比shell别名更好?
2011年

20
git别名很好,因为它将命令封装在“ git”名称空间中。您可能还会问为什么所有git命令都以“ git”开头而不是使用自己的名称。
Lily Ballard

5
对于任何发现此问题的人,目前投票过时的答案都是过时的。凯恩的答案很准确:stackoverflow.com/a/49427199/3499424
John Neuhaus

Answers:


176

Git 2.14开始,您可以使用git pull --recurse-submodules(并为其加上别名)。

Git 2.15开始,您可以设置submodule.recurse为true以启用所需的行为。

您可以通过运行以下命令全局执行此操作:

git config --global submodule.recurse true

3
在2.16中确认,将其设置为true将导致git pull也获取子模块并运行submodule update。现在确实需要接受这个答案
John Neuhaus

1
在全球范围内进行设置:git config --global submodule.recurse true
wintersolutions '18

14
我对子模块感到沮丧,然后我做到了。现在他们像我期望的那样工作。我没有考虑这不是默认行为的原因吗?

9
他们也应为此启用git clone。并默认启用它。否则,由于子模块总是不同步,因此使用子模块总是会有巨大的阻力:-(
Ciro Santilli郝海东冠状病六四事件法轮轮功

1
@CiroSantilli新疆改造中心法轮功六四事件桑蒂利GIT中命令(如commitfetchpull等)被设计成仅适用于当前存储库。子模块是另一个存储库,默认情况下,子模块不应受到在父存储库中执行的命令的影响。这是git-developer的一种设计决策。
负离子

113

git config --global alias.pullall '!git pull && git submodule update --init --recursive'

如果要将参数传递给git pull,请改用以下方法:

git config --global alias.pullall '!f(){ git pull "$@" && git submodule update --init --recursive; }; f'

4
如果要在所有使用的git存储库中使用此别名,请记住使用“ git config --global”
yoyo

43

从Git 1.7.5开始,它将默认自动更新子模块,如您所愿。

[编辑:每条评论:1.7.5的新行为是自动获取子模块的最新提交,但不自动更新他们(在git submodule update意义上的)。因此,此答案中的信息与背景相关,但其本身并不是完整的答案。您仍然需要一个别名才能在一个命令中提取和更新子模块。]

默认行为“按需”是每当您获取用于更新子模块提交的提交,而该提交尚未位于本地克隆中时,都会更新子模块。
您也可以使它在每次获取时都更新,也可以从不更新(我假设1.7.5之前的行为)。
更改此行为的config选项为fetch.recurseSubmodules

此选项可以设置为布尔值或on-demand
将其设置为布尔值会更改行为,fetch并且pull在设置为true时无条件递归到子模块,或者在设置为false时完全不递归。

当设置为on-demand(默认值),fetchpull 仅在其超级项目检索更新该子模块引用的提交时才递归到填充的子模块中

看到:

想要查询更多的信息。

git fetch --recurse-submodules[=yes|on-demand|no]

27
请注意:正如下面的答案所解释,这只会自动获取更改,您仍然必须进行子模块更新-因此别名答案是正确的。
Artem

4
@Artem是正确的。这个答案虽然有用,但不能解决整个问题。此设置仅执行git fetch,而不执行git submodule update
Andrew Ferrier 2014年

2
这个答案极具欺骗性。即使与git pull,而不是与一起使用git fetch,此选项也只能使获取递归。它根本不会改变在子模块中检出的提交。因此,git submodule update仍然是必要的,如@Artem指出。
马克·阿默里

31

我很惊讶没有人提到使用git hooks来做到这一点!

只需将名为post-checkout和的文件添加post-merge.git/hooks相关存储库的目录中,然后将以下文件放入每个存储库中:

#!/bin/sh
git submodule update --init --recursive

由于您是专门要求别名的,因此假设您想在许多存储库中使用该别名,则可以创建一个别名,将其添加到您的存储库中.git/hooks


2
有没有办法将其设置为全局设置?还是您在签出存储库时自动获得的?
Raoul Steffen

3
git的最新版本2.9 添加了一个名为core.hooksPathhooks目录的设置git-config有关更多详细信息,请参阅文档。
taleinat

1
至于退房时自动收到的东西,我进行了搜索,但找不到任何类似的东西。一位消息人士提到,故意不支持此安全问题,因为它很容易用于在客户端计算机上运行任意代码。
taleinat

1
我知道这可能是一个安全问题。毕竟,我想用它来运行我在同事计算机上编写的代码,而无需指示他们。
Raoul Steffen

1
这个解决方案是我的第一个想法,但是后来我意识到它不会涵盖使用git pull --rebase:(
Vaz 18'Sep

8

凯文·巴拉德(Kevin Ballard)提出的别名是一个很好的解决方案。只是为了扔掉另一个选择,您还可以使用仅运行的后合并钩子git submodule update [--init]


7

您可以为git命令创建一个别名,以自动处理子模块更新。将以下内容添加到您的.bashrc中

# make git submodules usable
#   This overwrites the 'git' command with modifications where necessary, and
#   calls the original otherwise
git() {
    if [[ $@ == clone* ]]; then
        gitargs=$(echo "$@" | cut -c6-)
        command git clone --recursive $gitargs
    elif [[ $@ == pull* ]]; then
        command git "$@" && git submodule update --init --recursive
    elif [[ $@ == checkout* ]]; then
        command git "$@" && git submodule update --init --recursive
    else
        command git "$@"
    fi
}

1
除了使用git的别名外,您还可以通过alias命令或在路径中创建以git-(git-bettermodule)
idbrii

7

正如其他人所提到的,您可以使用以下方法轻松设置此设置:

git config --global submodule.recurse true

但是,如果您像我一样,并且.gitconfig设置更复杂(我的主~/.gitconfig文件用于include加载其他.gitconfig文件),并且您永远都不记得如何在命令行git配置格式和.gitconfig格式之间进行转换,那么这是添加方法到您的任何.gitconfig文件:

[submodule]
  recurse = true

0

我唯一能够获取子模块和嵌套子模块进行更新的方法:

git submodule update --remote --merge --recursive; git submodule foreach --recursive "(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);" git add .; git commit -m 'SubmodulesSynced'; git push; git pull;

由于括号的原因,我无法通过终端创建别名,因此我必须将其手动添加到.gitconfig中以进行全局操作:

[alias] supdate = "!git submodule update --remote --merge --recursive; git submodule foreach --recursive '(git add .; git commit -m 'SubmoduleSync'; git push; git pull;);' git add .; git commit -m 'SubmodulesSynced'; git push; git pull;"

关于如何自动运行命令或别名的任何建议?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.