阿里云
发表主题 回复主题
  • 6382阅读
  • 2回复

《走进git时代系列二》 从SVN迁移到GIT教程

级别: 小白
发帖
10
云币
52
— 本帖被 戴蒙 设置为精华(2016-02-22) —
摘要
       本文介绍了通过git-svn 工具,如何将SVN 代码 迁移 到Git 的全部过程, 以及如何混用SVN+GIT的教程


          本篇文章是走进git时代系列之二,不了解GIT的同学可以先看系列一 《走进git时代系列一》 你该怎么玩?https://yq.aliyun.com/articles/5843 或  https://bbs.aliyun.com/read/272687.html


    

本文分为以下几部分内容:


1.   SVN 迁移到 Git 的简单原理


2.  图文教程从TaoCode SVN 迁移到 YunCode  Git


3.  如何混用SVN+GIT

    


SVN 迁移到 Git 的简单原理  

  • 本文所涉及的工具只有一个 git-svn , 包含在1.7.1以上的git客户端版本内, 该工具详细介绍见: https://www.kernel.org/pub/software/scm/git/docs/git-svn.html  
  • 那么, 有了这个工具, svn to git  就变的没那么复杂了, 基本的思路如下:

1.  初始化本地代码库: `git svn clone -s svn-repository-url `


2.  建立分支,切换,提交,合并等纯git操作

3.  推送到远端Git 仓库中


4.  当前分支和远程SVN同步: `git svn rebase`  。 当同步SVN时出现冲突,需要手动修改冲突,git add 添加后继续rebase: `git svn rebase --continue`


5.  或者提交到远端的SVN仓库中,假如你本地是git , 远端是SVN, `git svn dcommit`


  • svn和git的工作原理毕竟不同,git对代码提交的非线性特性在svn中难以再现,如果使用了git-merge或者git-pull,再提交到svn,相关分支上的提交历史有可能无法体现在svn上。从svn的使用者的角度,无法辨别这是一个提交还是一次合并,所以在和svn协作过程中,尽量让代码库保持线性。


  • 尽量保持git代码库的线性特征。比如在new_branch分支中,先和master做rebase,再合并到master分支中:


      -  git rebase master
      -  git checkout master
      -  git merge new_branch
      -  然后在master上做dcommit,就可以在svn代码库中看到完整的提交历史




    


图文教程从TaoCode SVN 迁移到 YunCode  Git


  • 下面进入正题部分, 我将演示如何从一个SVN仓库迁移到GIT仓库中, 演示过程中的代码库均为开源代码,大家可以直接下载来练习。 SVN 地址为淘蝌蚪开源社区中的一个推荐仓库: http://code.taobao.org/svn/QLExpress/
  • 首先我们看一下本地的SVN和GIT客户端版本:


  • 使用命令git svn clone -s http://code.taobao.org/svn/QLExpress/ , 为什么要加-s , 因为这个仓库是按照标准的tags、trunk、branches结构划分的,则git svn会将对应的分支、标签识别存放到git的结构中。 如果不加-s,不会将tags、branch按照git的结构进行划分 。

  • 从图中可以看到, git svn 是将每次svn 的提交计算出来写入git的每一个commit version, 所以, 如果你的SVN代码库Version 非常多, 这个过程会很慢, 那么,我们可以通过git svn clone -s -r$REVNUMBER:HEAD http://svnurl/yourrepo 来检出最后的几个版本。 举个栗子:
  • 先通过svn log http://svnurl/yourrepo| tail -4 | head -1 获取当前仓库的起始Version,假设是r10, 那我们如果要检出所有版本,命令为git svn clone -s -r10:HEAD http://svnurl/yourrepo
  • 再通过svn info http://svnurl/yourrepo | grep Revision 获取最新的SVN版本号,假设我们要最后10个版本,则命令为git svn clone -s --prefix=svn/ -r90:HEAD http://svnurl/yourrepo , 示例图如下 :

  • 这里我们将全部version 都检出,经过几分钟的过程,我们可以看到此目录下同时具备svn和git的一些信息:(注:截图里st=status , br=branch)

  • SVN信息:

  • 通过git show-ref 可以看到有master这个本地分支,同时有remote 分支trunk , 1.4.1, 2.1.0 等, 通过Git Version 发现trunk 和 Master分支的版本是一样的, 其他几个分支和SVN客户端branches 目录下的结构是一样的。 说明 git svn 将svn的主干和其他分支 转换为了git的 master 和其他branch 。

  • 假如你的SVN仓库是非标结构的,也可以用“-T 主干名 -b 分支名 -t 标签名”参数分别指定归类,
  • 例1: git svn clone http://svnurl/yourrepo -T trunk -b branches -t release 这里制定了release是一个标签集。
  • 例2:git svn clone http://svnurl/yourrepo/project1 -T rpm -b branches -t release这里指定了svn库中的rpm目录是主干、branches目录是分支集,release目录是标签集,而project1下的其他目录会被忽视。
  • 这时我们发现有一些remote 分支,不是本地仓库的分支, 我们还没有设置remote, 那就需要执行以下的命令将remote 分支移回本地分支。
  1. cp -Rf .git/refs/remotes/tags/* .git/refs/tags/
  2. rm -Rf .git/refs/remotes/tags
  3. cp -Rf .git/refs/remotes/* .git/refs/heads/
  4. rm -Rf .git/refs/remotes
  • 这个示例仓库没有tag ,只有branch ,所以只要把branch 挪到本地即可, 执行后效果如下:

  • 这时我们就需要一个真正远程的Git 仓库了, 我们使用https://code.aliyun.com 来创建。 首先使用阿里账户登录code.aliyun.com , 然后在左侧导航内“个人资料设置” --> “SSH 秘钥” 这里添加一个我本地的公钥,本地公私钥 通过 ssh-keygen 命令 一路回车后创建, 然后将~/.ssh/id_rsa.pub的内容粘贴到下图中:




  • 现在回到网址首页,创建一个同名为QLExpress 的开源代码库:

  • 先在我本地做git 的基本全局设置:
  1. git config --global user.name "tangrong.lx"
  2. git config --global user.email "tangrong.lx@taobao.com"
  • 可以看到这是一个空的git代码库:


  • 在本地的仓库中,增加远程git remote 地址:git remote add origin git@code.aliyun.com:tangrong111/QLExpress.git , 这些命令在云code 中创建代码库后页面里有提示,可以直接复制,当然我这个是从svn 倒过来的代码库,只需要这一个远程地址即可,不需要git 初始化之类的操作

  • 这时,我们通过git status 查看一下,避免本地有其他不小心的修改, 然后再执行git push origin --all , 就可以鉴证这伟大的时刻了:


  • 同样通过git log 可以看到每一个commit 都有记录 对应的svn版本地址, 而且svn的 commit log 也被转换为了 git的commit log, 是不是很神奇。 这时,我们刷新一下https://code.aliyun.com/tangrong111/QLExpress 这个页面,代码库已经被推送上来,并记录了大小,分支,提交次数等信息:

  • 看下文件列表:


  • 最后看一下commit 记录, 可以查看每个分支的,每个记录都有,是不是很帅! 从此就可以快乐的在yuncode上玩耍了!

    



如何混用SVN+GIT

  • 最后我介绍一下, 如何在本地使用git, 同时远程有git和svn并存的情况,以及没有远程Git只有远程SVN,但你本地又想用Git的情况(这种属于公司内只有SVN,你又是个git死忠,当然你可以推荐你们公司使用yuncode ,也有saas版可以单独部署的哦)
  1. 远程Git和SVN都使用,流程如下:
  1. git branch -m svn
  2. git remote add origin git@github.com:yourname/yourrepo.git
  3. git checkout master
那么本地svn分支对应svn的远程仓库,本地master分支对应git的远程仓库你可以继续创建本地分支进行开发, 当要提交到远程git时,切换到master分支下, 合并你的分支, git push 到git远端上如果代码要更新到svn上:
  1. git checkout svn
  2. git merge master
  3. git svn dcommit
    2.  如果没有远程Git仓库, 那么:修改本地代码后, 通过 git add/commit提交到本地git库定期rebase 获取svn, 定期 dcommit 提交到svn库
  1. Just redo this tripple:
  2. git svn fetch
  3. git svn rebase
  4. git svn dcommit 如果要给svn库建分支:
  5. git svn branch xxxxx 如果要给svn打tag :
  6. git svn tag 0.1
[font='Helvetica Neue', Helvetica, Arial, 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif]    3.  冲突与解决
假设其他同学也在同时开发,已经提交了新版本到SVN中, 当你git svn dcommit 的时候提示本地文件已经过期你通过 git svn rebase 获取SVN的最新文件版本, 导致文件出现冲突不过这个时候SVN的版本信息已经添加到本地的git库里, 通过git log 可以看到那么,打开冲突文件,修改代码,解决冲突。 执行
  1. git rebase --continue
  2. 提示You must edit all merge conflicts and then mark them as resolved using git add 执行 git add xxxx 后,再次执行
  3. git rebase --continue 提示'Applying: xxxxxxxxx'
此时git的版本成功加入到本地版本库, 可以通过git log 查看。执行 git svn dcommit把解决后的文件同步到SVN远程库中,到此算是完成一次冲突解决。    

写在最后
  • 其实, 你如果对svn 的log 不是那么看中, 最简单的就是在 code.aliyun.com 上创建一个git 仓库,然后代码拷贝过去, 从第一个version 开始新的里程 ~~
  • 假设你看完这篇文章明白了 怎么从svn 迁移到 git 中, 那么就敬请期待 走进Git 时代的系列三 :《玩转云Code最佳实践》 吧 !







[ 此帖被唐容在2016-02-22 14:00重新编辑 ]
级别: 论坛版主
发帖
4292
云币
2522

只看该作者 沙发  发表于: 2016-03-11
感谢分享
级别: 新人
发帖
1
云币
1
只看该作者 板凳  发表于: 2017-01-04
Re《走进git时代系列二》 从SVN迁移到GIT教程
现在taocode登录不了就是让你迁移项目吗
发表主题 回复主题
« 返回列表上一主题下一主题

限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
验证问题: ECS是阿里云提供的什么服务? 正确答案:云服务器
上一个 下一个