这个GitPro页面很好地总结了git子模块更新的结果
When you run git submodule update, it checks out the specific version of the project, but not within a branch. This is called having a detached head — it means the HEAD file points directly to a commit, not to a symbolic reference.
The issue is that you generally don’t want to work in a detached head environment, because it’s easy to lose changes.
If you do an initial submodule update, commit in that submodule directory without creating a branch to work in, and then run git submodule update again from the superproject without committing in the meantime, Git will overwrite your changes without telling you. Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve.
2013年3月:
正如在“git子模块跟踪最新”中提到的,现在一个子模块(git1.8.2)可以跟踪一个分支。
# add submodule to track master branch
git submodule add -b master [URL to Git repo];
# update your submodule
git submodule update --remote
# or (with rebase)
git submodule update --rebase --remote
参见“git子模块更新—远程vs git pull”。
MindTooth的回答说明了手动更新(不需要本地配置):
git submodule -q foreach git pull -q origin master
在这两种情况下,这将改变子模块的引用(gitlink,父repo索引中的一个特殊条目),你将需要从主repo中添加、提交和推送这些引用。
下次克隆父repo时,它将填充子模块以反映那些新的SHA1引用。
这个答案的其余部分详细介绍了经典的子模块特性(引用固定提交,这是子模块概念背后的全部要点)。
为了避免这个问题,当你在子模块目录下工作时,使用git checkout -b work或类似的东西创建一个分支。当您第二次更新子模块时,它仍然会恢复您的工作,但至少您有一个指针可以返回。
切换带有子模块的分支也很棘手。如果你创建了一个新分支,在那里添加了一个子模块,然后切换回一个没有该子模块的分支,你仍然有子模块目录作为未跟踪目录:
我来回答你的问题:
我是否可以创建分支/修改,并像在常规回购中那样使用推/拉,或者有什么需要谨慎的地方?
您可以创建一个分支并推送修改。
警告(来自Git子模块教程):总是在发布(推送)子模块的变更到引用它的超项目之前发布(推送)子模块的变更。如果您忘记发布子模块更改,其他人将无法克隆存储库。
我如何将子模块引用提交从say (tagged) 1.0推进到1.1(即使原始回购的头已经在2.0)
“理解子模块”页面可以提供帮助
Git子模块使用两个移动部分实现:
.gitmodules文件和
一种特殊的树对象。
这些组合在一起对特定存储库的特定修订进行三角定位,该存储库被检出到项目中的特定位置。
从git子模块页面
不能在主项目内修改子模块的内容
100%正确:你不能修改子模块,只能引用它的一个提交。
这就是为什么,当你在主项目中修改子模块时,你:
需要在子模块内提交和推送(到上游模块),以及
然后转到你的主项目,重新提交(为了让主项目引用你刚刚创建和推送的新子模块commit)
子模块使您能够使用基于组件的方法进行开发,其中主项目只引用其他组件的特定提交(这里“其他Git存储库声明为子模块”)。
子模块是一个标记(提交)到另一个Git存储库,它不受主项目开发周期的约束:它(“其他”Git回购)可以独立发展。
这取决于主项目从另一个回购中选择它需要的任何提交。
但是,如果你想,出于方便,直接从你的主项目中修改这些子模块,Git允许你这样做,前提是你先将这些子模块的修改发布到它原来的Git repo中,然后提交你的主项目,引用该子模块的新版本。
但主要思想仍然是:引用特定的组件:
有自己的生命周期
有自己的一套标签吗
有自己的发展
你在主项目中引用的特定提交列表定义了你的配置(这就是配置管理的全部内容,包括版本控制系统)
如果一个组件真的可以与主项目同时开发(因为对主项目的任何修改都会涉及修改子目录,反之亦然),那么它将不再是一个“子模块”,而是一个子树合并(在将遗留代码库从cvs转移到分布式存储库的问题中也有介绍),将两个Git repo的历史链接在一起。
这有助于理解Git子模块的本质吗?