这个问题有没有办法让 git pull 自动更新子模块?有一个公认的配置 git 的答案:
git config --global submodule.recurse true
就像该答案的评论之一一样,我想知道为什么这不是 git 的默认行为;更准确地说,设置此配置选项有哪些缺点?
此选项是在 commit 046b482 中引入的,最初用于工作树 操作命令 (
read-tree
/checkout
/reset
)
git grep
/fetch
/pull
/push
很快就跟进了。git clone --recurse-submodules <URL> <directory>
。这是引入后的设计决定,因为
可能太大。git clone
也许我们需要重新考虑该决定,如果设置了,则克隆子模块。submodule.recurse
由于所涉及的子模块的数量/大小可能很大,因此目前的默认行为是默认不递归地包含它们。
主要缺点是由于必须在每个子模块(以及它们各自的子模块)中递归,可能会带来时间开销。
如果您有很多,并且不需要 all,最好不要选择该选项,并在需要时指定
--recursive
。
然而,一个优点是避免在切换分支时看到“未跟踪的文件”,如本讨论中所示。
警告,从 Git 2.34(2021 年第 4 季度)开始,如果配置
git clone --recurse-submodules
设置为 true,则 git pull
意味着简单的 submodule.stickyRecursiveClone
将递归到子模块中。
即使
git config --global submodule.recurse
未 设置。
参见“有没有办法让
git pull
自动更新子模块?”。
最近我回到
recurse=false
有两个原因:
recurse=false
似乎已经缓解了这个问题,但再次强调:我没有充分调查问题。事情是这样的:人们倾向于采用默认值,除非他们的工作流程无法正确运行,而 Git 的复杂性是恕我直言完全,因为它支持的工作流程多样性。
您的工作流程将会有很大的不同,具体取决于您是否在供应商基础上携带补丁(这也取决于补丁是否在您的顶级存储库或一个或多个子模块中)、您尝试对代码执行的操作(开发新功能?测试升级?只是简单的获取和构建?),项目的设置方式(构建每个配置总是需要所有子模块吗?将可选功能分成单独的历史记录可以得到回报伟大的),一切。
因此,调用与您正在使用的工作流程匹配或不匹配的默认值是一个“缺点”,在我看来,只见树木不见森林。 无论工厂默认设置如何设置,由于 Git 提供的工作流程种类繁多,它们可能至少在某些存储库中对于您的工作流程来说不是最佳的。使默认值适合您,其他人会出现询问为什么他们默认以递归方式获取所有内容。
我可以明确指出将自动递归设置为默认值的唯一缺点是:鉴于任何人都在猜测该设置是否与任何特定存储库中的工作流程相匹配,并且工厂默认值必须是猜测,所以情况更糟猜测更昂贵的选择。
为您的所有工作打开自动递归配置很容易,但如果您不必这样做,您可能会浪费大量时间进行克隆,而您根本不知道根本不需要这样做。大型共享供应商历史记录的本地前端或参考库很容易。
当克隆或拉取包含子模块的存储库时 默认情况下不会检出子模块;您可以指示克隆 递归到子模块。 git 的 init 和 update 子命令 子模块将维护子模块签出并在适当的时候 工作树中的修订。或者你可以设置 submodule.recurse 将签出递归到子模块中。
来源:git-scm.com
此选项的缺点是克隆或拉取包含多个子模块的存储库会降低性能。
好吧,即使提交哈希值已经匹配,它似乎也会连接并获取子模块,这是不必要的。 所以这有点糟糕。
除此之外应该没问题,因为一切都是由提交固定的。