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

phi*_*reo 174 git git-submodules

有没有办法自动拥有git submodule update(或最好随时git submodule update --init调用git pull

寻找一个git配置设置,或者一个git别名来帮助解决这个问题.

Kan*_*ane 132

从git 2.14开始,您可以设置submodule.recurse为true以启用所需的行为.

您可以通过运行来全局执行此操作:

git config --global submodule.recurse true
Run Code Online (Sandbox Code Playgroud)

  • 我对子模块感到沮丧,然后我就这样做了.现在他们像我期望的那样工作.有没有理由我没想到这不是默认行为? (11认同)
  • 在 2.16 中确认,将此设置为 true 将导致 `git pull` 也获取一个子模块并运行 `submodule update`。这真的需要成为现在公认的答案 (8认同)
  • 这是一个**危险的**设置**如果您关心子模块中的本地更改**。它似乎相当于“--force”,它将丢弃索引或工作树中的任何更改,并且它会很高兴地让您失去对本地提交的跟踪(您必须诉诸“reflog”)! (8认同)
  • 他们也应该为`git clone`启用它.并默认启用它.否则,使用子模块总会有很大的阻力,因为人们的模块总是不同步:-( (6认同)
  • @Andrea看来,除了一个突出的错误(v2.29.2)之外,现在已经基本上修复了,如果您切换到没有子模块的分支,该错误会导致本地更改无声丢失,但该错误是已知的并且已修复正在开发中。 (3认同)
  • @CiroSantilli新疆改造中心法轮功六四事件 Santilli git 命令(如 `commit`、`fetch`、`pull` 等)被设计为仅应用于当前存储库。子模块是另一个存储库,默认情况下不应受到父存储库中执行的命令的影响。这是 git 开发人员的一种设计决策。 (2认同)
  • 由于某种原因,这对我不起作用。我在 Windows 上使用 _Git Bash_,版本为“2.34.1.windows.1”。设置此选项后,执行 `git clone <repo>` 仍然不起作用。我仍然必须在克隆之后进入并执行“git submodule update --init”。 (2认同)

Lil*_*ard 111

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'
Run Code Online (Sandbox Code Playgroud)

  • 如果你想在你使用的所有git repos中使用这个别名,请记得使用"git config --global" (4认同)

Chr*_*ers 42

从Git 1.7.5开始,它应该像你想要的那样自动更新子模块.

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

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

此选项可以设置为布尔值或on-demand.
将其设置为布尔值会更改行为,fetchpull在设置为true时无条件地递归到子模块,或者在设置为false时根本不递归.

当设置为on-demand(默认值),fetchpull 在其上层项目检索提交,更新子模块的引用将只迭代到一个人口稠密的子模块.

看到:

欲获得更多信息.

git fetch --recurse-submodules[=yes|on-demand|no]
Run Code Online (Sandbox Code Playgroud)

  • 注意:正如下面的答案所解释的,这只是自动获取更改,您仍然需要进行子模块更新 - 所以别名答案是正确的. (27认同)
  • @Artem是对的.这个答案虽然有用,却没有解决整个问题.此设置只执行`git fetch`,而不是`git submodule update`. (4认同)
  • 这个答案非常具有欺骗性.即使与`git pull`一起使用,而不是`git fetch`,这个选项只会使*fetching*递归.它根本不会改变在子模块中检出的提交.因此,如@Artem所述,仍然需要`git submodule update`. (2认同)

tal*_*nat 29

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

只需添加文件命名post-checkoutpost-merge.git/hooks有关的信息库的目录,并把下列它们:

#!/bin/sh
git submodule update --init --recursive
Run Code Online (Sandbox Code Playgroud)

由于您明确要求别名,假设您希望为多个存储库提供此别名,您可以创建一个别名,将这些别名添加到存储库中.git/hooks.

  • 最新版本的git,2.9,为[hooks目录添加了一个名为`core.hooksPath`的设置](https://github.com/blog/2188-git-2-9-has-been-released#git -tidbits-gitbits-tidgits),有关详细信息,请参阅`git-config`的文档. (3认同)
  • 有没有办法让这个全球化?或者在检查存储库时自动获得? (2认同)

Cas*_*bel 8

正如凯文巴拉德所建议的那样,别名是一个非常好的解决方案.只是为了抛出另一个选项,你也可以使用简单运行的合并后钩子git submodule update [--init].


Bra*_*ena 6

您可以为自动处理子模块更新的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
}
Run Code Online (Sandbox Code Playgroud)


Jac*_*lyn 6

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

git config --global submodule.recurse true
Run Code Online (Sandbox Code Playgroud)

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

[submodule]
  recurse = true
Run Code Online (Sandbox Code Playgroud)