24.5 git-subtree插件

git-subtree插件[1]用shell脚本开发,安装之后为Git提供了新的git subtree命令,支持前面介绍的子树合并和子树拆分。命令非常简单易用,将其他版本库以子树形式导入,再也不必和底层的Git命令打交道了。

安装Git subtree很简单,操作如下:


$git clone git://github.com/apenwarr/git-subtree.git

$cd git-subtree

$make doc

$make test

$sudo make install


下面就来介绍Git subtree的常用命令。

1.git subtree add

命令git subtree add相当于将其他版本库以子树方式加入到当前版本库。用法如下:


git subtree add[—squash]-P<prefix><commit>

git subtree add[—squash]-P<prefix><repository><refspec>


其中可选的—squash的含义是压缩为一个版本后再添加。

对于文中的示例,为了将util.git合并到main.git的lib目录,可以直接这样调用:


$git subtree add-P lib/path/to/repos/util.git master


不过推荐的方法还是先在本地建立util.git版本库的追踪分支。


$git remote add util/path/to/repos/util.git

$git fetch util

$git branch util-branch util/master

$git subtree add-P lib util-branch


2.git subtree merge

命令git subtree merge相当于将子树对应的远程分支的更新重新合并到子树中,相当于完成了git merge-s subtree操作,用法如下:


git subtree merge[—squash]-P<prefix><commit>


其中可选的—squash的含义是压缩为一个版本后再合并。

对于文章中的示例,为了将util-branch分支包含的上游的最新改动合并到master分支的lib目录中,可以直接这样调用:


$git subtree merge-P lib util-branch


3.git subtree pull

命令git subtree pull相当于先对子树对应的远程版本库执行一次git fetch操作,然后再执行git subtree merge。用法如下:


git subtree pull[—squash]-P<prefix><repository><refspec…>


对于文章中的示例,为了将util.git版本库的master分支包含的最新改动合并到master分支的lib目录中。可以直接这样调用:


$git subtree pull-P lib/path/to/repos/util.git master


更喜欢用前面介绍的git subtree merge命令,因为git subtree pull存在版本库地址写错的风险。

4.git subtree split

命令git subtree split相当于将目录拆分为独立的分支,即子树拆分。拆分后形成的分支可以推送到一个新的版本库中,进而实现用原版本库的一个子目录为根目录创建出新的版本库。用法如下:


git subtree split-P<prefix>[—branch<branch>][—onto…][—ignore-joins]

[—rejoin]<commit…>


说明:

该命令总是输出子树拆分后的最后一个commit-id。这样可以通过管道方式传递给其他命令,如git subtree push命令。

参数—branch提供拆分后创建的分支名称。如果不提供,只能通过git subtree split命令提供的提交ID得到拆分的结果。

参数—onto参数将目录拆分附加于已经存在的提交上。

参数—ignore-joins忽略对之前拆分历史的检查。

参数—rejoin会将拆分结果合并到当前分支,因为采用ours的合并策略,不会破坏当前分支。

5.git subtree push

命令git subtree push先执行子树拆分,再将拆分的分支推送到远程服务器。用法如下:


git subtree push-P<prefix><repository><refspec…>


该命令的用法和git subtree split的类似,这里就不再赘述。

[1]http://github.com/apenwarr/git-subtree/