SVN迁移Git实践

前言

Git是我工作使用得最多的代码管理工具。从毕业到现在,一直在使用Git管理我的代码,使用Git的branch分支功能进行需求开发,尝试使用GitLab进行持续构建。关于Git与SVN的对比,你可以阅读这里的文章。大多数人,可能会认为SVN已经很好的满足我的工作需要,为什么还需要去迁移到Git呢?

为什么要迁移到Git

必备技能

Git 是最流行的版本管理工具,也是程序员的必备技能之一。未来可能SVN也会变为历史。学习Git后,你可以尝试在终端命令行操作Git。使用命令行的操作几乎可以完成大部分操作,极大的提升你的工作效率。除了代码对比之外,几乎不需要GUI工具了。

分支合并

SVN的分支合并是一个老生常谈的问题。使用Git里,你可以创建无数的分支,尝试自己各种创意的想法,把代码合并到master里,也不是一件很复杂的事情。但SVN不是的,尝试过Git后,再使用SVN时,每次合并都会让你感到无力,切换分支需要花费时间,合并分支需要时间。时间对工程师来讲,可能是开发撸代码中的最大成本。

团队协作

团队协作是Git的一大特色。我认为Git是间接让GitHub已经成为最大的程序员社区网站的原因之一。假设有一个推荐系统的源代码,如果你觉得其中的算法,无法满足自己的需求,手动git clone下来,尝试建立单独的分支,尝试自己的想法,通过无数的单元测试后,对自己最后的代码调整完毕,发起一个MR说明自己的改动原因,希望自己的提交尽快可以被Review。选择Git作为版本控制系统,就是选择一种新的团队协作方式。如果要使用SVN的话,我不知道要如何去实现分布式的代码提交体验,甚至无法想象SVN的协作流程可以有这么顺畅。

好了,说了这么多,那么如何将SVN迁移到Git呢?

如何将SVN迁移到Git

准备一份提交者列表

通常需要先整理svn的全部提交者的username和email,与git进行对应。

svn log --xml |\
grep '<author>' | sed 's#<author>##' | sed 's#</author>##' | sort -u |\
sed 's/.*/& = & <&@test.com>/' > authors.txt

上面的命令为了获取全部的作者的的用户名和邮箱地址,我们来分解下每一步操作的作用:

svn log –xml 以xml的格式输出对应的日志
grep ‘‘ 搜索author为关键字的行,避免获取到注释中有author的情况
sed ‘s###’ 搜索行的替换为空
sed ‘s#
##’ 搜索行的
替换为空
sort -u 去重排序
sed ‘s/.*/& = & &@test.com/’ 将每一行进行格式化
author => author = author author@test.com

SVN版本库

假设有这样的一个SVN的版本库:

# svn url
svn+ssh://svnuser@svn.xbc.me/your_svn/
# 目录结构
branches
tags
trunk

那么最简单的将SVN版本转为Git版本库的命令为:

git svn clone -s svn+ssh://svnuser@svn.test.com/your_svn --authors-file=authors.txt

这样将SVN的全部代码对应起来:trunk对应到master,branche以及tag都对应到Git版本库。

实际上,我们在迁移的过程中,可能遇到另外一类情况。假设有以下SVN的版本库:

# svn url
svn+ssh://svnuser@svn.test.com/your_svn/trunk/
# 目录结构
app
h5
pc

那么我们尝试将单一的版本库拆分为3个不同的版本库:

git svn clone svn+ssh://svnuser@svn.test.com/trunk/app --authors-file=authors.txt --no-metadata
git svn clone svn+ssh://svnuser@svn.test.com/trunk/h5 --authors-file=authors.txt --no-metadata
git svn clone svn+ssh://svnuser@svn.test.com/trunk/pc --authors-file=authors.txt --no-metadata

使用–no-metadata 会移除类似下面的svn id信息。

git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
    be05-5f7a86268029

现在你可以添加远程分支,进行代码提交了。

git remote add origin git@git.test.com:my/app.git
git push origin master

同步SVN版本库的更新

在转为Git版本库后,可能会还有一段过渡期,也就是以SVN为主,待熟悉Git整体工作流程后才会切换到Git。那么这时,该如何同步SVN的更新到Git呢?

我会使用以下脚本进行代码的同步:

git checkout master
git svn fetch
git svn rebase 
git push origin master
git checkout -

主要的命令有2个:

git svn fetch 获取SVN版本库的更新提交

git svn rebase 将SVN的更新变基当前master代码分支,这样整体的代码提交就是线性的了。

最好把上面的做成定时任务去执行就好了,每10分钟执行一次。

*/10 * * * * bash git.up.sh

常见问题

svn: E220001: Item is not readable

出现这个问题,是由于svn log的命令参数错误导致的。

svn log ^/ --xml
改为
svn log --xml

Author: (no author) not defined in

出现这个错误,是因为在作者列表找不到该用户,需要手动添加该用户。

(no author) = no author <noauthor@test.com>

总结

将SVN转换为Git版本库,可能整体工作流程迁移中的一小步,更重要的整个工作流程是否支持Git版本库,项目的DevOps流程是否完善,比如持续集成,自动构建,代码检查,自动发布等。另外,我认为更重要的是学习并熟悉Git的开发协作流程,比如我经常使用到的GitLab Flow的变种。下一篇会尝试说明如何进行GitLab Flow的工作流程。

SVN迁移Git实践

发表评论

电子邮件地址不会被公开。 必填项已用*标注