拉取后,我想用一个命令递归地初始化所有新的子模块。
使用
git submodule update --init --recursive
的问题是它还会重置我预先存在的子模块指向的提交。
现在你完全改变了你的问题并且你在问(强调我的):
拉动后,我想用一个命令递归地初始化所有new子模块。
使用
的问题是它还会重置我的预先存在的子模块所指向的提交。git submodule update --init --recursive
要仅初始化新的子模块,您首先必须找出您所做的
git pull
是否带来了任何新的子模块。类似下面的内容应该列出自拉取之前的提交以来已添加的子模块 (grep 160000
) (--diff-filter=A
) (ORIG_HEAD..
):
git log --format=%h ORIG_HEAD.. --summary --diff-filter=A | \grep 160000 | awk '{print $4}'
然后您可以将
git submodule update
与此子模块列表一起使用以仅初始化这些子模块:
git submodule update --init --recursive $(git log --format=%h ORIG_HEAD.. --summary --diff-filter=A | \grep 160000 | awk '{print $4}' | tr \\n ' ')
请注意,从您的问题中不清楚您想要避免更改的预先存在的子模块处于什么状态。它们是否被“修改”(即您在子模块中签出了不同的提交,但尚未在超级项目中运行
git add
)、“添加”(即您在子模块中签出了不同的提交,在中运行了 git add
)超级项目,但尚未在超级项目中提交该更改)或者相反,如果您的工作目录完全干净,但自上次拉取以来您确实提交了子模块更改。根据这一点以及您想要的最终结果,只需运行 git submodule update --init --recursive --merge
或 git submodule update --init --recursive --rebase
可能会满足您的需求...
git submodule update --init --recursive
确实是用于递归初始化所有子模块的正确命令。子模块存储库将被克隆,并且超级项目中记录的提交将被检出。
git-submodule(1)
中正确记录:
通过克隆缺失的子模块、获取子模块中缺失的提交以及更新子模块的工作树来更新注册的子模块以匹配超级项目的期望。 “更新”可以通过多种方式完成,具体取决于命令行选项和
配置变量的值。命令行选项优先于配置变量。如果两者都没有给出,则执行 checkout。 [...]submodule.<name>.update
: 超级项目中记录的提交将在分离的 HEAD 上的子模块中检出。checkout
[...]
如果子模块尚未初始化,而您只想使用
中存储的设置,则可以使用.gitmodules
选项自动初始化子模块。--init
如果指定了
,此命令将递归到已注册的子模块,并更新其中的任何嵌套子模块。--recursive
请注意,只需使用
git clone --recurse-submodules
即可获得相同的行为。
这离人迹罕至的地方太远了,我认为你必须编写脚本。几乎所有 Git 命令都是以脚本形式开始的,并且仍然可以通过这种方式完成。
如果您始终保持所有子模块处于活动状态,那么
git submodule foreach --recursive
就是您的起点,但如果您有选择性地签出哪些子模块,您将需要做的不仅仅是
git submodule foreach --recursive -q 'echo git -C $PWD checkout `git rev-parse @`'
(这实际上是
git submodule
文档中的一个示例)并运行打印的结帐,以在递归更新执行过多操作后恢复您关心的内容。