差异b / w'git submodule update'和'git pull'

时间:2016-06-29 20:37:06

标签: git

'git submodule update'与进入git子模块目录之间有什么区别(如果有的话),并且每个目录都执行'git pull'?

由于

1 个答案:

答案 0 :(得分:4)

的区别。此外,我还要注意,我刻意避免使用子模块(又名sobmodules,理由很充分:它们让用户非常伤心,或者感到沮丧,或两者兼而有之。)

子模块是一个单独的Git仓库

区分" main"或"超级项目"和每个子模块",让我们调用顶级超级项目。子项目,子模块或子存储库都只是" sub-repos"当我们将它们作为存储库使用时。

超级项目是一个普通的Git存储库。它像往常一样有分支,并且在分支上提交(并且可选地在分支上提交,等等)。对于每个子模块,它还有一些记录的信息:

  • 子模块库的URL
  • 子模块存储库的路径
  • 子模块的提交ID

前两项存储在.gitmodules中,这是超级项目工作树顶部的普通文件,格式为git config文件(如$HOME/.gitconfig和{ {1}})。 .git/config文件还可以包含每个子模块的附加信息,但前两项是必需的。

第三项 - 提交ID - 作为" gitlink"类型的文件存储在存储库中。当您更改哪个提交将用于特定子模块时,这是更新的文件。

为了便于说明,我们假设超级项目在路径.gitmoduleslibbig下有两个子模块libsmalllibs/big。因此,您的{{1>} 路径libs/small.gitmodules网址可以是任何内容,具体取决于libs/biglibs/small的上游存储库的位置。

与此同时,Git将在您的超级项目中录制一个"文件"名为libbig,其内容为libsmall或其他内容,另一个"文件"名为libs/big,其内容是另一个丑陋的SHA-1哈希。

将每个子模块放入"分离的HEAD"状态

当您克隆并检出超级项目时,您没有子模块'存储库,您只需要1a987f1356...文件和存储的提交ID。使用libs/small会将存储库克隆到适当的目录中。然后,它将检查由gitlink条目识别的特定提交

这会将每个子仓库放入"分离的HEAD"状态。

(即使对于所有较新的"分支"模式,情况似乎也是如此,尽管我还没有对此进行过实验。)

.gitmodules = git submodule update + git pull

正在运行git fetch只运行一个有限的git something,然后是另一个Git命令:git pullgit fetch。哪个远程用于获取步骤,哪个分支用于merge-or-rebase步骤,由您当前的分支控制。这两个设置'值组合起来构成当前分支的上游设置:如果当前分支为git merge,则上游为git rebase,其中$branch为输出时的任何内容您运行$remote/$merge$remote是您运行git config --get branch.$branch.remote时获得的输出。

由于您的子仓库处于"分离的HEAD"国家,它的当前分支"是"没有分支",也称为特殊的匿名分支。根据定义,它既没有远程也没有合并设置。 $merge命令都将失败。

获取步骤仍然有效,因为Git默认从git config --get branch.$branch.merge获取。但是,合并或重组步骤必须失败。因此git config --get不会做得很好。

origin完全做了其他事情

它的确具有高度可配置性,因此see the documentation。通常,如果未配置,它只进行任何必要的初始化。并且,一般情况下,它不会将子模块放在分支上:即使它根据分支名称更新子模块,它仍然会将它留在"分离的HEAD"状态。

小结

子模块背后的一般思想是你不关心分支,只关注原始的commit-ID。每个子模块都说明了来自此特定存储库的特定提交 ",其中提交ID记录在" gitlink&#34中;超级项目中的条目,子仓库的URL记录在超级项目的git pull文件中。因此,提交ID和URL包含在超级项目的提交中:通过gitlink"文件"的ID,以及通过git submodule update文件的URL。

要将某个子模块指向不同的提交ID,您只需(hah)检查子模块中的新ID,然后进入超级项目并且" git add"新ID进入相应的gitlink。使用.gitmodules为您完成第二步。您可以轻松地手动执行第二步(除非它是,或者至少曾经,非常容易错误地操作,因为文件名完成留下了&# 34; /"在路径中)。一旦你更新了所有的子模块,你就可以" git commit"在超级项目中进行新提交的结果,记录新的gitlink哈希值。

.gitmodules为你做的所有烦恼都是为了完成上述两个步骤(让git submodule add步骤让你手动完成)。