Git子项目

简介

Git子项目也就是submodule,它允许你在主项目的某个子目录下嵌入另外一个git仓库。gitlink是实现子项目的基础。当git add命令遇到某个子本身是git仓库的子目录时,它会创建gitlink而不是把子目录中的所有文件和目录加到主项目的git仓库中去。通过git ls-tree命令可以查看当前仓库是否包含子项目。比如,Vim常用git和pathogen来管理插件。这些插件本身都在github上找到。这时使用子项目方式管理会带来很多便利。以下是本人的dotvim项目中包含的子项目信息:

$ cd .vim/bundle
$ git ls-tree HEAD

160000 commit a3ae0df1d9e13941e9e8086637055841ce93f7bd  commentary
160000 commit d44fd5cca10c466c0eb3d6f7b18c4b13f5bf24d7  dbext
160000 commit 124550cfee33a1bb9a227e78ccc709317a89dae9  fugitive
160000 commit db80fc95ed01d2c559c4bdc7da8514ed3cc7fcd9  powerline
160000 commit fe40c002effefdde3111b3da0e18ff4b9e97aa03  pytest
160000 commit a81bef76031ca1c71766b516417480caeb01c932  repeat
160000 commit 528a59f26d12278698bb946f8fb82a63711eec21  solarized
160000 commit 7a32e0866bfea26cf7781935289df131d1d0c0e0  supertab
160000 commit 02199ea0080d744ec76b79d74ce56d51d25cf7ae  surround
160000 commit a029dc28ebc1ba5953cd5b0ef9a50bd0ffba3aa4  vim-unimpaired

 这个例子输出的第二列是commit,它说明后面的目录本身是个Git Repository,并且它的工作目录的内容对应第三列所表示的提交。

主要操作

增加子项目

增加子项目大致有两种办法,第一种是先用通常的办法在主项目的某个子目录里创建git仓库,然后在主项目里执行git add <sub_project_dir>。这里要注意的是,子项目的目录名最后不要带多余的斜杠,不然git add不会创建git link,而会将子项目中的所有文件和目录加入到父项目中去。另外一种方法是使用git submodule add命令:

$ git submoudle add <repo_url> subdir

复制带子项目的Git仓库

当你用常规的方法复制带有子项目的Git仓库时,子项目并不会自动初始化。Git 1.7.9.4及以上版本可以用git clone --recurse-submodules来让git同时复制子项目。之前的版本需要手工执行git submodule init和git submodule update来初始化和复制子项目。以下是一个完整的示例:

$ git clone --recurse-submodules https://github.com/schnell18/dotvim.git

 

 

更新子项目的内容

如果子项目的上游有了更新,这些变化并不自动反应在主项目中。这是由于git link只会指向特定版本的子项目。如果要把上游的更新集成到主项目中去,你需要更新git link使它指向最新的版本。实现这个目标有两个方法。第一种方法是先进入子项目顶层目录,然后确保你在正确的分支上,接着执行git pull origin把上游的更新拉到本地。接着,回到父项目把git link的变动加入到stage:

# do not add trailing slash
$ git add path_to_submoudle

 
最后commit主项目即可。

第二种方法更简便,尤其适用于有多个子项目的情形。该方法是在父项目目录里执行:

$ git submodule foreach git pull origin

 然后把git link的变动加入到stage,最后提交即可。

 

在带子项目的Git仓库中切换分支

如果你在不同的分支有不同的子项目,那么切换分支时,存在于原来的分支中但目标分支中不包含的子项目会变成untracked而并不会自动删除。这时可以使用:

$ git clean -ffd

来清除。这个命令必须使用两个f,否则不能删本身是git仓库的目录。

 

你可能感兴趣的:(git)