公司内部原本使用 SVN 进行版本控制,但随着 Github 的流行我个人的代码管理习惯逐渐转变。虽然公司项目并非开源,SVN 所具有的标准 trunk / branches / tags 结构完全够用,使用 Git 仍然有如下优势:

  • 类似 GitHub 的 GitLab 免费管理工具。将代码托管在自己内部服务器上的同时,提供了优美的 web 界面,图形化分支结构,更直观的代码审查,统计、issue 系统、wiki 等功能全面集成。
  • 更方便主程做 code review,控制代码质量。创建主仓库,多人开发时使用 fork 模式,每个人拥有自己独立的 repo,独立的 trunk / branches,最后发送 pull request 进行代码合并。
  • commit 和 push 更快。体现在 push 到远程仓库时 Git 会先对所有需要上传的文件进行 zip 打包压缩,然后一次性传输,在远程服务器解压,全部自动完成。而 SVN 则是一个一个文件地上传,代码是纯文本,总体积并不大,但是大量零碎的小文件频繁建立网络连接造成延迟。这在升级第三方的库或者框架时,成千上万的文件更新更加让人难以忍受。
  • hook 可以更方便做自动化部署。当然这个 SVN 也有。

权衡后我决定花时间进行代码仓库的迁移。代码迁移并非简单地创建 Git repo 把当前项目代码一次性 commit 过去就够了,因为 SVN 中存有长年累月的 commit 历史记录,丢失历史记录将对今后追溯 debug 造成非常大的麻烦,所以如何保留 commit 记录就是迁移的关键。

  

一、迁移步骤

创建用户映射 (例如 users.txt) ,将 SVN 用户和 Git 用户对应起来:

user1 = First Last Name <email@address.com> user2 = First Last Name <email@address.com> …

如果上面的文件中有用户缺失,后面的 SVN 命令将会停止。不过你可以更新用户映射然后接着再来(类似断点续传)。

现在从 SVN 仓库中拉取所有数据:

git svn clone --stdlayout --no-metadata -A users.txt svn://hostname/path dest_dir-tmp

这个命令将会在 dest_dir-tmp 新建一个 Git repo,并开始从 SVN 中拉取代码。请注意 “--stdlayout” 参数表示你的项目在 SVN 中是常见的 “trunk/branches/tags” 目录结构,如果不是,那你需要使用 --tags, --branches, --trunk 参数(请通过 git svn help 自行了解)。

再后面的参数是 SVN 的地址,一些常见协议都是支持的 : svn://, http://, https://. 注意这个 URL 应该指向项目的 base repository,例如 http://svn.mycompany.com/myrepo/repository. 不要指到了 /trunk, /tag/branches 里。

如果出现用户名没找到,更新你的 users.txt 文件,然后

cd dest_dir-tmp
git svn fetch

如果你的项目非常大,你可能需要重复上面的命令好几次,直到所有的 SVN commit 都被抓下来了:

git svn fetch

完成后,Git 将会 checkout SVN 的 trunk 到一个新的 Git branch,而其他的 SVN branch 将会设为 Git remote,你可以查看所有的 SVN branch:

git branch -r

如果你想在你的 Git repo 中保留其他的 remote branch,你需要手动创建本地 branch。否则,SVN 的 branch 将不会在最后被 clone。

git checkout -b local_branch remote_branch
# it's ok if local_branch and remote_branch are the same name

SVN tags 被当作 branch 导入了,你需要创建本地 branch,打一个 tag,然后删掉那个 branch,这样才会在 Git 中生成 tag。例如 SVN tag “v1″:

git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1

把上面的 GIT-SVN repo Clone 到一个全新的干净 git repo:

git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir

之前从 remote branch 创建的本地 branch 又会在新 clone 的 repo 中成为 remote branch,于是对每个 branch 再做一次:

git checkout -b local_branch origin/remote_branch

最后,从干净的 Git repo 中删掉 remote (指向我们刚刚已经删掉的 temp repo)

git remote rm origin

这样一个全新 Git repo 就已经从 SVN 迁移好了。

二、新的 Git 远程仓库

将本地的 Git repo push 到远程仓库(我这里用的是 GitLab):

git remote add origin git@git.udev.hk:udba/udba.git
git push -u origin master

push 所有的 branch:

git push origin --all

push 所有的 tag:

git push origin --tags

最后再放两张 GitLab 的截图

在线阅读代码

图形化统计数据

– EOF –

http://www.lovelucy.info/codebase-from-svn-to-git-migration-keep-commit-history.html

将代码库从 SVN 迁移至 Git 并保留所有 commit 记录的更多相关文章

  1. 从svn迁移至Git并保留所有 commit 记录

    用户映射文件user.txt,等号左边为svn账号,右边为Git用户名和邮箱.注意:svn中有多少用户就要映射多少 test1=test1<147258369@qq.com>test2=t ...

  2. 从 SVN 迁移至 Git 并保留所有 commit 记录

    yum install -y git-svn 用户映射文件user.txt,等号左边为svn账号,右边为Git用户名和邮箱.注意:svn中有多少用户就要映射多少 test1=test1<1472 ...

  3. git学习------>从SVN迁移到Git之后,项目开发代码继续在SVN提交,如何同步迁移之后继续在SVN提交的代码到Git?

    最近逐步逐步的将公司的项目都从SVN往Git迁移了,但是想团队成员都能够一步到位就迁移到Git是不可能的,因为还有大部分人都还不会Git,所以整个过渡过程估计得大半年. 因此导致虽然项目迁移过来了,但 ...

  4. SVN迁移到Git的过程(+ 一些技巧)

    SVN迁移到Git的过程(+ 一些技巧) 李顺利 Key Words SVN,Git,Clone,Conversion,Tips,VCS,Pro Git 关于在VCS中SVN和Git之间的迁移(Clo ...

  5. SVN迁移到Git的过程(+ 一些技巧

    关于在VCS中SVN和Git之间的迁移(Clone)这个部分网上已经有大批的文章介绍,而且都非常不错,能够满足我们的常见的需求,这里介绍的是我自己整理的一些技巧和使用中出现的一些问题和疑问.阅读本篇文 ...

  6. svn 迁移至git操作手册

    svn 迁移至git操作手册 项目交付.版本管理工具变更等情况下,迁移svn旧历史记录有很大必要,方便后续追踪文件的提交历史,文件修改记录比对等.git自带了从svn迁移至git的工具命令,可很好的对 ...

  7. svn迁移到git仓库并保留commit历史记录

    svn迁移到git仓库并保留commit历史记录 最近在做svn迁移到gitlab,由于之前一直是由svn做版本控制.最简单的方式是将svn的内容export出来,然后添加到gitlab即可.但是,如 ...

  8. 使用subgit进行svn迁移至git(branch,tags)

    前言: 最近公司需要将整体项目从svn迁移至gitlab上,经过几天的研究,现记录一下流程 整体思路是进行一次导入: 先通过subgit将svn整个import至本地,在与git上的项目进行合并. 1 ...

  9. SVN迁移到Git原因说明

    1.Git分布式的源码管理 每位开发人员计算机本地会有一份代码库,开发人员可在不受其他人代码提交影响的前提下对源码进行提交/回滚/撤销等操作. 在独立的开发任务中即可实现对源码管理又不受其他开发人员提 ...

随机推荐

  1. git —— 异常1,index.lock

    git提交过程中出现的问题 解决方法:找到 index.lock文件将其删除 一般 index.lock 在.git下面, 有时 .git 是隐藏的,但是无论怎样, 可以通过 everything 找 ...

  2. Javascript 跨域访问解决方案 总结

    在客户端编程语言中,如javascript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义.同 源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问 ...

  3. inherited 的研究。

    结论: 1. inherited默认调用的是父类的同名 同参数方法.(常用,如果是同名 同参数方法 比如 overide 的,可以省略,只写个inherited就可.) 2. 子类的方法里可以 inh ...

  4. js交互

    Js和native交互的方法与问题 实现JS和Native交互有两种方式: 第一种:shouldOverrideUrlLoading(WebView view, String url) 通过给WebV ...

  5. Rookey.Frame之DAL工厂

    昨天给大家介绍了表单验证功能,今天给大家介绍下Rookey.Frame框架的数据层工厂,由于Rookey.Frame框架ORM是基于servicestack.ormlite,很多朋友反映这个网上中文资 ...

  6. 【POJ】1819.Disks

    博客园的话插链接链接都是凉的= = 题解 我理解成能不能看到这个圆,除了最后几个圆特殊以外都是等价的,然而我凉了,因为我把圆当成线段来处理,但是,有可能一个圆完全被遮住了,还有一个缝隙,就WA了 计算 ...

  7. 记录移动端html界面中底部输入框触发焦点时键盘会把输入框遮挡的问题

      //浏览器当前的高度 var oHeight = $(document).height(); //监听窗口大小的时候动态改变底部输入框控制器的定位 $(window).resize(functio ...

  8. bzoj 1295 1295: [SCOI2009]最长距离

    思路:对于每个点出发bfs做一次dp, dp[ i ][ j ][ k ] 表示从枚举的该点能不能经过k个障碍物到达(i , j). #include<bits/stdc++.h> #de ...

  9. oracle中vsize和length

    其实LENGTH与VSIZE这两个函数联系不大,区别很大.虽然都是“取长度”,但是LENGTH函数结果是“有多少个字符”,VSIZE结果是“需要多少bytes”.简单看一下这两个函数. 1.创建表T并 ...

  10. JSP的学习二(请求转发与 重定向)

    一: 1.介绍知识点 1). 本质区别: 请求的转发只发出了一次请求, 而重定向则发出了两次请求. 具体: ①. 请求的转发: 地址栏是初次发出请求的地址.  请求的重定向: 地址栏不再是初次发出的请 ...