git子模块更新
我不清楚以下的意思(从git子模块更新文档):
…将使子模块HEAD被分离,除非
--rebase
或--merge
被指定…
--rebase
/ --merge
如何改变事物?
我的主要用例是有一堆中央回购,我将通过submodulesembedded到其他回购。 我希望能够直接在原来的位置,或者从embedded式回收站(通过子模块使用回收站)来改进这些中央回购站。
在这些子模块中,我可以创build分支/修改,并像使用常规回购一样使用推/拉,或者有些事情需要谨慎?
我将如何提高子模块引用提交从说(标记)1.0到1.1(即使原始回购的头已经在2.0),或select使用哪些分支提交?
这个GitPro页面很好地总结了git子模块更新的结果
当你运行
git submodule update
,它会检出项目的特定版本,但不在分支中。 这被称为具有分离头 – 这意味着HEAD文件直接指向一个提交,而不是一个符号引用。
问题是你一般不想在一个独立的头脑中工作,因为很容易失去改变 。
如果您执行初始子模块更新,则在该子模块目录中提交而不创build要工作的分支,然后在超级项目中再次运行git submodule update,同时不提交,Git将在不通知您的情况下覆盖您的更改。 从技术上说,你不会失去工作,但你不会有一个分支指向它,所以检索会有些困难。
2013年3月注释:
正如在“ git submodule tracking latest ”中提到的,现在子模块(git1.8.2)可以跟踪一个分支。
这个答案的其余部分详细介绍了经典的子模块function(参考一个固定的提交)。
为了避免这个问题,当你在一个使用git checkout -b工作的子模块目录或类似的东西上工作时创build一个分支。 当您再次执行子模块更新时,它仍会恢复您的工作,但至less您有一个返回的指针。
在子模块中切换分支也很麻烦。 如果你创build一个新的分支,在那里添加一个子模块,然后切换回没有子模块的分支,你仍然把子模块目录作为一个未被跟踪的目录:
所以,要回答你的问题:
我是否可以创build分支/修改,并像使用常规回购一样使用推/拉,还是有需要谨慎的事情?
您可以创build一个分支并推送修改。
警告(从Git子模块教程 ):在发布(推)更改到引用它的超级项目之前,始终发布(推送)子模块更改。 如果您忘记发布子模块更改,其他人将无法克隆存储库。
我将如何提高子模块引用提交从说(标记)1.0到1.1(即使原始回购的头已经在2.0)
“ 了解子模块 ”页面可以提供帮助
Git子模块使用两个移动部分来实现:
.gitmodules
文件和- 一种特殊的树木对象。
这些一起三angular化一个特定的版本库的特定版本,这是检出到您的项目中的特定位置。
从git子模块页面
您不能从主项目中修改子模块的内容
100%正确:你不能修改一个子模块,只能引用其中的一个提交。
这就是为什么当您在主项目中修改子模块时,您:
- 需要在子模块(到上游模块)中提交和推送,并且
- 然后在你的主项目中上去,然后重新提交(为了使主项目引用刚创build和推送的新子模块提交)
子模块使您可以进行基于组件的方法开发,其中主项目仅指其他组件的特定提交(这里是“声明为子模块的其他Git存储库”)。
子模块是一个标记(提交)到另一个不受主项目开发周期约束的Git仓库:它(“其他”Git仓库)可以独立进化。
无论提交什么需求,从其他回购中select主要项目。
但是,如果您想方便地直接从主项目中修改其中一个子模块,Git允许您这样做,只要您首先将这些子模块修改发布到其原始Git仓库中, 然后提交主项目即可所述子模块的新版本。
但主要想法仍然是:引用具体的组件:
- 有自己的生命周期
- 有自己的一套标签
- 有自己的发展
您在主项目中引用的特定提交列表定义了您的configuration (这就是configurationpipe理的全部内容,包括版本控制系统 )
如果一个组件可以和你的主项目同时开发(因为主项目的任何修改都会涉及到修改子目录,反之亦然),那么它将不再是一个“子模块”,而是一个子树合并(也在问题中提出, 将遗留代码库从CVS传输到分布式存储库 ),将两个Git回购的历史链接在一起。
这有助于理解Git子模块的真实性质吗?
要更新每个子模块,可以调用以下命令。 (在回购的根源。)
git submodule -q foreach git pull -q origin master
您可以删除-q选项来遵循整个过程。
要解决–rebase vs –merge选项:
假设您有超级回购A和子模块B,并且希望在子模块B中做一些工作。您已经完成了作业,并且知道在调用
git submodule update
你处于一个无头的状态,所以你在这一点上做的任何提交都很难回到。 所以,你已经开始在子模块B的新分支上工作了
cd B git checkout -b bestIdeaForBEver <do work>
与此同时,项目A中的其他人已经决定B的最新版本是A应得的。 你,习惯,合并最近的变化,并更新你的子模块。
<in A> git merge develop git submodule update
哦,不! 您又回到了无头的状态,可能是因为B现在指向与B的新提示相关的SHA或其他提交。 如果只有你有:
git merge develop git submodule update --rebase Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437. Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437'
现在,对于B来说,最好的想法已经重新投入到新的承诺中,更重要的是,你仍然在B的开发部门,而不是处于无头的状态!
(–merge会将beforeUpdateSHA到afterUpdateSHA的变化合并到您的工作分支中,而不是将更改重新分配到afterUpdateSHA。)