git Git子模块更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1979167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Git submodule update
提问by deepblue
I'm not clear on what the following means (from the Git submodule updatedocumentation):
我不清楚以下是什么意思(来自Git 子模块更新文档):
...will make the submodules HEAD be detached, unless
--rebase
or--merge
is specified...
...将使子模块 HEAD 被分离,除非
--rebase
或--merge
被指定...
How does --rebase
/--merge
change things?
--rebase
/如何--merge
改变事情?
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?
- 在这些子模块中,我可以像在常规存储库中一样创建分支/修改并使用推/拉,还是需要谨慎?
- 我如何将子模块引用的提交从 say (tagged) 1.0 推进到 1.1(即使原始存储库的头部已经是 2.0),或者选择使用哪个分支的提交?
回答by VonC
This GitPro pagedoes summarize the consequence of a git submodule update nicely
这个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.
当您运行时
git submodule update
,它会检出项目的特定版本,而不是在一个分支内。这称为具有分离的头——这意味着 HEAD 文件直接指向提交,而不是符号引用。
问题是您通常不想在独立的头部环境中工作,因为很容易丢失更改。
如果您进行初始子模块更新,请在该子模块目录中提交而不创建要工作的分支,然后从超级项目再次运行 git submodule update 而不在此期间提交,Git 将覆盖您的更改而不告诉您。从技术上讲,您不会丢失工作,但是您不会有指向它的分支,因此检索起来会有些困难。
Note March 2013:
2013 年 3 月注意:
As mentioned in "git submodule tracking latest", a submodule now (git1.8.2) can track a branch.
正如“ 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
See "git submodule update --remote
vs git pull
".
见“git submodule update --remote
对git pull
”。
MindTooth's answerillustrate a manual update (without local configuration):
git submodule -q foreach git pull -q origin master
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.
在这两种情况下,这都会更改子模块引用(gitlink,父存储库索引中的特殊条目),您需要从主存储库添加、提交和推送所述引用。
下次您将克隆该父存储库时,它将填充子模块以反映那些新的 SHA1 引用。
The rest of this answer details the classic submodule feature (reference to a fixedcommit, which is the all point behind the notion of a submodule).
这个答案的其余部分详细介绍了经典的子模块功能(参考固定提交,这是子模块概念背后的全部要点)。
To avoid this issue, create a branch when you work in a submodule directory with git checkout -b work or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to.
Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory:
为避免此问题,请在使用 git checkout -b work 或等效命令在子模块目录中工作时创建一个分支。当您第二次更新子模块时,它仍然会恢复您的工作,但至少您有一个可以返回的指针。
切换包含子模块的分支也很棘手。如果您创建一个新分支,在那里添加一个子模块,然后切换回没有该子模块的分支,您仍然将子模块目录作为未跟踪目录:
So, to answer your questions:
所以,回答你的问题:
can I create branches/modifications and use push/pull just like I would in regular repos, or are there things to be cautious about?
我可以像在常规存储库中一样创建分支/修改并使用推/拉,或者有什么需要谨慎的地方吗?
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.
警告(来自Git 子模块教程):在将更改发布(推送)到引用它的超级项目之前,始终发布(推送)子模块更改。如果您忘记发布子模块更改,其他人将无法克隆存储库。
how would I advance the submodule referenced commit from say (tagged) 1.0 to 1.1 (even though the head of the original repo is already at 2.0)
我将如何将子模块引用的提交从 say (tagged) 1.0 推进到 1.1(即使原始 repo 的头部已经是 2.0)
The page "Understanding Submodules" can help
“理解子模块”页面可以提供帮助
Git submodules are implemented using two moving parts:
- the
.gitmodules
file and- a special kind of tree object.
Git 子模块使用两个移动部分实现:
- 该
.gitmodules
文件- 一种特殊的树对象。
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
you cannot modify the contents of the submodule from within the main project
您不能从主项目中修改子模块的内容
100% correct: you cannot modify a submodule, only refer to one of its commits.
100% 正确:您不能修改子模块,只能参考其提交之一。
This is why, when you do modify a submodule from within the main project, you:
这就是为什么当您从主项目中修改子模块时,您:
- need to commit and push withinthe submodule (to the upstream module), and
- then go up in your main project, and re-commit (in order for that main project to refer to the new submodule commit you just created and pushed)
- 需要在子模块内提交和推送(到上游模块),以及
- 然后进入您的主项目,并重新提交(以便该主项目引用您刚刚创建和推送的新子模块提交)
A submodule enables you to have a component-based approachdevelopment, where the main project only refers to specific commits of other components (here "other Git repositories declared as sub-modules").
子模块使您能够进行基于 组件的方法开发,其中主项目仅引用其他组件的特定提交(此处“其他 Git 存储库声明为子模块”)。
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.
子模块是另一个 Git 存储库的标记(提交),它不受主项目开发周期的约束:它(“另一个”Git 存储库)可以独立发展。
由主项目从其他存储库中选择它需要的任何提交。
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 firstpublish those submodule modifications to its original Git repo, and thencommit your main project refering to a newversion of said submodule.
但是,为了方便起见,如果您想直接从主项目修改这些子模块之一,Git 允许您这样做,前提是您首先将这些子模块修改发布到其原始 Git 存储库,然后提交您的主项目参考所述子模块的新版本。
But the main idea remains: referencing specific components which:
但主要思想仍然是:引用特定组件,其中:
- have their own lifecycle
- have their own set of tags
- have their own development
- 有自己的生命周期
- 有自己的一套标签
- 有自己的发展
The list of specific commits you are refering to in your main project defines your configuration(this is what ConfigurationManagement is all about, englobing mere Version Control System)
您在主项目中引用的特定提交列表定义了您的配置(这就是配置管理的全部内容,仅包含版本控制系统)
If a component could really be developed at the same timeas 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.
如果一个组件真的可以和你的主项目同时开发(因为对主项目的任何修改都会涉及修改子目录,反之亦然),那么它就不再是一个“子模块”,而是一个子树合并(也出现在将遗留代码库从 cvs 转移到分布式存储库的问题中),将两个 Git存储库的历史链接在一起。
Does that help understanding the true nature of Git Submodules?
这是否有助于理解 Git 子模块的真实性质?
回答by MindTooth
To update each submodule, you could invoke the following command (at the root of the repository):
要更新每个子模块,您可以调用以下命令(在存储库的根目录):
git submodule -q foreach git pull -q origin master
You can remove the -qoption to follow the whole process.
您可以删除-q选项以遵循整个过程。
回答by robinspb
To address the --rebase
vs. --merge
option:
要解决--rebase
vs.--merge
选项:
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
假设您有超级存储库 A 和子模块 B,并且想在子模块 B 中做一些工作。您已经完成了功课并且在调用后知道
git submodule update
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
您处于无 HEAD 状态,因此您此时所做的任何提交都很难恢复。所以,你已经开始在子模块 B 中的一个新分支上工作
cd B
git checkout -b bestIdeaForBEver
<do work>
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.
同时,项目 A 中的其他人认为 B 的最新和最好版本确实是 A 应得的。您出于习惯,将最近的更改合并并更新您的子模块。
<in A>
git merge develop
git submodule update
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:
哦不!您又回到了无头状态,可能是因为 B 现在指向与 B 的新提示或其他一些提交相关联的 SHA。如果你有:
git merge develop
git submodule update --rebase
Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437.
Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437'
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!
现在 B 有史以来最好的想法已经重新基于新的提交,更重要的是,您仍然在 B 的开发分支上,而不是处于无头状态!
(The --merge
will merge changes from beforeUpdateSHA to afterUpdateSHA into your working branch, as opposed to rebasing your changes onto afterUpdateSHA.)
(这--merge
会将更改从 beforeUpdateSHA 到 afterUpdateSHA 合并到您的工作分支中,而不是将您的更改重新设置到 afterUpdateSHA 上。)
回答by Iulian Onofrei
Git 1.8.2 features a new option ,--remote
, that will enable exactly this behavior. Running
Git 1.8.2 具有一个新选项 , --remote
,它将启用此行为。跑步
git submodule update --rebase --remote
will fetch the latest changes from upstream in each submodule, rebase them, and check out the latest revision of the submodule. As the documentationputs it:
将从每个子模块的上游获取最新更改,重新设置它们,并检查子模块的最新版本。正如文档所说:
--remote
This option is only valid for the update command. Instead of using the superproject's recorded SHA-1 to update the submodule, use the status of the submodule's remote-tracking branch.
- 偏僻的
此选项仅对更新命令有效。不要使用超级项目记录的 SHA-1 来更新子模块,而是使用子模块的远程跟踪分支的状态。
This is equivalent to running git pull
in each submodule, which is generally exactly what you want.
这相当于git pull
在每个子模块中运行,这通常正是您想要的。
(This was copied from this answer.)
(这是从这个答案复制的。)