这个GitPro页面确实很好地总结了git子模块更新的结果
运行时git submodule update
,它将签出项目的特定版本,但不在分支中。这被称为具有分离的头部-这意味着HEAD文件直接指向提交,而不是符号引用。
问题是您通常不希望在独立的头部环境中工作,因为它很容易丢失更改。
如果执行初始子模块更新,则在不创建要使用的分支的情况下提交该子模块目录,然后在不提交的情况下再次从超级项目运行git子模块更新,而Git会在不通知您的情况下覆盖您的更改。从技术上讲,您不会丢失工作,但不会有指向它的分支,因此检索起来有些困难。
注意: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 submodule update --remote
vsgit pull
”。
MindTooth的答案说明了手动更新(无本地配置):
git submodule -q foreach git pull -q origin master
在这两种情况下,这都会更改子模块引用(gitlink,父回购索引中的特殊条目),并且您将需要从主回购中添加,提交和推送所述引用。
下次克隆该父存储库时,它将填充子模块以反映那些新的SHA1引用。
该答案的其余部分详细介绍了经典的子模块功能(对固定提交的引用,这是子模块概念背后的全部内容)。
为避免此问题,请在使用git checkout -b work或类似功能的子模块目录中工作时创建一个分支。当您第二次更新子模块时,它仍将还原您的工作,但是至少您有一个指针可以返回。
切换其中具有子模块的分支也很棘手。如果您创建一个新分支,在其中添加一个子模块,然后切换回没有该子模块的分支,则您仍将子模块目录作为未跟踪目录:
因此,回答您的问题:
是否可以像在常规存储库中一样创建分支/修改并使用推/拉,还是需要谨慎?
您可以创建分支并推送修改。
警告(来自Git Submodule Tutorial):始终发布(推送)子模块更改,然后再发布(推送)更改到引用它的超级项目。如果您忘记发布子模块更改,则其他人将无法克隆存储库。
我如何将子模块引用的提交从(标记)1.0提升到1.1(即使原始存储库的头部已经是2.0)
“ 了解子模块 ” 页面可以提供帮助
Git子模块使用两个移动部分来实现:
- 该
.gitmodules
文件和
- 一种特殊的树对象。
这些一起对特定存储库的特定修订版进行了三角划分,并检出到项目中的特定位置。
从git子模块页面
您不能从主项目中修改子模块的内容
100%正确:您不能修改子模块,只能引用其提交之一。
这就是为什么当您从主项目中修改子模块时,您:
- 需要在子模块内提交并推送(到上游模块),并且
- 然后进入您的主项目,然后重新提交(以使该主项目引用您刚刚创建并推送的新子模块提交)
子模块使您能够进行基于 组件的方法开发,其中主项目仅引用其他组件的特定提交(此处称为“其他Git存储库声明为子模块”)。
子模块是另一个Git存储库的标记(提交),它不受主项目开发周期的约束:它(“其他” Git存储库)可以独立发展。
由主项目决定是否需要从其他仓库中选择任何提交。
但是,如果您出于方便目的直接从主项目中修改其中一个子模块,则Git允许您这样做,前提是您首先将这些子模块的修改发布到其原始Git存储库中,然后再提交与所述子模块的新版本。
但是主要思想仍然是:引用特定的组件,这些组件:
您在主项目中引用的特定提交列表定义了您的配置(这是Configuration Management的全部内容,仅包含Version Control System)
如果某个组件确实可以与您的主项目同时开发(因为对主项目的任何修改都涉及修改子目录,反之亦然),那么它就不再是“子模块”,而是子树合并(也在将遗留代码库从CVS转移到分布式存储库中出现)中,将两个Git 存储库的历史链接在一起。
这是否有助于理解Git子模块的真实本质?