【问题标题】:Why is git submodule not updated automatically on git checkout?为什么 git 子模块不会在 git checkout 上自动更新?
【发布时间】:2009-12-14 09:05:38
【问题描述】:

当使用 git checkout 切换分支时,我会假设大多数时候你会想要更新你的子模块。

  • 在什么情况下您不想在切换后更新子模块?
  • 如果这由 git checkout 自动完成,会出现什么问题?

更新示例:

  • 分支 A 在 3852f1 有子模块 S
  • B 分支在 fd72d7 有子模块 S

在分支 A 上,git checkout B 将生成分支 B 的工作副本,其中子模块 S 位于 3852f1(带有修改的 S)。 git submodule update 将在 fd72d7 签出 S。

【问题讨论】:

  • 我同意你的看法。我正在处理带有子模块的项目,每次拉取后我应该执行 git submodule update,但大多数时候没有必要。这样做的唯一原因 - 不要错过实际更新子模块之一的时间。

标签: git git-submodules


【解决方案1】:

git checkout --recurse-submodules 已添加到 git 2.13

发行说明中提到了这一点:https://github.com/git/git/commit/e1104a5ee539408b81566066aaa6963cb87d5cd6#diff-c24776ff22455a30fbb78e378b7df0b0R139

submodule.recurse 选项已添加到 git 2.14

设置为:

git config --global submodule.recurse true

man git-config 说:

指定命令是否默认递归到子模块中。这适用于所有具有--recurse-submodules 选项的命令。默认为 false。

我觉得默认不更新模块是一个糟糕的 Git 默认行为,它违背了大多数用户的期望并限制了子模块的采用,我真的希望开发人员能够改变它。

【讨论】:

  • submodule.recurse 似乎从 git 2.14 开始工作。
  • 我已将submodule.recurse 设置为true,但我发现仍有时间(我认为是在添加子模块时来回跳跃?)我必须做git submodule update --init --recursive在我的git checkout 之后。有没有办法让它自动发生?
  • 既然有配置设置,他们应该默认启用它,并让任何(不知何故)喜欢手动更新的人选择退出。
  • @jamesdlin 我同意,并且我建议如果您对此感觉足够强烈,您可以向Git development community 表达您的意见。还有一个recent patch 建议在何时设置submodule.recurse使用git clone --recurse-submoodules。您也可以在邮件列表中就该建议发表您的意见:)
【解决方案2】:

我相信不自动更新的子模块符合 Git 的开发目标。 Git 旨在以分布式模式工作,并且不假定您甚至可以连接到非本地存储库,除非您明确告诉它这样做。考虑到这种情况,Git 不自动刷新子模块将是预期的行为。

话虽如此,如果你知道你总是希望这些子模块被拉入,并且你知道你永远不会将这些子模块分支到另一个本地存储库,那么如果你自动地它不应该破坏任何东西结帐后刷新它们。

【讨论】:

  • 我认为如果子模块的提交不可用,git checkout 应该只是抱怨,而不是默认情况下使工作目录处于不一致的状态。然后你可以做 git submodule update 来获取引用的提交。同样,通常提交将可用,并且可以在没有任何网络访问的情况下完成签出。接受您的回答,因为这听起来很合理(但我不喜欢它;)
  • 我支持 git 应该尝试执行子模块初始化并在初始结帐时更新并抱怨并显示状态是否存在第一次未在本地拉出的子模块的概念。在你拥有它之后,需要显式更新的概念是有意义的,因为 repos 是不同的,并且子模块引用了特定的提交。但即使在一个可能不可用的分布式世界中,您也很可能在某个时候想要它,而 git 应该让您知道它从未被拉取过。
  • git fetch 有一个自动 fetch 子模块的选项,所以同样我认为结帐应该有一个类似的选项来自动更新/结帐子模块。
  • “考虑到这种方式,Git 不自动刷新子模块将是预期的行为。” - 我不明白为什么。事实上,我看不出你第一段中的任何一点与 Git 是否应该在拉取时自动尝试更新子模块的问题有任何关系。
  • Git 并不假定您在想要对存储库执行工作时始终可以访问您签出的存储库。相反,一旦克隆,您的存储库就可以完全独立运行。如果开始的假设是您只在被告知时才连接到外部存储库,那么 Git 不应该自动刷新我试图传达的子模块。
【解决方案3】:

使用 Git 2.27(2020 年第二季度),“--recurse-submodules”选项得到了更好的记录。

参见Damien Robert (damiens-robert)@commit acbfae3commit 4da9e99commit d09bc51commit b3cec57commit dd0cb7d(2020 年 4 月 6 日)。
(由Junio C Hamano -- gitster -- 合并到commit cc908db, 2020 年 4 月 28 日)

doc: --recurse-submodules 主要适用于 active 子模块

签字人:Damien Robert
协助人:Philippe Blain

文档提到“初始化”或“填充”子模块,以解释哪些子模块受“--recurse-submodules”影响,但这里的真正术语是“active”子模块。相应地更新文档。

一些术语:

  • Active is defined in gitsubmodules(7),只涉及配置变量'submodule.active'、'submodule.<name>.active'和'submodule.<name>.url'。
    submodule.c::is_submodule_active 函数检查子模块是否处于活动状态。
  • Populated 表示子模块的工作树存在(并且 gitfile 正确指向子模块存储库),即超级项目使用--recurse-submodules 克隆,或者用户运行git submodule update --init,或@987654333 @ 和 git submodule update [<path>] 分别填充了子模块工作树。
    这不涉及上面的 3 个配置变量。
  • Initialized(至少在本补丁所涉及的手册页的上下文中)表示上面定义的“填充”和“活动”,即[git submodule更新 --init](https://git-scm.com/docs/git-submodule) 会。

--recurse-submodules 选项主要影响活动子模块。

一个例外是git fetch,该选项会影响填充的子模块。
因此,在git pull --recurse-submodules 中,fetch 会影响填充的子模块,但生成的工作树更新只会影响活动的子模块。

git-pull的文档中,让我们区分影响填充子模块的获取部分和仅影响活动子模块的工作树更新。


使用 Git 2.33(2021 年第三季度),submodule.recurse 的文档更加清晰:

参见Philippe Blain (phil-blain)commit 878b399(2021 年 7 月 16 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit c018818,2021 年 8 月 2 日)

doc:澄清“submodule.recurse”的描述

签字人:Philippe Blain

submodule.recurse”的文档以“指定命令是否默认递归到子模块”开头。
并非所有具有“--recurse-submodules”选项的命令都是如此。
例如,'git pull --recurse-submodules'(man) 不在每个子模块中运行 'git pull'(man),而是运行 '@987654344 @'(man) 以便拉取后的子模块工作树与超级项目中记录的提交匹配。

通过说它启用“--recurse-submodules”来澄清这一点。

请注意,此设置与“fetch.recurseSubmodules”和“push.recurseSubmodules”交互的方式,它们可以具有除真或假以外的其他值,自4da9e99(“doc:在(fetch|push).recurseSubmodules", 2020-04-06, Git v2.27.0-rc0 -- merge 列在batch #4)。

git config 现在包含在其man page 中:

一个布尔值,指示命令是否应默认启用--recurse-submodules 选项。 适用于支持此选项的所有命令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 1970-01-01
    • 2020-12-20
    • 2019-02-02
    • 2018-11-23
    相关资源
    最近更新 更多