我有以下项目结构:
root-project
|
|-- A
| |
| |-- C
|
|-- B
A和B是根项目的子模块。C又是一个子模块假设我对项目A、B和C进行了更改承诺对相应的指数进行这些更改。之后我更新根项目中对A和B的引用,并提交该更改也当我使用选项推送根项目的更改时--recurse submodules=按需,git推送项目A的所有提交,B和根项目,但静默地忽略项目C。我希望它也能推动项目C的变化。
我知道我可以通过在根项目文件夹中使用以下两个命令来解决这个问题。
git submodule foreach --recursive 'git push origin master'
git push
有人能澄清一下我是否做错了什么,或者这是git推送中的一个错误吗?我已经在git邮件列表上问过这个问题,但没有收到任何回复:http://thread.gmane.org/gmane.comp.version-control.git/266184
我还编写了一个小型shell脚本,用于设置所描述的项目结构并执行递归推送操作:https://gist.github.com/usommerl/6e8defcba94bd4ba1438
git 2.3.3版
git push --recurse-submodules=on-demand
将使用git 2.14.x/2.15(2017年第三季度)进行真正的递归,但有一些条件。
参见Brandon Williams(mbrandonw
)提交的c7be720(2017年7月20日)
(由Junio C Hamano合并——gitster
——提交49794d,2017年8月22日)
子模块--helper:教推送检查处理HEAD
在06bf4ad(
push
:传播远程和refspec--递归子模块,git 2.13.0)push被教导如何在给定"--recurse-submodules
"标志时将refspec向下传播到子模块。允许传播的仅限的refspec是命名存在于超级项目和子模块中的ref的refspec,但需要注意的是不允许使用"HEAD"。
此补丁教导推送检查(子模块助手,用于确定refspec可以传播到子模块),以允许传播"
HEAD
"当且仅当:
- 超级项目和子模块都有相同的已签出命名分支,并且
- 子模块不处于分离的头部状态
我自己的答案的副本
如果您有包含子模块的子模块,则命令git push --recurse-submodules=on-demand
不起作用。(git
版本:2.20.1)
在~/.gitconfig
文件中添加以下别名:
[alias]
push-all = "! find . -depth -name .git -exec dirname {} \; 2> /dev/null | sort -n -r | xargs -I{} bash -c "cd {}; git status | grep ahead > /dev/null && { echo '* Pushing: {}'; git push; }""
然后在父git文件夹中发出git push-all
。
解释
!
:我们正在发出一个非git命令find . -depth -name .git -exec dirname {} \; 2> /dev/null
:查找所有子模块(和git存储库,这不会造成危害)| sort -n -r
:按路径深度排序,最深的将排在第一位| xargs -I{} bash -c "
:将目录传递给以下命令:cd {};
:cd
到目标目录git status | grep ahead > /dev/null
:测试是否需要推送此存储库&& { echo '* Pushing: {}'; git push; }""
:通知并推送