Git 子模块推送

如果我修改一个子模块,我是否可以将提交推回到子模块原点,还是需要一个克隆? 如果是克隆,我可以将克隆存储在另一个存储库中吗?

152806 次浏览

子模块只不过是另一个回购中的 git 回购的克隆,其中包含一些额外的元数据(gitlink 树条目,。Gitmodule 文件)

$ cd your_submodule
$ git checkout master
<hack,edit>
$ git commit -a -m "commit in submodule"
$ git push
$ cd ..
$ git add your_submodule
$ git commit -m "Updated submodule"

注意,自从 git1.7.11(Git 1.7.11. rc1释放通知书,2012年6月)提到:

git push --recurse-submodules”学会了可选地查看与超级项目绑定的子模块的历史并将其推出。

可能在 这个补丁--on-demand选项之后完成:

recurse-submodules=<check|on-demand>::

确保要推送的修订所使用的所有子模块提交都可以在远程跟踪分支上获得。

  • 如果使用 check,将检查所有在要推送的修订中更改的子模块提交是否在远程上可用。
    否则推送将中止,并以非零状态退出。
  • 如果使用 on-demand,将推送修订中更改的所有子模块。
    如果随需应变不能推动所有必要的修订,它也将中止,退出与非零状态。

所以你可以用(来自父回购) a 一次性完成所有事情:

git push --recurse-submodules=on-demand

此选项仅适用于一级嵌套。不会推送对另一个子模块内部的子模块的更改。


对于 git 2.7(2016年1月) ,一个简单的 git 推就足以推动父回购... 和 所有的子模块。

参见 麦克 · 克罗(mikecrowe)提交 d34141c提交 f5c7cd9(2015年12月3日) ,提交 f5c7cd9(2015年12月3日)和 提交 b33a15b(2015年11月17日)。
(由 朱尼奥 · C · 哈马诺 gitster于2015年12月21日在 提交5d35d72合并)

push: 添加 recurseSubmodules配置选项

--recurse-submodules命令行参数已经存在了一些 但是它没有等效的配置文件。

按照 git fetch对应参数的样式,让我们 发明 push.recurseSubmodules以提供此参数的默认值。
这还需要将 --recurse-submodules=no添加到 允许在命令行上重写配置 需要。

实现这一点的最直接方法似乎是 pushsubmodule-config中使用与 fetch类似的代码。

返回文章页面 git config文档现在包括:

返回文章页面

确保要推送的修订所使用的所有子模块提交都在远程跟踪分支上可用。

  • 如果值是“ check”,那么 Git 将验证在要推送的修订中更改的所有子模块提交在子模块的至少一个远程上都是可用的。如果缺少任何提交,则推送将中止,并以非零状态退出。
  • 如果值是“ on-demand”,那么所有在修订中改变的子模块将被推送。如果随需应变不能推动所有必要的修订,它也将中止,退出与非零状态。-
  • 如果值是“ no”,则保留推送时忽略子模块的默认行为。

您可以通过指定“ --recurse-submodules=check|on-demand|no”在推送时覆盖此配置。

所以:

git config push.recurseSubmodules on-demand
git push

Git 2.12(Q12017)

git push --dry-run --recurse-submodules=on-demand实际上可以工作。

提交0301c82提交1aa7365(2016年11月17日) by 布兰登 · 威廉姆斯(mbrandonw)
(由 朱尼奥 · C · 哈马诺 gitster于2016年12月16日在 提交12cf113合并)

当 push 配置为 push 子模块时,push run with --dry-run实际上并不执行演练(2016年12月2.11日及之前的 Git) 随叫随到。
相反,所有需要推送的子模块实际上都被推送到它们的远程,而超级项目的任何更新都作为一个模拟运行执行。
这是一个错误,而不是预期的演习行为。

教导 push在配置为递归按需推送子模块时尊重 --dry-run选项。
这是通过将 --dry-run标志传递给子进程来完成的,子进程在执行模拟运行时对子模块执行推送操作。


在 Git 2.12中,您现在有了一个“ --recurse-submodules=only”选项 推出子模块,而不用推动顶级的超级项目

犯罪现场调查,第225季,第8集提交6c656c3犯下罪行(2016年12月19日) by 布兰登 · 威廉姆斯(mbrandonw)
(由 朱尼奥 · C · 哈马诺 gitster于2017年1月31日在 犯罪心理,第二季,第22集合并)


对于 Git 2.36(Q22022) ,“ git fetch --negotiate-only(< a href = “ https://git-scm.com/docs/git-get # Documents/git-fetch.txt-——Talk-only”rel = “ nofollow noReferrer”> man )git push(< a href = “ https://git-scm.com/docs/git-push # Documents/git-push.txt-to”rel = “ nofollow noReferrer”> man )使用的一个内部命令,用于找出我们的历史中缺少了哪一部分。
即使设置了 fetch.recursesubmodules配置变量,它也不应该递归到子模块中,也不应该触发“ gc”。
该代码已经被加强,以确保它只能进行公共祖先发现,而不能进行其他操作。

第386c076号提交135a12b犯罪(2022年1月18日) by Glen Choo (chooglen)
犯下罪行(2022年1月20日) by 滨野俊男(gitster)
(由 朱尼奥 · C · 哈马诺 gitster于2022年2月9日在 提交472a219合并)

不要更新子模块

签名: Glen Choo

git fetch --negotiate-only (< a href = “ https://git-scm.com/docs/git-get # Documents/git-fetch.txt-——Talk-only”rel = “ nofollow noReferrer”> man )是推式协商的实现细节,与大多数 git fetch(< a href = “ https://git-scm.com/docs/git-get”rel = “ nofollow norefrer”> man )调用不同,它实际上不更新主存储库。
因此,即使启用了子模块递归,它也不应该更新子模块。

这不仅是缓慢的,而且是错误的。例如,使用“ submodule.recurse=true”进行推送协商将导致子模块更新,因为它调用了 git fetch --negotiate-only

如果给定 --negotiate-only,通过禁用子模块递归来解决这个问题。
因为这使得 --negotiate-only--recurse-submodules不兼容,检查这个无效的组合和死亡。

fetch-options现在在其 手册中包括:

这与 --recurse-submodules=[yes|on-demand]不兼容。


使用 Git 2.39(Q42022) ,使用‘ --recurse-submodules=on-demand’递归地推送所有子模块。

提交 e62f779(2022年11月14日) by 谭(jhowtan)
(由 朱尼奥 · C · 哈马诺 gitster犯下173fc54合并,2022年11月23日)

Doc : 文件 push.recurseSubmodules=only

签名: Jonathan Tan
由 Taylor Blau 签名

Git 通过指定 --recurse-submodules=only6c656c3(“ submodules: add RECURSE_SUBMODULES_ONLY value”,2016-12-20,Git v2.12.0-rc0—— 第八批中列出的 合并)和 225e8bf(“ push: add option to push only submodule”,2016-12-20,Git v2.12.0-rc0—— 第八批中列出的 合并)的用户学会了在不推送超级项目的情况下推送子模块。
对于经常使用这个特性的用户,最好有一个等效的配置。

由于 --recurse-submodules=only特性的实现方式(用于解析 --recurse-submodules的函数被更新为只支持,但同样的函数也被用于解析 push.recurseSubmodules) ,因此这种配置(push.recurseSubmodules=only)已经得到支持,尽管在提交消息中既没有记录也没有提到它。
剩下的就是记录它并测试它,这就是这个提交要做的事情。

当递归到本身具有 push.recurseSubmodules=only配置的子模块时,可能会产生混淆,因为如果存储库只推送其子模块,而不推送其本身,则永远不能推送其超级项目。
因此,将这些配置视为“ on-demand”,并打印一条警告消息。

警告信息:

recursing into submodule with push.recurseSubmodules=only; using on-demand instead

git config现在在其 手册中包括:

可以是“ check”、“ on-demand”、“ only”或“ no”,具有相同的行为 作为“ push --recurse-submodules”。

git push现在在其 手册中包括:

当使用‘ on-demand’或‘ only’时,如果子模块具有 “ push.recurseSubmodules={on-demand,only}”或“ submodule.recurse”配置, 在这种情况下,“ only”被视为“ on-demand”。

你可以使用 对 git 的 foreach 命令

Bash 命令的例子:

git submodule foreach "git add . && git commit -m 'update' && git push"