使用Git子模块创建多个远程分支

3

我第一次使用Git子模块,正在努力理解如何创建跨所有仓库的分支并将它们添加到所有远程仓库中。

目前我的文件结构如下:

-parent_repo
  |
  |_ submodule_1
  |_ submodule_2
  |_ submodule_3
  |_ submodule_4
  |_ submodule_5
  |_ submodule_6
  |_ submodule_7

如果我在父仓库上创建一个分支:
(master) $ git checkout -b feature/my_feature
(feature/my_feature) $ git commit -m "created my_feature"
(feature/my_feature) $ git push -u origin feature/my_feature

我希望创建一个跨越所有子模块和父模块的分支。之后,将所有分支推送到每个子模块和它们各自的存储库中。尝试了以下步骤:
$ git submodule foreach -b branch_name
$ git push --recurse-submodules=on-demand
$ git submodule foreach "(git checkout branch_name; git pull)&"

...只是失败了。第一条命令未找到。

...如果我执行以下操作:

$ git config -f .gitmodules submodule.submodule_1.branch branch_name
$ git submodule update --remote

Git 返回:

fatal: Needed a single revision
Unable to find current origin/branch_name revision in submodule path 'submodule_1'

2
git submodule foreach -b branch_name should be git submodule foreach 'git checkout -b branch_name' - Marina Liu
Git 2.36(2022 年第一季度):git -c submodule.propagateBranches=true branch --recurse-submodules topic origin/main。请参见下面的答案 - VonC
2个回答

8

请参考子模块小贴士

假设我们要开始一个新的功能或修复一个bug,而且在多个子模块中都有工作进行。
我们可以轻松地将所有子模块中的工作暂存起来:

$ git submodule foreach 'git stash'
Entering 'CryptoLibrary'
No local changes to save
Entering 'DbConnector'
Saved working directory and index state WIP on stable: 82d2ad3 Merge from origin/stable
HEAD is now at 82d2ad3 Merge from origin/stable

然后,我们可以在所有的子模块中创建一个新的分支并切换到它:
$ git submodule foreach 'git checkout -b featureA'
Entering 'CryptoLibrary'
Switched to a new branch 'featureA'
Entering 'DbConnector'
Switched to a new branch 'featureA'

接下来,您仍需要在父存储库中创建相同的分支,添加、提交和推送,因为所有子模块存储库都将发生更改。

但请记住:这些是不同的分支(即使它们具有相同的名称),每个分支特定于其自己的存储库(无论是父存储库还是子模块存储库)。


一旦我按照你上面提到的方法创建并检出一个分支,它是有效的。你是否熟悉如何在不进入每个repo并创建远程分支的情况下,在所有repo中都能够使用push -u origin featureA?类似于 $ git submodule foreach 'git push -u origin featureA'。由于子模块是使用对存储库的http引用而不是ssh创建的,因此会提示我输入凭据。 - Josh
@Josh 你可以在一个子模块中尝试这个方法,并且一劳永逸地缓存这些凭据:请参考 https://dev59.com/4WYr5IYBdhLWcg3wy9KA#13386417 的开头部分。 - VonC

1
我想创建一个跨越所有子模块包括父模块的分支。
这将在 Git 2.36 中得到正式支持(首先以实验模式)(2022年第二季度)。
git branch手册 学习了 --recurse-submodules 选项。

请查看 提交 09e0be1 (2022年1月31日),作者为Junio C Hamano(gitster)
请查看提交 679e369, 提交 961b130, 提交 6e0a2ca, 提交 3f3e760, 提交 bc0893c, 提交 e89f151 (2022年1月28日),作者为Glen Choo (chooglen)
(由Junio C Hamano--gitster --提交 5cc9522中合并,日期为2022年2月18日)

branch:添加--recurse-submodules选项以创建分支

协助者:Jonathan Tan
签名者:Glen Choo
审阅者:Jonathan Tan

为了改善子模块的用户体验,我们希望教 Git 如何处理子模块的分支。从通过向 "git branch"(man) 添加 --recurse-submodules 选项开始这个过程,这样 git branch --recurse-submodules(man) 主题将在超级项目和其子模块中创建 topic 分支。
虽然此提交不会引入破坏性更改,但它与现有的 --recurse-submodule 命令不兼容,因为 "git branch --recurse-submodules" 写入子模块 ref 存储,但大多数命令仅考虑超级项目 gitlink,并"忽略"子模块 ref 存储。
例如,"git checkout --recurse-submodules"(man) 将检出超级项目的提交 gitlinks(并将子模块放在游离状态下)而不是检出子模块分支。
因此,此提交引入了一个新的配置值: submodule.propagateBranches。计划是,如果该值为 true,则 Git 命令将优先考虑子模块 ref 存储的信息而不是超级项目 gitlinks
由于 "git branch --recurse-submodules" 写入子模块 ref 存储,为了清晰起见,除非设置了此配置值,否则其将不起作用。
此提交还包括一些更改,以支持从超级项目提交中处理子模块,因为 "branch --recurse-submodules"(以及未来的命令)需要从超级项目提交读取 .gitmodulesgitlinks,但通常从文件系统的 .gitmodules 和索引的 gitlinks 中读取子模块。
这些更改包括:
  • 添加一个 submodules_of_tree() 帮助程序,提供树内子模块的相关信息(例如路径和 oid),并初始化存储库
  • 通过向 is_submodule_active() 添加一个 treeish_name 参数,添加 is_tree_submodule_active()
  • 添加 "submoduleNotUpdated" 建议,建议用户更新其树中的子模块
顺便修复了一个不正确的用法字符串,该字符串将 git branch 的“list”用法(-l)与“create”用法组合在一起;自其创建以来,这个字符串就不正确了a8dfd5e(“使 builtin-branch.c 使用 parse_options。”,2007年10月07日,Git v1.5.4-rc0 -- merge)。

git config现在在其手册页面中包含以下内容:

submodulesNotUpdated

当用户运行子模块命令失败时,显示建议,因为未运行git submodule update --init

git config现在在其手册页面中包含以下内容:

submodule.recurse:

一个布尔值,指示命令是否应默认启用--recurse-submodules选项。
默认为false。

当设置为true时,可以通过--no-recurse-submodules选项来停用它。请注意,一些缺少此选项的Git命令可能会调用受submodule.recurse影响的上述某些命令;例如,git remote update将调用git fetch,但没有--no-recurse-submodules选项。对于这些命令,解决方法是使用git -c submodule.recurse=0临时更改配置值。

以下列表显示接受--recurse-submodules的命令以及它们是否受此设置支持。

  • checkoutfetchgreppullpushread-treeresetrestoreswitch始终受支持。
  • clonels-files不受支持。
  • branch仅在启用submodule.propagateBranches时受支持。

submodule.propagateBranches

[实验性]一个布尔值,启用分支支持,当使用--recurse-submodulessubmodule.recurse=true时。 启用此功能将允许某些命令接受--recurse-submodules,并且某些已经接受--recurse-submodules的命令现在将考虑分支。

git branch 现在在其手册页面中包含以下内容:

'git branch' [--track[=(direct|inherit)] | --no-track] [-f]
[--recurse-submodules] <branchname> [<start-point>]

git branch 现在在其手册页面中包含以下内容:

--recurse-submodules

此选项为实验性功能!如果启用了submodule.propagateBranches,则会导致当前命令递归到子模块中。请参见git config中的submodule.propagateBranches
目前,仅支持分支创建。

在分支创建时,在超级项目中将创建一个新的分支<branchname>,并且所有超级项目中的子模块都将被包含在内。

在子模块中,该分支将指向超级项目中<start-point>的子模块提交,但是该分支的跟踪信息将基于子模块的分支和远程设置,例如git branch --recurse-submodules topic origin/main将创建指向超级项目中的子模块提交的子模块分支“topic”,但跟踪子模块的“origin/main”。


在 Git 2.40(2023 年第一季度)中,当 "git branch --recurse-submodules"(man) 失败时,将改进给出的建议信息。

请查看 提交 97cf0c7(2023年1月16日),作者为Philippe Blain (phil-blain)
(由Junio C Hamano -- gitster --合并于提交 7d4d34f,2023年1月27日)

分支:当--recurse-submodules失败时改进建议

签名:Philippe Blain
审核者:Glen Choo

'git branch --recurse-submodules'(man) 如果在“from-here”中存在任何未克隆的子模块(在submodule.propagateBranches=true下),则会失败。 我们给出以下建议: 你可以尝试使用“git checkout from-here && git submodule update --init”更新子模块 如果设置了“submodule.recurse”,则从-here 'git checkout'(man) 也会失败,因为它将尝试递归检出子模块。 通过向checkout命令添加“--no-recurse-submodules”来改进建议。

您可以尝试使用 'git checkout --no-recurse-submodules %s && git submodule update --init' 命令来更新子模块


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接