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