我有一个包含几个子模块的 git 项目(现在回想起来我有点后悔这个选择)。它使用 gnu
make
目前,我希望人们在第一次构建项目之前以及在更新子模块引用的任何更改之后手动发出
git submodule update --init
1。
但是,我希望 Makefile 在需要时自动发出这些命令。如果他们有时在不需要时发出命令(虚假更新),那没关系 - 但它不应该经常发生。
对于最初的
init
,有一个类似的规则似乎就足够了(对于位于目录module1
中的子模块:
module1/.git:
git submodule update --init
这里选择
.git
作为“代表”子模块的文件是相当任意的,它可以是其他文件。
但是,当引用已更新时,这对于更新子模块来说效果不佳。我想我可以使子模块依赖于根
.gitmodules
文件,我想当子模块引用更新时应该更改该文件,例如:
module1/.git: .gitmodules
git submodule update --init
这里使用
.git
似乎是错误的:大概当 update
运行时不一定会直接更新(特别是如果这个特定子模块没有更新),这将使更新命令每次都运行。
在这里寻找更清洁的解决方案。
1 或者可以在初始
--recursive
上使用 clone
参数,这具有相同的效果。
我制作了这样的东西:
.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
仅在需要时运行。
您可以在更新子模块之前生成一个文件:
all: .gitmodules_updated my-target
.gitmodules_updated : .gitmodules
touch .gitmodules_updated
git submodule update --init
如果 .gitmodules 更新,它会比 .gitmodules_updated 更新,因此子模块也会更新。