35.2 Hg版本库到Git的迁移
Mercurial(水银)是和Git同时代的、与之齐名的一款著名的分布式版本控制系统,也有相当多的使用者。就像水银又名汞一样,作为版本控制系统的Mercurial又称作Hg(水银元素符号)。Hg具有简单易用的优点,至少Hg按提交的顺序递增的数字编号让Subversion用户感到更为亲切。Hg的开发语言除少部分因性能原因使用C语言外,大部分用Python语言开发完成,因而更易扩展,最终形成了Hg最具特色的插件系统。例如MQ就是Hg一个很有用的插件,通过Quilt式的补丁集实现对定制开发的特性分支的版本控制,当然StGit和Topgit也可以实现类似的功能。
但是Hg存在一些不足。例如服务器的存储效率不能和Git相比,服务器存储空间占用更大。Hg还不支持真正的分支,所以不能向git-svn那样完整地对Subversion版本库进行转换和互操作。Hg的提交只能回退一次,要想多次回退和整理版本库需要用到MQ插件。作为定制开发的利器,Hg+MQ不适合多人协作开发而Git+Topgit更为适合。
不论是何原因如果想从Hg迁移到Git,用一个名为fast-export的转换工具就可以很方便地实现。fast-export是一个用Python开发的命令行工具,可以将本地的Hg版本库迁移为Git版本库。其原理和CVS版本库迁移至Git时使用的cvs2git相仿,都是先从源版本库生成导出文件,再用Git的通用版本库转换工具git-fast-import导入到新建的Git版本库中。
安装fast-export非常简单,只要用Git克隆fast-export的版本库即可。
$cd/path/to
$git clone git://repo.or.cz/fast-export.git
完成克隆后,会看到/path/to/fast-export目录中有一个名为hg-fast-import.sh的脚本文件,该文件封装了对相应Python脚本的调用。使用该脚本可以实现Hg版本库到Git版本库的迁移。
下面就演示一下Hg版本库到Git版本库的转换,具体操作过程如下。(1)要转换的Hg版本库位于路径/path/to/hg/hello/.hg下。
Hg不支持真正的分支,而且版本库中可能存在尚未合并的多个头指针。检查一下不要存在具有相同分支名但尚未合并的多个头指针,否则转换会失败。下面显示的该Hg版本库中具有两个具名分支r1.x和next,还有一个默认的未设置名称的头指针,因为分支名各不相同所以不会为转换过程造成麻烦。
$hg heads
修改集:7:afdd475caeee
分支:r1.x
标签:tip
父亲:0:798a9568e10e
用户:Jiang Xin<jiangxin@ossxp.com>
日期:Fri Jan 14 17:01:47 2011+0800
描述:
start new branch:r1.x
修改集:6:7f5a46201dda
分支:next
用户:Jiang Xin<jiangxin@ossxp.com>
日期:Fri Jan 14 17:01:04 2011+0800
文件:src/locale/zh_CN/LC_MESSAGES/helloworld.po
描述:
imported patch 100_locale_zh_cn.patch
修改集:1:97f0a21021c6
用户:Jiang Xin<worldhello.net AT gmail DOT com>
日期:Sun Aug 23 23:53:05 2009+0800
文件:src/COPYRIGHT src/main.bak src/main.c
描述:
Fixed#6:import new upstream version hello-2.0.0
(2)初始化一个Git版本库,该版本库就是迁移的目标版本库。
$mkdir-p/path/to/my/workspace/hello
$cd/path/to/my/workspace/hello
$git init
Initialized empty Git repository in/path/to/my/workspace/hello/.git/
(3)在刚刚完成初始化的Git工作区中调用hg-fast-export.sh脚本完成版本库转换。
$/path/to/fast-export/hg-fast-export.sh-r/path/to/hg/hello
(4)转换完毕,执行git branch会看到Hg版本库中的具名分支都被转换为相应的分支,没有命名的默认头指针被转换为master分支。
$git branch
*master
next
r1.x
在转换后的Git版本库目录中,保存了几个用于记录版本库转换进度的状态文件(.git/hg2git-*),当在Git工作区不带任何参数执行hg-fast-export.sh命令时,会继续进行增量式的转换,将Hg版本库中的新提交迁移到Git版本库中。
如果使用了多个不同的Hg克隆版本库进行分支管理,就需要对Hg版本库逐一进行转换,然后再对转换后的Git版本库进行合并。在合并Git版本库的时候可以参考下面的命令。
$git remote add<name1><path/to/repos/1>
$git remote add<name2><path/to/repos/2>
$git remote update
$git checkout-b<branch1>origin/<name1>/master
$git checkout-b<branch2>origin/<name2>/master