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

发布于 2024-10-10 17:52:41 字数 166 浏览 5 评论 0 原文

自动让 git submodule update (或者最好是在 git pull 完成时调用 git submodule update --init

有没有办法 git 配置设置,或 git 别名来帮助解决这个问题。

Is there a way to automatically have git submodule update (or preferably git submodule update --init called whenever git pull is done?

Looking for a git config setting, or a git alias to help with this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

游魂 2024-10-17 17:52:41

Git 2.14 开始,您可以使用 git pull --recurse-submodules (并将其别名为您喜欢的任何名称)。

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

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

git config --global submodule.recurse true

As of Git 2.14, you can use git pull --recurse-submodules (and alias it to whatever you like).

As of Git 2.15, you could set submodule.recurse to true to enable the desired behaviour.

You can do this globally by running:

git config --global submodule.recurse true
眼藏柔 2024-10-17 17:52:41

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'

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

If you want arguments to be passed to git pull, then use this instead:

git config --global alias.pullall '!f(){ git pull "$@" && git submodule update --init --recursive; }; f'
情场扛把子 2024-10-17 17:52:41

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

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

默认行为“按需”是每当您获取更新子模块提交的提交时更新子模块,并且此提交尚未位于您的本地克隆。
您还可以在每次获取时更新它或从不更新它(我假设是 1.7.5 之前的行为)。
更改此行为的配置选项是 fetch.recurseSubmodules

此选项可以设置为布尔值或按需
将其设置为布尔值会更改 fetchpull 的行为,以便在设置为 true 时无条件递归到子模块,或者在设置为 false 时根本不递归。

当设置为on-demand(默认值)时,fetchpull 只会在以下情况下递归到填充的子模块:它的超级项目检索更新子模块引用的提交

请参阅:

了解更多信息。

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

Starting with Git 1.7.5 it should update submodules automatically by default like you want it to.

[EDIT: per comments: the new 1.7.5 behaviour is to automatically fetch the latest commits for submodules, but not to update them (in the git submodule update sense). So the information in this answer is relevant as background, but is not a complete answer by itself. You still need an alias to pull and update submodules in one command.]

The default behavior, "on-demand", is to update submodules whenever you fetch a commit that updates the submodule commit, and this commit isn't already located in your local clone.
You can also have it updated on every fetch or never (pre-1.7.5 behavior I assume).
The config option to change this behavior is fetch.recurseSubmodules.

This option can be either set to a boolean value or to on-demand.
Setting it to a boolean changes the behavior of fetch and pull to unconditionally recurse into submodules when set to true or to not recurse at all when set to false.

When set to on-demand (the default value), fetch and pull will only recurse into a populated submodule when its superproject retrieves a commit that updates the submodule’s reference.

See:

for more information.

git fetch --recurse-submodules[=yes|on-demand|no]
各自安好 2024-10-17 17:52:41

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

只需将名为 post-checkoutpost-merge 的文件添加到相关存储库的 .git/hooks 目录中,并将以下内容放入每个文件中:其中:

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

由于您特别要求提供别名,假设您希望许多存储库都拥有此别名,那么您可以创建一个别名,将这些别名添加到存储库的 .git/hooks 中。

I'm surprised nobody mentioned using git hooks to do this!

Just add files named post-checkout and post-merge to your .git/hooks directory of the relevant repositories, and put the following into each of them:

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

Since you specfically asked for an alias, assuming you want to have this for many repositories, you can create an alias which adds these to a repository's .git/hooks for you.

网名女生简单气质 2024-10-17 17:52:41

正如其他人提到的,您可以轻松地设置它:

git config --global submodule.recurse true

但是,如果您像我一样并且有更复杂的 .gitconfig 设置(我的主 ~/.gitconfig 文件使用 include 加载其他 .gitconfig 文件),并且你永远记不住如何在命令行 git 配置格式和.gitconfig 格式,以下是将其添加到任何 .gitconfig 文件中的方法:

[submodule]
  recurse = true

As others have mentioned, you can easily set this with:

git config --global submodule.recurse true

However, if you're like me and have a more complex .gitconfig setup (my main ~/.gitconfig file uses include to load in other .gitconfig files), and you can never remember how to convert between the command-line git config format and the .gitconfig format, here's how to add it to any of your .gitconfig files:

[submodule]
  recurse = true
三生一梦 2024-10-17 17:52:41

正如凯文·巴拉德(Kevin Ballard)建议的那样,别名是一个完美的解决方案。只是为了抛出另一个选项,您还可以使用合并后挂钩,它只运行 git submodule update [--init] 。

An alias, as suggested by Kevin Ballard, is a perfectly good solution. Just to toss another option out there, you could also use a post-merge hook which simply runs git submodule update [--init].

甜`诱少女 2024-10-17 17:52:41

您可以为自动处理子模块更新的 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
}

You can create an alias for the git command that automatically handles submodule updating. Add the following to your .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
}
与君绝 2024-10-17 17:52:41

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

事实上,你不必这样做。

Git 2.34(2021 年第 4 季度)之前,“git clone --recurse-submodules"(man),所有子模块都会被克隆,但默认情况下它们不会被其他命令递归到。

使用 Git 2.34 和 submodule.stickyRecursiveClone 配置集,在使用“clone”创建的存储库中,submodule.recurse 配置设置为 true --recurse-submodules”选项。

请参阅 提交 48072e3(2021 年 8 月 14 日),作者:Mahi Kolla (24mahik)
(由 Junio C Hamano -- gitster -- 合并于 提交 6d09fc5,2021 年 9 月 10 日)

克隆:设置submodule.recurse=true如果启用了 submodule.stickyRecursiveClone

签署人:Mahi Kolla

根据当前经验,运行时 git clone --recurse-submodules(man),开发人员不希望其他命令(例如 pull 或 checkout)递归运行到活动子模块中。

但是,在此步骤中设置 submodule.recurse=true 可以消除后续命令中对 --recurse-submodules 选项的需要,从而简化工作流程。

要收集有关开发人员未来将 submodule.recurse=true 设置为默认配置值的偏好的更多数据,请在 opt in submodule.stickyRecursiveClone 标志下部署此功能。


警告:使用 Git 2.37(2022 年第 3 季度):

git pull"(man)< /sup> 没有 --recurse-submodules= 导致 submodule.recurse 错误地优先于 fetch.recurseSubmodules,这导致了已使用 Git 2.37(2022 年第 3 季度)进行更正。

请参阅 提交 5819417(2022 年 5 月 10 日),作者:Glen Choo (chooglen)
(由 Junio C Hamano -- gitster -- 合并于 提交 ed54e1b,2022 年 5 月 20 日)

:不要让 submodule.recurse 覆盖 fetch.recurseSubmodules

报道人:黄邹
帮助者:Philippe Blain
签字人:Glen Choo

修复“git pull< /code>(man)其中,在执行提取时,submodule.recurse 优先于 fetch.recurseSubmodules(Documentation/config/fetch.txt 表示 fetch.recurseSubmodules 应该是首选。)。

通过将“--recurse-submodules”CLI 选项的值传递给底层提取来完成此操作,而不是传递组合了 CLI 选项和配置变量的值。

换句话说,出现这个错误是因为 builtin/ pull.c 混淆了两个听起来相似但不同的概念:

  • git pull”本身是否应该关心子模块,例如它是否应该在执行合并后更新子模块工作树。
  • 传递给底层 git fetch 的“--recurse-submodules”值。

因此,当设置 submodule.recurse 时,底层的“git fetch"(man) 通过 --recurse-submodules[=value]" 调用,覆盖 fetch.recurseSubmodules 的值。

修复该错误的另一种(也是更明显的)方法是教“git pull”理解fetch.recurseSubmodules,但建议的解决方案效果更好,因为:

  • 我们不会在“git pull”和git fetch”中维护两个相同的配置解析实现。
  • 与“git pull”调用的其他命令配合使用效果更好,例如“git 合并'(man) 不会意外地尊重 fetch.recurseSubmodules

As of Git 2.15, you could set submodule.recurse to true to enable the desired behaviour.

Actually, you won't have to do that.

Before Git 2.34 (Q4 2021), after "git clone --recurse-submodules"(man), all submodules are cloned but they are not by default recursed into by other commands.

With Git 2.34, and submodule.stickyRecursiveClone configuration set, submodule.recurse configuration is set to true in a repository created by "clone" with "--recurse-submodules" option.

See commit 48072e3 (14 Aug 2021) by Mahi Kolla (24mahik).
(Merged by Junio C Hamano -- gitster -- in commit 6d09fc5, 10 Sep 2021)

clone: set submodule.recurse=true if submodule.stickyRecursiveClone enabled

Signed-off-by: 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.


Warning: use Git 2.37 (Q3 2022):

"git pull"(man) without --recurse-submodules=<arg> made submodule.recurse take precedence over fetch.recurseSubmodules by mistake, which has been corrected with Git 2.37 (Q3 2022).

See commit 5819417 (10 May 2022) by Glen Choo (chooglen).
(Merged by Junio C Hamano -- gitster -- in commit ed54e1b, 20 May 2022)

pull: do not let submodule.recurse override fetch.recurseSubmodules

Reported-by: Huang Zou
Helped-by: Philippe Blain
Signed-off-by: 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.
叫思念不要吵 2024-10-17 17:52:41

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

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

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

Only way how I was able to get the submodules and nested submodules to update:

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;

I was struggling to create the alias through terminal due to the brackets so I had to manually add this to .gitconfig for global:

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

Any suggestions for how to run the commands or the alias automatically?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文