简介

svn和git都是常用的版本管理软件,但是git无论在理念或是功能上都比svn更为先进。但是有的公司是以svn作为中央仓库,这时git与svn代码的同步就可以通过 git-svn这个软件进行,从而用git管理svn代码。最后的效果相当于把svn仓库当作git的一个remote(远程仓库),而你本地的代码都是通过git来管理,只有push到svn时才会把你本地的commit同步到svn。

从svn克隆

首先看一看用于测试的svn项目结构,svn的仓库路径是file:///d/Projects/svn_repo,可以用svnadmin create svn_repo命令新建。该仓库有2个分支,1个tag,属于svn标准布局。

SVN项目结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
/d/proj1
├── branches
│   ├── a
│   │   └── readme.txt
│   └── b
│   ├── 11.txt
│   └── readme.txt
├── tags
│   └── v1.0
│   ├── 11.txt
│   └── readme.txt
└── trunk
└── readme.txt

命令格式:git svn clone <svn仓库路径> [本地文件夹名] [其他参数] 相当于git clone
示例: git svn clone file:///d/Projects/svn_repo proj1_git -s --prefix=svn/
参数说明:

  • -s 告诉 Git 该 Subversion 仓库遵循了基本的分支和标签命名法则,也就是标准布局。
    如果你的主干(trunk,相当于非分布式版本控制里的master分支,代表开发的主线),分支(branches)或者标签(tags)以不同的方式命名,则应做出相应改变。
    -s参数其实是-T trunk -b branches -t tags的缩写,这些参数告诉git这些文件夹与git分支、tag、master的对应关系。
  • --prefix=svn/ 给svn的所有remote名称增加了一个前缀svn,这样比较统一,而且可以防止warning: refname 'xxx' is ambiguous.

现在,看下用git-svn克隆的项目情况(运行git branch -a),此处git的分支情况是与svn文件夹对应的。

1
2
3
4
5
* master
remotes/svn/a
remotes/svn/b
remotes/svn/tags/v1.0
remotes/svn/trunk

只下载指定版本之后的历史

如果svn上的commit次数非常多, git svn clone 就会非常慢,一般超过几百个版本就要大概十分钟。此时可以在clone的时候只下载部分版本,
命令:git svn clone -r<开始版本号>:<结束版本号> <svn项目地址> [其他参数]
示例:git svn clone -r2:HEAD file:///d/Projects/svn_repo proj1_git -s
说明:其中2为svn版本号,HEAD代表最新版本号,就是只下载svn服务器上版本2到最新的版本的代码.

工作流程

简单来说就是,首次新建分支会记录和svn远程对应分支的追踪关系,之后你的所有commit都是在本地的;并且和纯git管理的项目没有区别,只是在git svn rebasegit svn dcommit的时候才会和svn仓库发生关系

一般工作流程(推荐)

  1. 新建分支git checkout -b <本地分支名称> <远程分支名称>
    示例:git checkout -b a svn/a
    说明:此处新建了一个本地分支a,与svn的a分支对应。
  2. 在本地工作,commit到对应分支上
  3. git svn rebase 从svn上更新代码, 相当于svn的update。
  4. git svn dcommit 提交你的commit到svn远程仓库,建议提交前都先运行下git svn rebase。

在git本地其他分支工作的情况

  1. git chechout -b a svn/a 此处新建了一个本地分支a,与svn的a分支对应。
  2. git checkout -b feature1 在a分支的基础上,开一个本地feture1分支
  3. 在feture1分支进行开发,有了多次commit
  4. 在feture1分支上进行git svn rebase 和 git svn dcommit,这样feature1的commit也会提交到svn的a分支上。
    需要注意的是要记住feture1是从哪个分支checkout的,它的svn远程分支就与哪个相同。比如此处是a分支,那么svn分支就是svn/a,commit就会提交到svn的a分支。

SVN分支管理

新建分支到svn

命令:git svn branch <分支名称>
示例:git svn branch c_by_git
说明:在svn仓库上建了了一个c_by_git分支
分支情况

1
2
3
4
5
6
7
  a
* master
remotes/svn/a
remotes/svn/b
remotes/svn/c_by_git
remotes/svn/tags/v1.0
remotes/svn/trunk

删除svn分支

  • 删除svn分支目录svn rm <svn分支路径> -m <commit信息>
    示例:svn rm file:///d/Projects/svn_repo/branches/c_by_git -m 'rm branch'
  • 删除远程跟踪分支git branch -D -r <远程分支名称>
    示例:git branch -D -r svn/c_by_git

SVN上tag管理

新建tag

命令:git svn tag <tag名称>
示例:git svn tag v1.1
说明:在svn仓库上建了一个v1.1tag

删除tag

  1. 删除svn目录svn rm <svntag路径> -m <commit信息>
    示例:svn rm file:///d/Projects/svn_repo/tags/v1.1 -m 'rm tag'

  2. 删除远程跟踪分支git branch -D -r <远程分支名称>
    示例:git branch -D -r svn/tags/v1.1
    说明:svn的tag和分支在git看来是一样的,所以此处还是用的git branch

冲突解决

如果本地和svn都进行了修改,则不能快速前进,git svn rebase 会出现错误。
这时应该按以下步骤操作:

  1. 手动修改冲突文件,修改完成后git add

  2. git rebase --continue

  3. git svn dcommit

svn不遵循规范的情况

以上讲的都是svn仓库是标准的情况,如果不标准,则以下几个地方都会有所不同。主要就是每个步骤基本都要添加svn的具体路径。
先看看,示例项目的结构,仓库路径是file:///d/Projects/svn_repo2。这个项目主分支是dev文件夹,branch1和tag1文件夹分别代表的是一个分支和tag。

svn项目结构:

1
2
3
4
5
6
7
/d/proj2
├── branch1
│   └── file1.txt
├── dev
│   └── file1.txt
└── tag1
└── file1.txt

从svn克隆

命令:git svn clone <svn项目地址,要包含具体分支路径> [本地文件夹名]
示例:git svn clone file:///d/Projects/svn_repo2/dev proj2_svn

添加远程分支信息

命令:

  1. git config --add svn-remote.<远程分支名称>.url <svn地址,要包含具体分支路径>
  2. git config --add svn-remote.<远程分支名称>.fetch :refs/remotes/<远程分支名称>

示例:

  1. git config --add svn-remote.svn/branch1.url file:///d/Projects/svn_repo2/branch1
  2. git config --add svn-remote.svn/branch1.fetch :refs/remotes/svn/branch1

说明:此处的“远程分支名称”可以随意填写,只要这三个保持一致即可。建议都给他们增加svn/前缀,这样svn的所有分支显示起来会比较一致,与上面clone时的--prefix=svn/类似。

新建本地分支,与svn对应

命令:

  1. git svn fetch <远程分支名称> 获取svn仓库该分支的代码
  2. git checkout -b <本地分支名> <远程分支名称>

示例:

  1. git svn fetch svn/branch1
  2. git checkout -b branch1 svn/branch1

分支情况:

1
2
3
4
* branch1
master
remotes/git-svn
remotes/svn/branch1

git-svn:通过git来管理svn代码的更多相关文章

  1. Ubuntu下Apache+SVN+submin实现WEB管理SVN

    为什么需要submin管理SVN? 原来在Ubuntu下,都是直接通过命令行创建SVN仓库并分配权限,但是这有一些问题: 每创建一个SVN仓库,都需要修改httpd.conf 每创建一个帐户,都需要手 ...

  2. 代码管理(四)SVN和Git对比

    在日常运维工作中,经常会用到版本控制系统,目前用到最广泛的版本控制器就是SVN和Git,那么这两者之间有什么不同之处呢?SVN(Subversion)是集中式管理的版本控制器,而Git是分布式管理的版 ...

  3. 本地如何将svn和git管理的代码做关联

    svn和git都是广为流传的代码版本管理工具,实际项目中往往会将两者结合使用,那么如何将本地的一份代码和两者做有机的关联呢! 前提假设:项目已经在开发阶段中,此时变更了svn代码库的地址:或者是组里来 ...

  4. SVN和Git代码管理小结

    SVN和Git代码管理小结  之前,先用的是SVN,后来用了Git,最近又在用SVN.  关于代码管理,写几句.    由于自己参与的项目,人通常不超过10个人,版本不是很多,协作比较正常,感觉SVN ...

  5. android开发学习 ------- android studio 同时用svn和git 进行代码管理 出现的问题

    svn和git的工作机制:  SVN 是集中式或者有中心式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要 ...

  6. git与svn, tfs等源代码管理器的协同

    简单地说,这三个都是业界知名的源代码管理器.他们是有区别的,根本的区别在于git是分布式源代码管理器(每个本地都有完整的代码,及历史),而svn和tfs是集中式源代码管理器(只有服务器才有完整的历史, ...

  7. 如何用Android Studio同时使用SVN和Git管理项目

    这篇来讲讲如何在 Android Studio 上同时用 SVN 和 Git 来管理项目.我知道,你肯定会说我吃饱了撑着,没事找事做,为啥要同时用 SVN 和 Git 来管理项目.问题是,我也不想啊, ...

  8. 管理源代码的工具SVN与GIT

    如何看待源代码 源代码是公司的重要资产 对应软件公司来说,源代码相当于固定资产>人才 所以源代码管理对于公司来说是最重要的事物之一 一.管理源代码的工具 SVN:集中式的源代码管理工具,通常必须 ...

  9. 命令行操作svn和git和git

    前几天在写代码的时候电脑突然坏掉,老大交代的任务没完成,非常痛恨自己用svn或者git保存代码,相信很多程序员遇到过,硬盘坏掉,存在硬盘中的代码丢失,无法找回的问题,svn和git可谓程序员界的福音, ...

随机推荐

  1. netcat命令

    1 简介 netcat是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据.通过与其他工具结合和重定向,你可以在脚本中以多种方式使用它.使用netcat命令所能完成的事情令人惊讶. netc ...

  2. python的简洁是shell无法代替的

    之前线上服务器分发配置都是用shell和expect脚本分发,脚本写了很长,上周换了ansible,现在自己用python写一个,就30行代码就可以实现需求,之前的shell写了快200行了,蛋疼,代 ...

  3. Echarts 页面多图自适应的解决办法 (转)

    项目中用到了echarts的多图表的 问题,如果设置了 window.onresize  = option.chart.resize() 只能控制 某个图表的 自适应,如果要是页面上的图表都要自适应. ...

  4. 序列化与反序列化成XML

    http://blog.itpub.net/12639172/viewspace-490786/ 现在XML都普遍的用到了很多地方,它的平台无关.方便.结构化.适用性的特点让人不得不去接受它,在C#中 ...

  5. RouteData

    [备忘]ASP.NET MVC中RouteData.GetRequiredString("key")方法和RouteData.DataTokens["key"] ...

  6. Java %c0%ae 安全模式绕过漏洞

    漏洞类型:安全模式绕过漏洞 漏洞描述:在Java端"%c0%ae"解析为"\uC0AE",最后转义为ASCCII低字符-".".通过这个方法 ...

  7. php如何发起POST DELETE GET POST 请求

    关于POST,DELETE,GET,POST请求 get:是用来取得数据.其要传递过的信息是拼在url后面,因为其功能使然,有长度的限制 post:是用来上传数据.要上传的数据放在request的he ...

  8. Python开发【第二篇】:初识Python

    Python开发[第二篇]:初识Python   Python简介 Python前世今生 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏 ...

  9. 对AccessViolationException的一些总结

    引言 开发Winform程序时,应用程序出现了异常,整个应用程序崩溃自动退出了.在断点调试后,发现异常是AccessViolationException.所以对周围的语句加上了异常的处理机制.但是接下 ...

  10. Linux内核循环链表经典分析和移植

    为什么说这个链表做的经典呢,哥哥我从Linux内核里边儿扣出来的,要么怎么说内核不是一般人能写的,这代码太TM优美了! 这里有一篇参考文章:http://isis.poly.edu/kulesh/st ...