前言

本来以为自己没有使用svn的机会,但是最近接手的一个项目是用svn管理的,不得不把svn这块补起来。
由于之前一直都是用git管理源码的,没有用过svn,一般来说,都是svn过渡到git很痛苦,因为git会比svn复杂,所以我想自己从git到svn,应该没有一点难度,但是结果是也没有我想象中那么丝滑顺畅

SVN

Linux有svn(subversion),Windows里面用Tortoise SVN这个GUI工具

从学习编程开始都是用git而完全没有用过svn,所以刚上手svn时就自然而然以git的思维来操作svn,基于之前习惯git flow/github flow的工作流,一上来就想切分支开发,然后合并回去测试,再合并到主分支发布。

但是首先拉取代码到本地这一步就不太一样,在git里面拉取线上代码到本地是git clone,而svn是svn co(checkout),checkout在git里面可是切分支的意思;

更新本地代码是用svn up(update),就可以把本地的代码和线上代码同步,在git里面就是git pull origin master;

而如果是本地修改提交,svn和git都是commit,不过svn是直接commit到repo上,但是git是commit到本地的repo,git如果要用push才能把代码更新到repo;

svn info查看当前分支信息,一般用来看当前分支的URL,git里面看分支是用git branch,至于看远程分支的URL则是git remote -v;

svn status查看代码修改情况,比如哪些文件发生了变化(add/delete/modify),配合svn diff可以查看具体修改了什么,这个和git status和git diff是一样的;

svn log -l 3查看最近三次commit,一般都会带上-l参数,因为svn不像git log那样会自动分页,svn log会打印全部的日志,这个在实际使用的时候非常不方便;

svn还有一个cp(copy),这个就真的是svn里面切分支的功能了,不过这个copy可没有git那么爽快,git checkout无论原分支有多大,都是秒切出新分支,但是svn切新分支是完整复制,所以如果原分支很大,那么每次switch都要等待它复制完成,这个可就有点傻了。而在原有分支里面来回切换,则需要svn switch,不像git那样checkout有多个功用;

有切分支,那就肯定有合并分支,svn也提供了merge的功能,但是由于svn切分支并非那么好用,故merge也少用了。我也问了几个在用svn的朋友,他们都不经常用svn分支和分支合并的功能,所以svn的merge我就不说了,有兴趣可以自己折腾;

回滚,无论是单文件还是版本,svn都是revert,但是git对单文件修改(未commit只是add)的是checkout,而版本回滚是reset;

svn会出现上锁这种奇葩的问题,解决办法就是unlock和cleanup换着来解决,unlock不行就cleanup,再unlock…

工作流

我所知道的关于svn实际上常用的实践是,trunk分支(也就是svn的主分支,相当于git的master分支)对应本地的一个目录,然后在线上创建一个trunk的副本——demo测试分支,然后checkout拉取这个demo到本地,本地提交都可以直接和demo打交道,而不用污染trunk主分支。当你觉得是时候发布的时候,就把demo对应的本地目录里面的文件复制到trunk对应的本地目录,然后直接以一次commit提交到trunk上(这可以是一次相当大量修改的commit)

P.s.上面这套工作流,在我看来十分的原始,比原始复制粘贴代码高明不了多少,因为merge这块并非自动的。而且在git本地只有一个目录,不用像svn多少个分支就多少个目录,git分支之间的切换都是用指针的,轻量高效多了;

在我没有用svn之前,总是听说svn比git在代码保密上更好更好:
首先先不论现在对于企业而言,值钱的应该是数据,过分地保护代码对代码分层,在web领域只是会拖慢开发,调试和测试的节奏,让一个项目开发起来很难受;
而其实就代码而言,只要能svn checkout到本地的代码,统统可以拷贝走,所以svn所谓的代码保密其实是建立在代码权限分层上,也就是部分代码能见不能checkout(文件可读性),当然我手上这个项目所有代码都可checkout到本地,所以没有接触过代码权限分层的情况。但是我不禁要问,都没有办法checkout到本地,那么我本地修改了文件,但是相关的依赖文件没有办法checkout到本地,我该如何调试?这调试又该有多不方便?

Pros & Cons

待补充

写在最后

我对svn的理解是,svn就是一个线上的apache起来的服务器,做成了一个类似网盘的功能,除此之外,别无其他;

svn在我看来是一个已经要逐渐退出时代的旧物了,如果不是还有一些老项目积重难返无法转移到git管理下,或者有些项目有大量的二进制文件(其实二进制文件已经有成熟的解决方案,比如图片那些完全可以使用图床,视频则可以专门setup一个视频服务器,然后向外提供url,没有必要和代码混在一起,把代码中对图片的引用换成url,那么git就可以接手了),其实是不会选择svn的,尽管git是相对于svn有点复杂,但是这种复杂程度在现在笔者写这篇博文的时候,也不算不上什么复杂的存在了,毕竟好多编辑写作都会用git做版本管理了,一个编辑都搞得懂,本来就做程序开发的难道还能说复杂么?

P.s.在正式开工前,建议弄熟代码管理和发布流程,这会让问题解决起来更加容易。只有容易debug和测试,一些复杂和看似不可解的问题就有方法可解决