有办法自动有git子模块更新(或最好是git子模块更新——init调用每当git拉?

寻找一个git配置设置,或一个git别名来帮助这一点。


当前回答

您可以为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
}

其他回答

从Git 1.7.5开始,默认情况下它应该像你希望的那样自动更新子模块。

[EDIT: per comments:新的1.7.5行为是自动获取子模块的最新提交,但不更新它们(在git子模块更新的意义上)。所以这个答案中的信息是相关的背景,但它本身并不是一个完整的答案。您仍然需要一个别名来在一个命令中提取和更新子模块。]

默认的行为,“按需”,是每当你获取一个更新子模块提交的提交时更新子模块,并且这个提交还没有位于你的本地克隆中。 你也可以在每次读取时更新它,或者从不更新(我假设是1.7.5之前的行为)。 改变这种行为的配置选项是fetch.recurseSubmodules。

此选项可以设置为布尔值,也可以按需设置。 将其设置为布尔值将改变fetch和pull的行为,使其在设置为true时无条件递归到子模块中,或在设置为false时完全不递归。 当设置为按需(默认值)时,fetch和pull只会在已填充的子模块的超项目检索更新子模块引用的提交时递归到子模块中。

See:

Git配置手册页(1.7.5)(或最新的Git配置手册页) Git获取手册页(1.7.5)(或最新的Git获取手册页)

获取更多信息。

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

我如何能够获得子模块和嵌套子模块更新的唯一方法:

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;"

对于如何自动运行命令或别名有什么建议吗?

您可以为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
}

Kevin Ballard建议的别名是一个非常好的解决方案。只是抛出另一个选项,你也可以使用post-merge钩子,它只运行git子模块update[——init]。

从Git 2.15开始,你可以设置submodule。递归为true以启用所需的行为。

事实上,你不需要这么做。

在Git 2.34 (Q4 2021)之前,在“Git clone——recurse-submodules”(man)之后,所有子模块都被克隆了,但默认情况下不会被其他命令递归。

与Git 2.34,和子模块。stickyRecursiveClone配置集,子模块。递归配置在“clone”创建的存储库中被设置为true,并带有“——Recurse -submodules”选项。

参见Mahi Kolla (24mahik)提交的48072e3(2021年8月14日)。 (由Junio C Hamano—gitster—在commit 6d09fc5中合并,2021年9月10日)

克隆:设置子模块。如果子模块,递归=true。stickyRecursiveClone启用 署名:Mahi Kolla

Based on current experience, when running git clone --recurse-submodules(man), developers do not expect other commands such as pull or checkout to run recursively into active submodules. However, setting submodule.recurse=true at this step could make for a simpler workflow by eliminating the need for the --recurse-submodules option in subsequent commands. To collect more data on developers' preference in regards to making submodule.recurse=true a default config value in the future, deploy this feature under the opt in submodule.stickyRecursiveClone flag.


警告:使用Git 2.37 (Q3 2022):

"git pull"(man) without——recursive -submodules=<arg> made submodule。递归优先于取回。recurseSubmodules错误,已在Git 2.37 (Q3 2022)中更正。

参见格伦·秋(chooglen)提交的5819417(2022年5月10日)。 (由Junio C Hamano—gitster—在commit ed54e1b中合并,2022年5月20日)

拉:不让子模块。fetch.recurseSubmodules 报告人:Huang Zou 资助人:菲利普·布莱恩 署名:Glen Choo

Fix a bug in "git pull"(man) where submodule.recurse is preferred over fetch.recurseSubmodules when performing a fetch (Documentation/config/fetch.txt says that fetch.recurseSubmodules should be preferred.). Do this by passing the value of the "--recurse-submodules" CLI option to the underlying fetch, instead of passing a value that combines the CLI option and config variables. In other words, this bug occurred because builtin/pull.c is conflating two similar-sounding, but different concepts: Whether "git pull" itself should care about submodules e.g. whether it should update the submodule worktrees after performing a merge. The value of "--recurse-submodules" to pass to the underlying git fetch". Thus, when submodule.recurse is set, the underlying "git fetch"(man) gets invoked with --recurse-submodules[=value]", overriding the value of fetch.recurseSubmodules. An alternative (and more obvious) approach to fix the bug would be to teach "git pull" to understand fetch.recurseSubmodules, but the proposed solution works better because: We don't maintain two identical config-parsing implementions in "git pull" and git fetch". It works better with other commands invoked by "git pull" e.g. 'git merge'(man) wont accidentally respect fetch.recurseSubmodules.