拉取后,我想用一个命令递归地初始化所有新的子模块。使用git submodule update --init --recursive的问题是,它还重置了我预先存在的子模块所指向的提交。
git submodule update --init --recursive
p8h8hvxi1#
现在你完全改变了你的问题,你问(强调我的):拉取后,我想用一个命令递归地初始化所有new子模块。使用git submodule update --init --recursive的问题是,它还重置了我的预先存在的子模块所指向的提交。为了只初始化新的子模块,你首先需要找出是否有任何新的子模块是由你所做的git pull带来的。下面的内容应该列出了自从你在pull(ORIG_HEAD..)之前提交以来已经添加的子模块(grep 160000):
git 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
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 --merge或git submodule update --init --recursive --rebase可能会满足你的需求。
git add
git submodule update --init --recursive --merge
git submodule update --init --recursive --rebase
juzqafwq2#
git submodule update --init --recursive确实是递归初始化所有子模块的正确命令。子模块存储库将被克隆,超级项目中记录的提交将被检出。这在git-submodule(1)中有正确的记录:通过克隆丢失的子模块,获取子模块中丢失的提交并更新子模块的工作树,更新已注册的子模块以匹配超级项目所期望的内容。根据命令行选项和submodule.<name>.update配置变量的值,可以通过多种方式进行“更新”。命令行选项优先于配置变量。如果两者都没有给出,执行checkout。[…]
git-submodule(1)
submodule.<name>.update
checkout:记录在超级项目中的提交将在分离的HEAD上的子模块中检出。
checkout
[...]如果子模块尚未初始化,而您只想使用存储在.gitmodules中的设置,则可以使用--init选项自动初始化子模块。如果指定了--recursive,则此命令将递归到已注册的子模块中,并更新其中的任何嵌套子模块。请注意,您可以通过简单地使用git clone --recurse-submodules来获得相同的行为。
.gitmodules
--init
--recursive
git clone --recurse-submodules
wqnecbli3#
这是一条非常不寻常的路径,我认为你必须编写脚本。几乎所有的Git命令都是以脚本开始的,现在仍然可以这样做。如果您总是保持所有子模块都处于活动状态,那么git submodule foreach --recursive就是您的起点,但是如果您选择检出哪些子模块,那么您将不得不做更多的事情,而不仅仅是
git submodule foreach --recursive
git submodule foreach --recursive -q 'echo git -C $PWD checkout `git rev-parse @`'
字符串(这实际上是git submodule文档中的一个示例),并运行打印的 checkout ,以在递归更新做得太多之后恢复您关心的内容。
git submodule
3条答案
按热度按时间p8h8hvxi1#
现在你完全改变了你的问题,你问(强调我的):
拉取后,我想用一个命令递归地初始化所有new子模块。
使用
git submodule update --init --recursive
的问题是,它还重置了我的预先存在的子模块所指向的提交。为了只初始化新的子模块,你首先需要找出是否有任何新的子模块是由你所做的
git pull
带来的。下面的内容应该列出了自从你在pull(ORIG_HEAD..
)之前提交以来已经添加的子模块(grep 160000
):字符串
然后,您可以使用
git submodule update
和以下子模块列表来仅初始化这些子模块:型
请注意,从您的问题中并不清楚预先存在的子模块处于什么状态,您希望避免更改这些子模块。它们是“修改”的吗(即,您在子模块中检出了不同的提交,但尚未在超级项目中运行
git add
),“added”(即,您在子模块中检出了不同的提交,在超级项目中运行了git add
,但尚未在超级项目中提交该更改),或者相反,如果您的工作目录完全干净,但是你在上次pull后确实提交了子模块的更改。根据这一点以及你想要的最终结果,简单地运行git submodule update --init --recursive --merge
或git submodule update --init --recursive --rebase
可能会满足你的需求。juzqafwq2#
git submodule update --init --recursive
确实是递归初始化所有子模块的正确命令。子模块存储库将被克隆,超级项目中记录的提交将被检出。这在
git-submodule(1)
中有正确的记录:通过克隆丢失的子模块,获取子模块中丢失的提交并更新子模块的工作树,更新已注册的子模块以匹配超级项目所期望的内容。根据命令行选项和
submodule.<name>.update
配置变量的值,可以通过多种方式进行“更新”。命令行选项优先于配置变量。如果两者都没有给出,执行checkout。[…]checkout
:记录在超级项目中的提交将在分离的HEAD上的子模块中检出。[...]
如果子模块尚未初始化,而您只想使用存储在
.gitmodules
中的设置,则可以使用--init
选项自动初始化子模块。如果指定了
--recursive
,则此命令将递归到已注册的子模块中,并更新其中的任何嵌套子模块。请注意,您可以通过简单地使用
git clone --recurse-submodules
来获得相同的行为。wqnecbli3#
这是一条非常不寻常的路径,我认为你必须编写脚本。几乎所有的Git命令都是以脚本开始的,现在仍然可以这样做。
如果您总是保持所有子模块都处于活动状态,那么
git submodule foreach --recursive
就是您的起点,但是如果您选择检出哪些子模块,那么您将不得不做更多的事情,而不仅仅是字符串
(这实际上是
git submodule
文档中的一个示例),并运行打印的 checkout ,以在递归更新做得太多之后恢复您关心的内容。