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。)