23.2 克隆带子模组的版本库

    之前的表23-1在对比Subversion的svn:externals属性和Git子模组实现差异时,提到过克隆带子模组的Git库,并不能自动将子模组的版本库克隆出来。对于只关心项目本身的数据,而不关心项目引用的外部项目数据的用户,这个功能非常好,数据没有冗余而且克隆的速度也更快。

    下面在另外的位置克隆super版本库,会发现lib/lib_a和lib/lib_b并未克隆。


    $git clone/path/to/repos/super.git/path/to/my/workspace/super-clone $cd/path/to/my/workspace/super-clone $ls-aF ./../.git/.gitmodules lib/ $find lib lib lib/lib_a lib/lib_b

    这时如果运行git submodule status可以查看到子模组的状态。


    $git submodule status -126b18153583d9bee4562f9af6b9706d2e104016 lib/lib_a -3b52a710068edc070e3a386a6efcbdf28bf1bed5 lib/lib_b

    可以看到,每个子模组的目录前面都是40位的提交ID,最前面的是一个减号。减号的含义是该子模组尚未检出。

    如果需要克隆出子模组形式引用的外部库,首先需要执行git submodule init。


    $git submodule init Submodule 'lib/lib_a' (/path/to/repos/libA.git)registered for path 'lib/lib_a' Submodule 'lib/lib_b' (/path/to/repos/libB.git)registered for path 'lib/lib_b'

    执行git submodule init实际上修改了.git/config文件,对子模组进行了注册。文件.git/config的修改示例如下(以加号开始的行代表新增的行)。


    [core] repositoryformatversion=0 filemode=true bare=false logallrefupdates=true [remote"origin"] fetch=+refs/heads/:refs/remotes/origin/ url=/path/to/repos/super.git [branch "master"] remote=origin merge=refs/heads/master +[submodule "lib/lib_a"] +url=/path/to/repos/libA.git +[submodule "lib/lib_b"] +url=/path/to/repos/libB.git

    然后执行git submodule update完成子模组版本库的克隆。


    $git submodule update Initialized empty Git repository in /path/to/my/workspace/super-clone/lib/lib_a/.git/ Submodule path 'lib/lib_a':checked out '126b18153583d9bee4562f9af6b9706d2e104016' Initialized empty Git repository in /path/to/my/workspace/super-clone/lib/lib_b/.git/ Submodule path 'lib/lib_b':checked out '3b52a710068edc070e3a386a6efcbdf28bf1bed5'