git 如何在拉取后初始化新的子模块而不影响预先存在的子模块?

qni6mghb  于 2023-11-15  发布在  Git
关注(0)|答案(3)|浏览(135)

拉取后,我想用一个命令递归地初始化所有新的子模块。
使用git submodule update --init --recursive的问题是,它还重置了我预先存在的子模块所指向的提交。

p8h8hvxi

p8h8hvxi1#

现在你完全改变了你的问题,你问(强调我的):
拉取后,我想用一个命令递归地初始化所有new子模块。
使用git submodule update --init --recursive的问题是,它还重置了我的预先存在的子模块所指向的提交。
为了只初始化新的子模块,你首先需要找出是否有任何新的子模块是由你所做的git pull带来的。下面的内容应该列出了自从你在pull(ORIG_HEAD..)之前提交以来已经添加的子模块(grep 160000):

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),“added”(即,您在子模块中检出了不同的提交,在超级项目中运行了git add,但尚未在超级项目中提交该更改),或者相反,如果您的工作目录完全干净,但是你在上次pull后确实提交了子模块的更改。根据这一点以及你想要的最终结果,简单地运行git submodule update --init --recursive --mergegit submodule update --init --recursive --rebase可能会满足你的需求。

juzqafwq

juzqafwq2#

git submodule update --init --recursive确实是递归初始化所有子模块的正确命令。子模块存储库将被克隆,超级项目中记录的提交将被检出。
这在git-submodule(1)中有正确的记录:
通过克隆丢失的子模块,获取子模块中丢失的提交并更新子模块的工作树,更新已注册的子模块以匹配超级项目所期望的内容。根据命令行选项和submodule.<name>.update配置变量的值,可以通过多种方式进行“更新”。命令行选项优先于配置变量。如果两者都没有给出,执行checkout。[…]

checkout:记录在超级项目中的提交将在分离的HEAD上的子模块中检出。

[...]
如果子模块尚未初始化,而您只想使用存储在.gitmodules中的设置,则可以使用--init选项自动初始化子模块。
如果指定了--recursive,则此命令将递归到已注册的子模块中,并更新其中的任何嵌套子模块。
请注意,您可以通过简单地使用git clone --recurse-submodules来获得相同的行为。

wqnecbli

wqnecbli3#

这是一条非常不寻常的路径,我认为你必须编写脚本。几乎所有的Git命令都是以脚本开始的,现在仍然可以这样做。
如果您总是保持所有子模块都处于活动状态,那么git submodule foreach --recursive就是您的起点,但是如果您选择检出哪些子模块,那么您将不得不做更多的事情,而不仅仅是

git submodule foreach --recursive -q 'echo git -C $PWD checkout `git rev-parse @`'

字符串
(这实际上是git submodule文档中的一个示例),并运行打印的 checkout ,以在递归更新做得太多之后恢复您关心的内容。

相关问题