【问题标题】:Automatic initialization and update of submodules in MakefileMakefile中子模块的自动初始化和更新
【发布时间】:2018-09-14 17:51:17
【问题描述】:

我有一个包含几个子模块的 git 项目(回想起来我有点后悔的选择)。它使用 gnu make

目前,我希望人们在首次构建项目之前以及在拉取更新子模块引用的任何更改之后手动发布git submodule update --init1

但是,我希望 Makefile 在需要时自动发出这些命令。如果他们有时在不需要的时候发出命令(虚假更新),这没关系 - 但它不应该经常发生。

对于最初的init,似乎有一个规则就足够了(对于位于目录module1中的子模块:

module1/.git:
    git submodule update --init

这里选择.git 作为“表示”子模块的文件是相当随意的,它可以是其他文件。

但是,当引用已更新时,更新子模块的效果并不好。我想我可以使子模块依赖于根 .gitmodules 文件,我猜想在更新子模块引用时应该更改它,例如:

module1/.git: .gitmodules
    git submodule update --init

这里使用.git 似乎是错误的:大概在运行update 时不一定会直接更新(特别是如果没有对此特定子模块进行更新),这将使更新命令运行每个时间。

在这里寻找更清洁的解决方案。


1 或者可能在初始clone 上使用--recursive 参数,效果相同。

【问题讨论】:

  • 您可以使用.git/modules/module1/HEAD 作为更新“module1”的先决条件。或者使用git submodule status 创建要更新的子模块列表(或者您也可以创建一个只更新更改子模块的makefile)。
  • 如果我使用.git/modules/module1/HEAD 作为前置要求,那么目标是什么(可能是模块内部的东西)?
  • 嗯.. 好问题。首先,我假设可以使用 module1/.git,但这不起作用。而且我不觉得使用 git 内部结构是个好主意。
  • @Kuchara 在下面的回答有效,但是有一些哲学上的东西。您已经发现 git 子模块是对自然的犯罪和对人类的侮辱。考虑替代方案。我还告诫不要将您的 Makefile 与您的工作副本混为一谈。这就像在捉鬼敢死队中穿越溪流——你想把这些问题分开。 Makefile 源,不要让它操纵源。考虑让您的持续集成系统根据需要处理克隆存储库。最后,我推荐 Kuchera 的解决方案,但让他们指导他们进行初始化。
  • 或者你的意思是 CI 基本上可以在某处克隆外部项目,然后以主项目无需使用 submodule 即可使用的方式注入它们?

标签: git makefile gnu-make git-submodules


【解决方案1】:

我制作了这样的东西:

.PHONY: check-and-reinit-submodules
check-and-reinit-submodules:
    @if git submodule status | egrep -q '^[-]|^[+]' ; then \
            echo "INFO: Need to reinitialize git submodules"; \
            git submodule update --init; \
    fi

它使用git submodule status 来确定子模块是否未初始化(开头为-)或以某种方式修改/过时(开头为+)。这个 make 目标会一直运行,但 git submodule update --init 只会在需要时运行。

【讨论】:

  • 请注意,您还需要将 check-and-reinit-submodules 添加到所有目标依赖项。喜欢:所有:check-and-reinit-submodules ....
  • ...或添加另一层makefile(覆盖makefile 将调用check-and-reinit-submodules,并运行真正的makefile)。然后根本不需要修改构建系统的makefile(覆盖的makefile可以作为make -f other-makefile运行)。
【解决方案2】:

您可以在更新子模块之前生成一个文件:

all: .gitmodules_updated my-target

.gitmodules_updated : .gitmodules 
     touch .gitmodules_updated
     git submodule update --init

如果 .gitmodules 更新,它会比 .gitmodules_updated 更新,因此子模块也会更新。

【讨论】:

  • 这不起作用,因为.gitmodules 仅在添加或删除模块时更新,而不是在与 gitmodule 关联的提交更改时更新。
猜你喜欢
  • 2011-03-21
  • 1970-01-01
  • 2011-07-02
  • 2012-01-06
  • 2013-06-30
  • 1970-01-01
  • 2011-02-14
  • 2013-04-14
  • 1970-01-01
相关资源
最近更新 更多