dee*_*lue 233 git git-submodules
我不清楚以下是什么意思(来自git submodule update docs):
...将使子模块HEAD分离,除非
--rebase
或--merge
指定...
怎么--rebase
/ --merge
改变事情?
我的主要用例是有一堆中央存储库,我将通过子模块嵌入到其他存储库中.我希望能够改进这些中央回购,直接在他们的原始位置,或从他们的嵌入回购(通过子模块使用它们的那些).
Von*_*onC 295
这个GitPro页面确实很好地总结了git子模块更新的结果
运行时
git submodule update
,它会检出项目的特定版本,但不会检出分支.这称为具有分离的头 - 这意味着HEAD文件直接指向提交,而不是指向符号引用.
问题在于,您通常不希望在分离的头部环境中工作,因为很容易丢失更改.
如果您执行初始子模块更新,请在该子模块目录中提交而不创建要运行的分支,然后再从超级项目再次运行git子模块更新而不提交,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
Run Code Online (Sandbox Code Playgroud)
见" git submodule update --remote
vsgit pull
".
git submodule -q foreach git pull -q origin master
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,这将改变子模块引用(gitlink,父repo索引中的特殊条目),并且您将需要添加,提交和推送来自主 repo的所述引用.
下次您将克隆该父repo时,它将填充子模块以反映这些新的SHA1引用.
本答案的其余部分详细介绍了经典的子模块功能(引用固定提交,这是子模块概念背后的所有要点).
要避免此问题,请在使用git checkout -b work或等效工作的子模块目录中创建分支.当您第二次执行子模块更新时,它仍将恢复您的工作,但至少您有一个指针可以返回.
切换带有子模块的分支也很棘手.如果您创建一个新分支,在那里添加一个子模块,然后切换回没有该子模块的分支,您仍然将子模块目录作为未跟踪的目录:
那么,回答你的问题:
我可以创建分支/修改并使用推/拉,就像我在常规回购中一样,或者有什么需要谨慎的吗?
您可以创建分支并推送修改.
警告(来自Git子模块教程):在将更改发布(推送)到引用它的超级项目之前,始终发布(推送)子模块更改.如果您忘记发布子模块更改,则其他人将无法克隆存储库.
我如何将子模块引用的提交从say(tagged)1.0推进到1.1(即使原始repo的头部已经是2.0)
" 了解子模块 " 页面可以提供帮助
Git子模块使用两个移动部件实现:
- 该
.gitmodules
文件- 一种特殊的树对象.
这些一起对特定存储库的特定修订进行三角测量,该存储库被检出到项目中的特定位置.
您无法从主项目中修改子模块的内容
100%正确:您无法修改子模块,只能参考其中一个提交.
这就是为什么当您从主项目中修改子模块时,您:
子模块使您可以进行基于 组件的方法开发,其中主项目仅引用其他组件的特定提交(此处"声明为子模块的其他Git存储库").
子模块是另一个Git存储库的标记(提交),它不受主项目开发周期的约束:它("其他"Git存储库)可以独立发展.
主要项目取决于其他任何需要提交的回购.
但是,如果您想方便地直接从主项目修改其中一个子模块,Git允许您这样做,前提是您首先将这些子模块修改发布到其原始Git仓库,然后提交您的主项目引用所述子模块的新版本.
但主要的想法仍然是:引用以下特定组件:
您在主项目中引用的特定提交列表定义了您的配置(这就是Configuration Management的全部内容,仅仅是版本控制系统)
如果一个组件真的可以与你的主项目同时开发(因为对主项目的任何修改都涉及修改子目录,反之亦然),那么它将不再是一个"子模块",而是一个子树合并(也在将遗留代码库从cvs转移到分布式存储库的问题中提出),将两个Git 仓库的历史链接在一起.
这有助于理解Git子模块的真实性质吗?
Min*_*oth 132
要更新每个子模块,可以调用以下命令.(根据回购.)
git submodule -q foreach git pull -q origin master
Run Code Online (Sandbox Code Playgroud)
您可以删除-q选项以遵循整个过程.
rob*_*spb 19
要解决--rebase vs --merge选项:
假设您有超级回购A和子模块B,并希望在子模块B中做一些工作.您已完成作业并且在调用后知道
--rebase
你处于无HEAD状态,所以你在这一点上所做的任何提交很难回复.所以,你已经开始在子模块B中的新分支上工作了
cd B
git checkout -b bestIdeaForBEver
<do work>
Run Code Online (Sandbox Code Playgroud)
与此同时,项目A中的其他人已经确定最新和最好的B版本确实是应得的.出于习惯,您可以合并最近的更改并更新子模块.
<in A>
git merge develop
git submodule update
Run Code Online (Sandbox Code Playgroud)
哦,不!你又回到了无头状态,可能是因为B现在指向与B的新提示或其他提交相关联的SHA.如果只有你:
git merge develop
git submodule update --rebase
Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437.
Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437'
Run Code Online (Sandbox Code Playgroud)
现在,B的最佳创意已经重新定位到新的提交,更重要的是,你仍然在B的开发分支,而不是无头状态!
(--merge会将来自beforeUpdateSHA的更改合并到afterUpdateSHA到您的工作分支,而不是将更改重新定义到afterUpdateSHA.)
Git 1.8.2提供了一个新选项--remote
,可以实现这种行为.运行
git submodule update --rebase --remote
Run Code Online (Sandbox Code Playgroud)
将从每个子模块的上游获取最新的更改,将它们重新绑定,并检查子模块的最新版本.正如文档所说:
- 远程
此选项仅对update命令有效.不使用超级项目记录的SHA-1来更新子模块,而是使用子模块的远程跟踪分支的状态.
这相当于git pull
在每个子模块中运行,这通常正是您想要的.
(从这个答案复制)
归档时间: |
|
查看次数: |
232830 次 |
最近记录: |