connect6-ng 连接 SVN 历史和 Git 历史

我的 connect6-ng 是在 connect6 的基础上进行的。原项目使用 SVN 做版本控制,但我更喜欢使用 Git。所以我在开始 connect6-ng 时先检出了 SVN 仓库里的最新版本然后取出其中源代码初始化了 Git 仓库,并没有继续 SVN 历史。

董渊老师建议我能把两段历史连接起来,以体现出项目的延续性。老师还帮忙使用 git-svn 在 Ubuntu 9.10 下将 connect6 项目的 SVN 历史转换到了 Git 仓库下:

mkdir connect6.git
cd connect6.git/
git-svn init http://connect6.googlecode.com/svn/ --no-metadata
git config svn.authorsfile ../authors.txt
git-svn fetch
git log
cd ..
tar -zcvf connect6.git.tgz connect6.git/

其中authors.txt的内容为:

qq280833822 = CHEN Shuang <qq280833822@gmail.com>
wanglei     = WANG Lei    <leopardguo25@gmail.com>

我收到 connect6.git.tgz 后在连接两段历史前,对前一段历史记录做了一些更改:使用 git filter-branch 删除了仓库里的 *.class 文件、/trunk/connect6.jar 文件,因为我觉得这些中间文件或目标文件放在仓库里意义不大。另外,我又将 trunk 目录做成了仓库的根目录,这和后面我的仓库更接近。处理后的仓库目录我命名为 connect6-shrinked/

参考 stackoverflow 中这个问题回答,我使用其中的第三种方法(refs/replace/) 将 SVN 仓库历史转换成的 git 历史添加在了 connect6-ng 提交历史的前面,连上了两段历史。不太详细的步骤如下:

切换到新项目 connect6-ng 的顶层目录,把 connect6-shrinked 加为一个远程仓库,命名为 history:

$ git remote add history file:///path/to/connect6-shrinked/

然后找出 connect6-ng 项目最初的提交(Initial commit)的 SHA1 值,保存到 $TAIL 变量中:

$ TAIL=$(git rev-list --topo-order master | tail -n 1)

接着找出要导入历史的旧项目的最近的一次提交,保存到 $TOP 变量中:

$ TOP=$(git rev-parse --verify history^0)

然后读取 $TAIL 这个 commit 对象的内容:

$ git cat-file commit $TAIL > TAIL_COMMIT

手工编辑 TAIL_COMMIT 这个文件,加入一行 parent $TOP(其中 $TOP 换成对应的 SHA-1 值),这使得新项目的初始提交有了旧项目的顶部作为父提交。将新的 TAIL_COMMIT 写入仓库:

$ NEW_TAIL=$(git hash-object -t commit -w TAIL_COMMIT)

最后使用 git replace

$ git replace $TAIL $NEW_TAIL

这样就连接好了两段历史记录,可以用 git log 等查看。

要把合并后的历史 push 出去,需要在自己仓库 .git/config 文件中对应 remote 部分加一行:

push = +refs/replace/*:refs/replace/*

在合并两段历史之前已经从 connect6-ng 远程仓库 clone 了代码仓库的同学,如果不做修改,还是只能看到较新的一段历史。要想看到旧的SVN导出的历史,需要修改自己的 .git/config 里 origin 部分(或者其他指向 connect6-ng 远程仓库的 remote 分支名)添加一行:

fetch = +refs/replace/*:refs/replace/*

这样之后 git fetchgit pull 就可以拉取 refs/replace/ 下的后来添加的历史了。

附注:本文参考了董渊老师和我的邮件、stackoverflow 上的回答等,一并感谢。

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s