git子模块更新

我不清楚以下的含义(从git子模块更新文档):

...将使子模块HEAD分离,除非指定了--rebase--merge ...

--rebase / --merge如何改变事物?

我的主要用例是有一堆中央仓库,我将通过子模块嵌入到其他仓库。 我希望能够直接在其原始位置或从其嵌入回购站(通过子模块使用它们)中改进这些中央回购站。

  • 从这些子模块内部,我可以创建分支/修改并像使用常规回购一样使用推/拉,还是需要谨慎处理?
  • 我如何将从say(标记)1.0到1.1的子模块引用提交(即使原始repo的头已经在2.0),或者选择使用哪个分支的提交?

  • 这个GitPro页面很好地总结了git子模块更新的结果

    当你运行git submodule update ,它会检出项目的特定版本,但不在分支中。 这被称为具有分离头 - 这意味着HEAD文件直接指向提交,而不是指向符号引用。
    问题在于,你通常不想在独立的头部环境中工作,因为很容易失去改变
    如果您执行初始子模块更新,则在该子模块目录中提交而不创建要工作的分支,然后在超级项目中再次运行git submodule update,而不在此期间提交,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
    

    请参阅“ git submodule update --remote vs git pull ”。

    MindTooth的答案说明了手动更新(没有本地配置):

    git submodule -q foreach git pull -q origin master
    

    在这两种情况下,这将改变子模块引用( gitlink ,父回购索引中的一个特殊条目),并且您需要添加,提交并从主回购库中推送所述引用。
    下一次您将克隆该父回购,它将填充子模块以反映这些新的SHA1引用。

    本答案的其余部分详细介绍了经典的子模块功能(引用了固定提交,这是子模块概念背后的重点)。


    为了避免这个问题,在你使用git checkout -b工作或类似的东西工作在子模块目录下时创建一个分支。 当您再次执行子模块更新时,它仍会恢复您的工作,但至少您有一个返回的指针。

    在子模块中切换分支也很麻烦。 如果您创建了一个新分支,请在其中添加一个子模块,然后切换回没有该子模块的分支,但您仍将子模块目录作为未跟踪目录:


    所以,要回答你的问题:

    我是否可以创建分支/修改,并像使用常规回购一样使用推/拉,还是需要谨慎对待?

    您可以创建分支并推送修改。

    警告(从Git子模块教程):在发布(推送)引用它的超级项目的更改之前,始终发布(推送)子模块更改。 如果您忘记发布子模块更改,其他人将无法克隆存储库。

    我将如何提升从say(标记)1.0到1.1的子模块引用提交(即使原始回购的头部已经在2.0)

    “了解子模块”页面可以提供帮助

    Git子模块使用两个移动部件实现:

  • .gitmodules文件和
  • 一种特殊的树形物体。
  • 它们一起对特定存储库的特定版本进行三角测量,并将其检出到项目中的特定位置。


    从git子模块页面

    您无法从主项目中修改子模块的内容

    100%正确:你不能修改一个子模块,只能参考它的一个提交。

    这就是为什么当您在主项目中修改子模块时,您:

  • 需要在子模块(到上游模块)中提交和推送,并且
  • 然后在你的主项目中继续,然后重新提交(为了使主项目引用刚才创建并推送的新子模块提交)
  • 子模块使您可以进行基于组件的方法开发,其中主项目仅指其他组件的特定提交(此处为“声明为子模块的其他Git存储库”)。

    子模块是一个标记(提交)到另一个不受主项目开发周期约束的Git仓库:它(“其他”Git仓库)可以独立进化。
    主要的项目是从其他回购中挑选它需要的任何提交。

    但是,如果您想出于方便 ,直接从您的主项目修改其中一个子模块,Git允许您这样做,只要您首先将这些子模块修改发布到其原始Git仓库,然后提交主项目引用所述子模块的新版本。

    但主要想法仍然是:引用特定的组件:

  • 有他们自己的生命周期
  • 有自己的一套标签
  • 有自己的发展
  • 您在主项目中引用的特定提交列表定义了您的配置 (这就是配置管理的全部内容,包括单纯的版本控制系统)

    如果一个组件可以与您的主项目同时开发(因为主项目的任何修改都会涉及修改子目录,反之亦然),那么它就不再是一个“子模块”,而是一个子树合并(也在问题中介绍,将遗留代码库从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。)

    链接地址: http://www.djcxy.com/p/16421.html

    上一篇: git submodule update

    下一篇: Authentication failed error when adding repository with SSH auth