Git 子模块更新
我不清楚以下含义(来自 Git 子模块更新 文档):
...将使子模块 HEAD 分离,除非指定
--rebase
或--merge
...
--rebase
是如何实现的/--merge
改变什么?
我的主要用例是拥有一堆中央存储库,我将通过子模块将它们嵌入到其他存储库中。我希望能够改进这些中央存储库,无论是直接在它们的原始位置,还是在它们的嵌入存储库(通过子模块使用它们的存储库)中。
- 在这些子模块中,我可以像在常规存储库中一样创建分支/修改并使用推/拉,还是有什么需要注意的?
- 我如何将子模块引用的提交从(标记的)1.0 推进到 1.1(即使原始存储库的头部已经是 2.0),或者选择使用哪个分支的提交?
I'm not clear on what the following means (from the Git submodule update documentation):
...will make the submodules HEAD be detached, unless
--rebase
or--merge
is specified...
How does --rebase
/--merge
change things?
My main use case is to have a bunch of central repositories, which I will embed via submodules into other repositories. I would like to be able to improve on these central repositories, either directly in their original location, or from within their embedding repositories (the ones that use them via submodule).
- From within these submodules, can I create branches/modifications and use push/pull just like I would in regular repositories, or are there things to be cautious about?
- How would I advance the submodule referenced commit from say (tagged) 1.0 to 1.1 (even though the head of the original repository is already at 2.0), or pick which branch's commit is used at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这个 GitPro 页面 确实很好地总结了 git 子模块更新的结果
注意 2013 年 3 月:
正如“git 子模块跟踪最新”中提到的,现在的子模块 (git1.8.2) 可以跟踪分支。
请参阅“
git submodule update --remote
与git pull
” 。MindTooth的答案 说明手动更新(无需本地配置):
在这两种情况下,这都会更改子模块引用(gitlink,父存储库索引中的特殊条目),您需要添加、提交和推送来自主存储库的引用。
下次您克隆该父存储库时,它将填充子模块以反映这些新的 SHA1 引用。
这个答案的其余部分详细介绍了经典的子模块功能(参考固定提交,这是子模块概念背后的全部要点)。
因此,回答您的问题:
您可以创建分支并推送修改。
警告(来自 Git 子模块教程):始终在发布(推送)之前发布(推送)子模块更改对引用它的超级项目的更改。如果您忘记发布子模块更改,其他人将无法克隆存储库。
页面“了解子模块" 可以提供帮助
它们一起对特定存储库的特定修订进行三角测量,该修订被检出到项目中的特定位置。
来自 git 子模块页面
100% 正确地修改子模块的内容:您无法修改子模块,只能引用其提交之一。
这就是为什么,当您从主项目中修改子模块时,您:
子模块使您能够拥有基于组件的方法开发,其中主项目仅引用其他组件的特定提交(此处“声明为子项目的其他 Git 存储库”) -模块”)。
子模块是另一个 Git 存储库的标记(提交),该存储库不受主项目开发周期的约束:它(“其他”Git 存储库)可以独立发展。
由主项目从其他存储库中选择它需要的任何提交。
但是,如果您出于方便想要直接从主项目修改其中一个子模块,Git 允许您这样做,前提是首先< /em> 将这些子模块修改发布到其原始 Git 存储库,然后提交引用所述子模块的新版本的主项目。
但主要思想仍然是:引用特定组件,这些组件:
在主项目中引用的特定提交列表定义了您的 配置 (这就是配置管理的全部内容,仅包含版本控制系统)
如果一个组件真的可以与您的主项目同时开发(因为对主项目的任何修改都将涉及修改子目录,反之亦然),那么它将不再是一个“子模块”,而是一个子树合并(也出现在问题 将遗留代码库从 cvs 传输到分布式存储库),链接两者的历史Git 存储库在一起。
这有助于理解 Git 子模块的真正本质吗?
This GitPro page does summarize the consequence of a git submodule update nicely
Note March 2013:
As mentioned in "git submodule tracking latest", a submodule now (git1.8.2) can track a branch.
See "
git submodule update --remote
vsgit pull
".MindTooth's answer illustrate a manual update (without local configuration):
In both cases, that will change the submodules references (the gitlink, a special entry in the parent repo index), and you will need to add, commit and push said references from the main repo.
Next time you will clone that parent repo, it will populate the submodules to reflect those new SHA1 references.
The rest of this answer details the classic submodule feature (reference to a fixed commit, which is the all point behind the notion of a submodule).
So, to answer your questions:
You can create a branch and push modifications.
WARNING (from Git Submodule Tutorial): Always publish (push) the submodule change before publishing (push) the change to the superproject that references it. If you forget to publish the submodule change, others won't be able to clone the repository.
The page "Understanding Submodules" can help
These together triangulate a specific revision of a specific repository which is checked out into a specific location in your project.
From the git submodule page
100% correct: you cannot modify a submodule, only refer to one of its commits.
This is why, when you do modify a submodule from within the main project, you:
A submodule enables you to have a component-based approach development, where the main project only refers to specific commits of other components (here "other Git repositories declared as sub-modules").
A submodule is a marker (commit) to another Git repository which is not bound by the main project development cycle: it (the "other" Git repo) can evolves independently.
It is up to the main project to pick from that other repo whatever commit it needs.
However, should you want to, out of convenience, modify one of those submodules directly from your main project, Git allows you to do that, provided you first publish those submodule modifications to its original Git repo, and then commit your main project refering to a new version of said submodule.
But the main idea remains: referencing specific components which:
The list of specific commits you are refering to in your main project defines your configuration (this is what Configuration Management is all about, englobing mere Version Control System)
If a component could really be developed at the same time as your main project (because any modification on the main project would involve modifying the sub-directory, and vice-versa), then it would be a "submodule" no more, but a subtree merge (also presented in the question Transferring legacy code base from cvs to distributed repository), linking the history of the two Git repo together.
Does that help understanding the true nature of Git Submodules?
要更新每个子模块,您可以调用以下命令(在存储库的根目录下):
您可以删除 -q 选项来跟踪整个过程。
To update each submodule, you could invoke the following command (at the root of the repository):
You can remove the -q option to follow the whole process.
要解决
--rebase
与--merge
选项的问题:假设您有超级存储库 A 和子模块 B,并且想要在子模块 B 中执行一些工作。您已经完成你的作业并知道在调用
git submodule update
后你处于无头状态,因此你此时所做的任何提交都很难返回。因此,您已经开始在子模块 B 中开发一个新分支。
同时,项目 A 中的其他人已经决定 B 的最新、最好的版本确实是 A 所应得的。您出于习惯,合并最近的更改并更新您的子模块。
哦,不!您再次回到无头状态,可能是因为 B 现在指向与 B 的新提示或其他提交关联的 SHA。如果你有:
现在 B 的最佳想法已经重新基于新的提交,更重要的是,你仍然在 B 的开发分支上,而不是处于无头状态!
(
--merge
会将 beforeUpdateSHA 到 afterUpdateSHA 的更改合并到您的工作分支中,而不是将更改重新调整到 afterUpdateSHA 上。)To address the
--rebase
vs.--merge
option:Let's say you have super repository A and submodule B and want to do some work in submodule B. You've done your homework and know that after calling
git submodule update
you are in a HEAD-less state, so any commits you do at this point are hard to get back to. So, you've started work on a new branch in submodule B
Meanwhile, someone else in project A has decided that the latest and greatest version of B is really what A deserves. You, out of habit, merge the most recent changes down and update your submodules.
Oh noes! You're back in a headless state again, probably because B is now pointing to the SHA associated with B's new tip, or some other commit. If only you had:
Now that best idea ever for B has been rebased onto the new commit, and more importantly, you are still on your development branch for B, not in a headless state!
(The
--merge
will merge changes from beforeUpdateSHA to afterUpdateSHA into your working branch, as opposed to rebasing your changes onto afterUpdateSHA.)Git 1.8.2 提供了一个新选项
--remote
,它可以实现这种行为。运行将从每个子模块的上游获取最新更改,重新设置它们,并检查子模块的最新版本。正如 文档 所说:
这相当于在每个子模块中运行 git pull ,这通常正是您想要的。
(这是从这个答案复制的。)
Git 1.8.2 features a new option ,
--remote
, that will enable exactly this behavior. Runningwill fetch the latest changes from upstream in each submodule, rebase them, and check out the latest revision of the submodule. As the documentation puts it:
This is equivalent to running
git pull
in each submodule, which is generally exactly what you want.(This was copied from this answer.)