为什么 git checkout 时 git 子模块没有自动更新?

发布于 2024-08-14 19:45:14 字数 340 浏览 8 评论 0 原文

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

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

更新示例:

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

在分支 A 上,git checkout B 将生成分支 B 的工作副本,其子模块 S 在 3852f1 处(带有修改后的 S)。 git 子模块更新将在 fd72d7 处签出 S。

When switching branches with git checkout I would assume that most of the time you would want to update your submodules.

  • In what situation do you not want to update submodules after switching?
  • What would break if this was done automatically by git checkout?

Updated with example:

  • Branch A has submodule S at 3852f1
  • Branch B has submodule S at fd72d7

On branch A, git checkout B will result in a working copy of branch B with submodule S at 3852f1 (with a modified S). git submodule update will checkout S at fd72d7.

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

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

发布评论

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

评论(3

两相知 2024-08-21 19:45:14

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

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

submodule.recurse< /code> 选项已添加到 git 2.14

设置为:

git config --global submodule.recurse true

man git-config 说:

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

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

submodule.recurse 使 git fetch 每次都获取所有子模块

这使得该选项基本上慢得无法使用,因为即使子模块启动时也会发生获取迄今为止,它尝试从这些子模块获取分支更新。

我做了很多抓取工作来查看同事的提交,所以我必须经常抓取。与顶级存储库相比,子模块的移动速度往往要慢得多,因此没有必要一直获取它们。

所以现在我坚持使用 Bash 函数解决方法:

gco() { git checkout --recurse-submodules "$@" }

这个解决方法并不完美,因为还有其他命令可以更改提交,例如 git rebase ,因此您最终必须定义多个别名。我现在没有更好的解决方案:

gsuu() {
  git submodule sync --recursive &>/dev/null
  git submodule update --init --recursive --progress "$@"
}
grb() {
  git rebase "$@"
  gsuu
}

git checkout --recurse-submodules was added to git 2.13

This is mentioned on the release notes at: https://github.com/git/git/commit/e1104a5ee539408b81566066aaa6963cb87d5cd6#diff-c24776ff22455a30fbb78e378b7df0b0R139

submodule.recurse option was added to git 2.14

Set as:

git config --global submodule.recurse true

man git-config says:

Specifies if commands recurse into submodules by default. This applies to all commands that have a --recurse-submodules option. Defaults to false.

I feel that not updating modules by default is a bad Git default behavior that goes against most user's expectations and limits the adoption of submodules, I really wish the devs would change it.

submodule.recurse makes git fetch fetch all submodules every time

This makes the option basically unusably slow, because the fetch happens even when the submodules are up to date, as it tries to fetch an branch updates from those submodules.

I do a lot of fetching to see my co-workers commits so I have to fetch often. And submodules tend do move much more slowly compared to the toplevel repo, so fetching them all the time is not necessary.

So for now I stick to the Bash function workaround:

gco() { git checkout --recurse-submodules "$@" }

This workaround is not perfect as there are other commands that can change commit, e.g. git rebase, so you end up having to define multiple aliases. I don't have a better solution for this right now:

gsuu() {
  git submodule sync --recursive &>/dev/null
  git submodule update --init --recursive --progress "$@"
}
grb() {
  git rebase "$@"
  gsuu
}
风尘浪孓 2024-08-21 19:45:14

我认为子模块不自动更新是符合Git的发展目标的。 Git 旨在以分布式模式工作,并且不假定您甚至能够连接到非本地存储库,除非您明确告诉它。当这样想时,Git 不自动刷新子模块将是预期的行为。

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

I believe that the submodules not updating automatically is in line with the development goals of Git. Git is meant to work in a distributed mode and doesn't presume that you are even able to connect to a non-local repository unless you explicitly tell it to. Git not auto-refreshing a submodule would be the expected behavior when thought of that way.

With that being said, if you know that you always want those sub-modules to be pulled in and you know that you would never branch off of those submodules to another local repository, then it shouldn't break anything if you automatically refreshed them after a checkout.

夜司空 2024-08-21 19:45:14

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

请参阅提交 acbfae3提交 4da9e99, 提交d09bc51提交b3cec57提交 dd0cb7d(2020 年 4 月 6 日),作者:达米恩·罗伯特 (damiens-robert)
(由 Junio C Hamano -- gitster -- 合并于 提交 cc908db,2020 年 4 月 28 日)

doc--recurse -submodules 主要适用于活动子模块

签字人:Damien Robert
帮助者:Philippe Blain

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

一些术语:

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

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

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


在 Git 2.33(2021 年第 3 季度)中,submodule.recurse 的文档更加清晰:

请参阅 提交 878b399(2021 年 7 月 16 日),作者:Philippe Blain (phil-blain)
(由 Junio C Hamano -- gitster -- 合并于 提交 c018818,2021 年 8 月 2 日)

doc:澄清“子模块”的描述。递归'

签字人:Philippe Blain

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

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

请注意,此设置与“fetch.recurseSubmodules”和“push.recurseSubmodules”交互的方式(可以具有除 true 或 false 之外的其他值)已记录在案由于 4da9e99 (“doc:更准确地说( fetch|push).recurseSubmodules",2020-04-06,Git v2.27.0-rc0 -- 合并 第 4 批)。

git config 现在包含在其 手册页

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

With Git 2.27 (Q2 2020), the "--recurse-submodules" option is better documented.

See commit acbfae3, commit 4da9e99, commit d09bc51, commit b3cec57, commit dd0cb7d (06 Apr 2020) by Damien Robert (damiens-robert).
(Merged by Junio C Hamano -- gitster -- in commit cc908db, 28 Apr 2020)

doc: --recurse-submodules mostly applies to active submodules

Signed-off-by: Damien Robert
Helped-by: Philippe Blain

The documentation refers to "initialized" or "populated" submodules, to explain which submodules are affected by '--recurse-submodules', but the real terminology here is 'active' submodules. Update the documentation accordingly.

Some terminology:

  • Active is defined in gitsubmodules(7), it only involves the configuration variables 'submodule.active', 'submodule.<name>.active' and 'submodule.<name>.url'.
    The function submodule.c::is_submodule_active checks that a submodule is active.
  • Populated means that the submodule's working tree is present (and the gitfile correctly points to the submodule repository), i.e. either the superproject was cloned with --recurse-submodules, or the user ran git submodule update --init, or git submodule init [<path>] and git submodule update [<path>] separately which populated the submodule working tree.
    This does not involve the 3 configuration variables above.
  • Initialized (at least in the context of the man pages involved in this patch) means both "populated" and "active" as defined above, i.e. what [git submodule update --init](https://git-scm.com/docs/git-submodule) does.

The --recurse-submodules option mostly affects active submodules.

An exception is git fetch where the option affects populated submodules.
As a consequence, in git pull --recurse-submodules the fetch affects populated submodules, but the resulting working tree update only affects active submodules.

In the documentation of git-pull, let's distinguish between the fetching part which affects populated submodules, and the updating of worktrees, which only affects active submodules.


With Git 2.33 (Q3 2021), the documentation for submodule.recurse is clearer:

See commit 878b399 (16 Jul 2021) by Philippe Blain (phil-blain).
(Merged by Junio C Hamano -- gitster -- in commit c018818, 02 Aug 2021)

doc: clarify description of 'submodule.recurse'

Signed-off-by: Philippe Blain

The doc for 'submodule.recurse' starts with "Specifies if commands recurse into submodles by default".
This is not exactly true of all commands that have a '--recurse-submodules' option.
For example, 'git pull --recurse-submodules'(man) does not run 'git pull'(man) in each submodule, but rather runs 'git submodule update --recursive'(man) so that the submodule working trees after the pull matches the commits recorded in the superproject.

Clarify that by just saying that it enables '--recurse-submodules'.

Note that the way this setting interacts with 'fetch.recurseSubmodules' and 'push.recurseSubmodules', which can have other values than true or false, is already documented since 4da9e99 ("doc: be more precise on (fetch|push).recurseSubmodules", 2020-04-06, Git v2.27.0-rc0 -- merge listed in batch #4).

git config now includes in its man page:

A boolean indicating if commands should enable the --recurse-submodules option by default.
Applies to all commands that support this option.

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