背景

先说说团队内之前使用 svn 情况,每个开发人员都开了一个 branches/xxx 的分支,接踵而来的麻烦就是,需要一个固定的人每次将各个开发的分支合并到 trunk 上,且需要解决合并带来的冲突,这个人还得审核代码,完了之后将 trunk 合并到各个开发的分支上。整个流程下来,基本都耗费了大半小时,如果发现冲突且无法解决,还必须拉上分支的开发人员过来捋捋思路,这个时间更长。

抛开消耗的时间来说,merge 代码的信息没有分支的完整提交记录,后面查找起来需要来回切换 trunk 和分支,并不方便。

对版本管理工具的需求:

  • 版本控制工具能把分支的提交记录合并过来
  • 减少没必要的开发分支,只保留主干和功能分支,又不影响个人提交
  • 合并的代码必须是开发解决完冲突之后的可稳定运行版本

初识 Git

至今,Git 已然成为最流行的版本管理系统,GitHub 上为无数开源项目提供的就是 Git 存储。svn 属于集中式版本管理系统,而 Git 属于分布式版本管理系统。

svn 必须联网才可提交代码,而 Git 在每个人的电脑上就是一个完整的版本库,工作的时候不需要联网,只有推到远程仓库才需要,这大大解决了程序员没网不能提交代码的痛楚。分布式对比集中式版本管理系统还有很多优点,这里就不一一列举了,这里的重心是代码迁移。

下面列举我学习 Git 的相关资料:

代码迁移

代码迁移需要保留之前 svn 的所有提交信息,这时,我们就需要知道 svn 的所有作者信息,以及与 Git 作者建立映射关系。

打开 svn 仓库根目录,例如:svn://xxx.xx.xxx.xxx/my-project/,然后通过该命令可以获得 svn 作者的列表:

  1. $ svn log --xml | grep -P "^<author" | sort -u | perl -pe 's/<author>(.*?)<\/author>/$1 = /' > users.txt

接下来在 svn 仓库根目录内就有出现一份 user.text 的 svn 作者列表文件,打开编辑,跟 Git 作者建立映射关系,格式如下:

  1. schacon = Scott Chacon <schacon@geemail.com>
  2. selse = Someo Nelse <selse@geemail.com>

接着,找个地方新建一个 test 空白文件夹,用来转换之用。把上面生成的 user.txt 放入该文件夹的根目录内,之后在 Git Bash 运行以下代码:

  1. $ git svn clone http://svn://xxx.xx.xxx.xxx/my-project/ --authors-file=users.txt --no-metadata -s my_project

options 说明:
—authors-file -A 指定作者目录文件
—trunk -T 指定自己 svn 仓库 trunk 文件夹的名字
—branches -b 指定自己 svn 仓库分支文件夹的名字
—tags -t 指定自己 svn 仓库 tag 文件夹的名字
—stdlayout -s svn 常规 trunk|branches|tags 目录结构
—no-metadata 阻止 git svn 包含那些 Subversion 的附加信息

注意:文件夹名字一定要对上,否则代码下载不成功

等待一会,代码下载完后进入 my_project 文件夹运行:

  1. $ git branch -a
  2. * master
  3. remotes/origin/master
  4. remotes/origin/branch1
  5. remotes/origin/branch2
  6. remotes/origin/branch3

注:branch1、branch2、branch3 为原来 svn branches 下的分支

接下来,把 refs/remotes 下面剩下的索引变成本地分支:

  1. $ cp -Rf .git/refs/remotes/* .git/refs/heads/
  2. $ rm -Rf .git/refs/remotes

转换后,Git 本地仓库添加远程 Git 库

  1. $ git remote add origin [远程Git项目仓库]

最后推送本地仓库到远程仓库上

  1. $ git push origin --all

进入远程仓库查看history
迁移完成~

Git 工作流

根据需求,最后选择 Fork 工作流。

工作流程如下:

  1. 开发者从官方项目fork代码到自己名下的私有仓库
  2. clone自己名下的仓库到本地,并根据本地master分支创建自己的开发分支develop
  3. 添加官方项目的远程链接到本地
  1. $ git remote upstream [git远程官方项目地址]
  1. 开发者在develop内的功能开发进行中需要 fix 紧急 bug 时,从本地master另开hotfix分支进行 fix 操作
  2. 假设 fix 完 bug 后,可同时合并到本地masterdevelop分支并删除
  3. 完成develop功能开发之后提交
  4. develop在合并到master前,先拉一下官方仓库代码到本地master进行 update
  1. $ git pull upstream master
  1. 接下来将develop合并到master上并解决冲突,提交代码,push 到自己远程仓库
  2. 由于我们使用的时 GitLab,最后到 GitLab 上提交 merge request 等待有权限的同事合并到官方仓库的masterdevelop分支上

结语

至此,svn 转 Git 历程已经结束。但是对 GitLab 的使用才刚刚开始,工具就是用来提高效率的,接下来就可以去添加一些自动化部署、测试等的功能…

欢迎留言讨论~