'git submodule update'与进入git子模块目录之间有什么区别(如果有的话),并且每个目录都执行'git pull'?
由于
答案 0 :(得分:4)
是的区别。此外,我还要注意,我刻意避免使用子模块(又名sobmodules,理由很充分:它们让用户非常伤心,或者感到沮丧,或两者兼而有之。)
区分" main"或"超级项目"和每个子模块",让我们调用顶级超级项目。子项目,子模块或子存储库都只是" sub-repos"当我们将它们作为存储库使用时。
超级项目是一个普通的Git存储库。它像往常一样有分支,并且在分支上提交(并且可选地在分支上提交不,等等)。对于每个子模块,它还有一些记录的信息:
前两项存储在.gitmodules
中,这是超级项目工作树顶部的普通文件,格式为git config
文件(如$HOME/.gitconfig
和{ {1}})。 .git/config
文件还可以包含每个子模块的附加信息,但前两项是必需的。
第三项 - 提交ID - 作为" gitlink"类型的文件存储在存储库中。当您更改哪个提交将用于特定子模块时,这是更新的文件。
为了便于说明,我们假设超级项目在路径.gitmodules
和libbig
下有两个子模块libsmall
和libs/big
。因此,您的{{1>} 路径为libs/small
和.gitmodules
。 网址可以是任何内容,具体取决于libs/big
和libs/small
的上游存储库的位置。
与此同时,Git将在您的超级项目中录制一个"文件"名为libbig
,其内容为libsmall
或其他内容,另一个"文件"名为libs/big
,其内容是另一个丑陋的SHA-1哈希。
当您克隆并检出超级项目时,您没有子模块'存储库,您只需要1a987f1356...
文件和存储的提交ID。使用libs/small
会将存储库克隆到适当的目录中。然后,它将检查由gitlink条目识别的特定提交。
这会将每个子仓库放入"分离的HEAD"状态。
(即使对于所有较新的"分支"模式,情况似乎也是如此,尽管我还没有对此进行过实验。)
.gitmodules
= git submodule update
+ git pull
正在运行git fetch
只运行一个有限的git something
,然后是另一个Git命令:git pull
或git 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
步骤让你手动完成)。