美文网首页
Mac环境下SVN快速入门

Mac环境下SVN快速入门

作者: 杨志聪 | 来源:发表于2020-04-04 14:35 被阅读0次

    和git一样,svn(subversion)作为一个版本控制系统,它主要实现的功能无非是三个:第一,保存你的项目文件,就算你的电脑不幸坏了,也能找回你的项目;第二,版本控制,像时光机一样让你在你的项目之前保存的版本里面自由穿梭;第三,团队协作,让多个人共同完成一个项目成为可能。

    下面在Mac系统中用命令行的方式简单演示一下svn上述的三大功能。

    架构

    在开始接触svn之前,先看一下svn的架构图:


    svn架构

    这个架构图中,上面一端是客户端程序,下面一端是Subversion仓库(后面简称仓库),整个图大致说明了客户端和仓库的通讯方式。我们从上往下看:

    图的顶部,是command-lineGUI client apps,代表我们使用svn的两种类型的客户端:命令行客户端或者图形界面客户端。这篇文章介绍的是命令行客户端的使用方式

    再往下看,是客户端访问仓库的三种方式:HTTP,SVN,LocalHTTP,SVN都是通过网络访问资源库的,Local就是直接访问本地的仓库。

    最下面,是Subversion Repository,也就是我们的仓库。

    svn是集中式的版本控制 (centralized version control)—有一个远程的主仓库, 仓库中存放了被版本控制的数据, 用户在本地操作数据的浅拷贝副本(而鼎鼎大名的Git是分布式版本控制系统)。

    保存项目文件

    在开始之前,先确认你的Mac里安装了svn。如果你安装了Xcode,Xcode会自动为你的Mac安装svn。

    终端指令(文章后面没有特别提示,都是终端指令):

    svn --version
    

    如果能看到svn的版本信息,说明你的电脑已经安装了svn。

    下面从创建仓库添加仓库用户将已有项目导入到仓库三个部分,演示如何用svn仓库来保存你的项目文件。

    创建仓库

    确认电脑安装了svn后,我们就来创建仓库。创建仓库使用的app是svnadmin,使用的指令是:

    svnadmin create [仓库路径]
    

    [仓库路径]指向一个空文件夹,使用绝对路径和相对路径都可以。假设我们设置的路径是/users/xiaoming/repos,上述命令执行完后,如果成功创建了仓库,/users/xiaoming/repos文件夹里应该会生成如下文件:

    README.txt conf       db         format     hooks      locks
    

    看到这些文件,代表我们的仓库创建成功了。

    配置用户

    仓库的使用者分为游客和用户两种类型。下一步,是要为仓库添加用户。进入文件夹/users/xiaoming/repos/conf,我们发现conf文件夹里有以下文件:

    authz          hooks-env.tmpl passwd         svnserve.conf
    

    其中passwd是配置用户信息的, authz是配置用户权限的,但默认情况下这两个文件是无效的,我们先要去同一目录下的svnserve.conf文件内进行修改,让这两个文件生效:

    使用vim编辑器打开svnserve.conf文件:

    vi svnserve.conf
    

    打开svnserve.conf文件后,我们发现里面一大堆的注释,关于svnserve.conf文件如何配置,这些注释写的很清楚,英文好的可以认真读一下。下面直接说一般情况下如何修改。

    首先,找到anon-accessauth-access这两个配置项,并取消它们的注释。anon-access配置的是游客访问仓库的权限,默认是只读;auth-access配置的是用户访问仓库的权限,默认是可读可写:

    anon-access = read
    auth-access = write
    

    然后,找到password-db配置,并去除注释。该配置默认的值是passwd,也就是前面我们说的配置用户信息的passwd文件。这样passwd文件就生效了。

    最后,找到authz-db配置,并去除注释。该配置默认的值是authz,也就是前面我们说的配置用户权限的authz文件。这样authz文件就生效了。

    保存退出,svnserve.conf文件就配置完毕了。下面我们就来添加用户:

    打开passwd文件:

    vi passwd
    

    里面也有很多注释,通过注释我们知道添加用户的格式是:

    # harry = harryssecrt
    

    比方说我们要添加两个用户:用户名xiaoming,密码xm666; 用户名tom,密码tom666;那么我们应该这么写:

    [users]
    xiaoming = xm666
    tom = tom666
    

    保存退出,我们就成功添加用户xiaomingtom了。

    前面在svnserve.conf文件中我们已经对游客和用户的权限进行了全局配置,但由于我们激活了authz文件,所以我们需要在authz文件中对用户的权限进行更详细的设置。

    打开authz文件:

    vi authz
    

    打开authz文件后,里面同样有很多注释,英文好的看注释也能大概知道怎么配置。authz文件能配置的信息主要是:

    1.添加组。例如和可以将xiaomingtom编为一组,并设置组名;

    2.指定用户在特定仓库路径的权限。例如,我们可以指定仓库中xxx/core这个文件夹,哪些用户可以读写,哪些用户只能读,哪些用户不可访问。

    例如,我要将xiaomingtom编为一组,取组名为developerdeveloper这个组可以读写仓库根目录下的所有文件;另外,我还要特别指明xiaoming不可访问根目录下的tom_only.txt文件。那么我们应该这么配置:

    #将xiaoming和tom编为一组,组名是developer
    [groups]
    developer = xiaoming,tom
    #在仓库根目录下,developer组的所有成员都能读写
    [/]
    @developer = rw
    #xiaoming不能访问根目录下的tom_only.txt文件
    [/tom_only.txt]
    tom = rw
    xiaoming = 
    

    [/]表示仓库的根目录,然后仓库的其他目录你应该知道怎么写了,比如根目录下的tom_only.txt文件就是[/tom_only.txt]

    在设置组名权限时,组名需要用@开头,上面设置developer组时是这样写的@developer = rwr表示只读,rw表示读写,留空表示不可访问。

    上传项目到仓库

    目前仓库已经创建好,也配置了该仓库的用户,但是现在仓库还是空的。假设我们现在已经有一个项目在/users/xiaoming/ios路径下, ios这个文件夹里是我们的项目文件。那么我们可以通过命令:

    svn import [项目路径] [仓库路径] --username=[用户名] -m '[信息]'
    

    [项目路径]就是你已经有的项目的路径,可以使用相对路径。需要特别说明的是[仓库路径],上面我们看架构图时,已经知道客户端和仓库通讯的方式有三种:1. HTTP;2.svnserve;3.Local。不同的通讯方式使用不同的通讯协议。对于Local的方式,仓库路径需要用file://开头,然后后面接上本地仓库的绝对路径。例如当前仓库的绝对路径是/users/xiaoming/repos,假设要把项目导入到仓库的ios文件夹里,那么仓库路径应该是file:///users/xiaoming/repos/ios[用户名]指定执行导入任务的用户。[信息]就是对你的这次导入写一点备注。

    那么导入已有的项目本地仓库的指令示例如下:

    svn import /users/xiaoming/ios file:///users/xiaoming/repos/ios --username=xiaoming -m 'initial import'
    

    通常我们不是只有一个项目。假设我还有一个android项目也需要使用svn进行版本管理,那么我们可以有两种方案:

    1. 再创建一个svn仓库;

    2. android项目也放到上述仓库中。

    是的,一个仓库是可以存放多个项目的,理论上可以存无限个项目。其示意图如下:

    仓库目录

    那么我们可以将我们的android项目也放到仓库的android目录中:

    svn import /users/xiaoming/android file:///users/xiaoming/repos/android --username=xiaoming -m 'initial import'
    

    至此,我们的仓库就大功告成了,你的项目就能保存在svn仓库里了。

    版本管理

    版本管理是最重要的功能了。下面从检出工作副本、提交版本和时光机三个部分演示版本管理功能。

    检出工作副本

    我们不会在仓库里工作,就算你想这么干,也不可能。因为就算你已经把项目导入到仓库,你发现在仓库里根本看不到你的项目。你发现你的仓库依然只有这些文件:

    README.txt conf       db         format     hooks      locks
    

    真正工作的地方,是工作副本。你需要从仓库检出工作副本,然后在工作副本上工作。检出工作副本的指令是:

    svn checkout [仓库路径] [项目路径] --username=[用户名] --password=[用户密码]
    

    这里再重复一次,客户端和仓库通讯的方式有三种:1. HTTP;2.svnserve;3.Local。和本地仓库通讯的协议是file://。所以从本地仓库检出工作副本的指令示例:

    svn checkout file:///users/xiaoming/repos/ios ./ios --usernae=xiaoming --password=xm666
    

    注意上面示例中,[本地路径]是可以使用相对路径的。这样就可以检出工作副本了,然后就可以在工作副本中愉快地开始你的项目了。

    提交版本

    首先,如果你在工作副本中创建了新的文件,新创建的文件是不会被svn进行版本管理的。需要使用如下指令添加到svn进行管理(下面的终端指令都是在你的工作副本中执行的):

    svn add [文件路径]
    

    然后,你可以使用:

    svn revert
    

    撤销你当前还没有保存的所有代码。

    当然你也可以:

    svn revert [文件路径]
    

    撤销指定文件还没有保存的代码。

    OK,现在你改了很多内容,你想看看你具体改了哪些,你可以在你的工作副本中使用如下命令来查看更改:

    svn status
    

    没有其他问题的话,就能提交提交新版本了:

    svn commit -m '[信息]'
    

    每次提交新版本后,你最好使用将你的工作副本更新到仓库的最新版本:

    svn update
    

    这里顺便一提svn提交版本的一个硬伤:如果你是通过网络来访问仓库,那么离线的状态下你是无法提交版本的(而隔壁家Git就没有这个问题)。

    时光机

    时光机,就是在不同的版本中切换。首先我们要知道当前有哪些版本:

    svn log
    

    输出:

    r3 | xiaoming | 2020-04-03 20:58:31 +0800 (五, 03  4 2020) | 1 line
    
    foo
    ------------------------------------------------------------------------
    r1 | xiaoming | 2020-04-03 20:03:59 +0800 (五, 03  4 2020) | 1 line
    
    initial import
    ------------------------------------------------------------------------
    

    上面日志输出了两个版本,其中r1r3就是它们的版本号。我们可以通过指令:

    svn update -[版本号]
    

    将工作副本切换到不同的版本,例如

    svn update -r1
    

    我们就能切换到版本r1

    多人协作

    多人协作,往往离不开分支。每人开辟自己的分支,在自己的分支上工作,就不会影响其他人的进度,等到分支的任务完成,就合并到主分支。合并主分支时,可能会和其他人修改了同一个地方,那么就会产生冲突,所以需要解决冲突之后才能顺利合并分支。

    分支示意图

    下面从创建分支合并分支两部分演示分支的使用。

    创建分支

    创建分支非常简单:就是用命令svn copy仓库中为项目创建一个副本。所以在svn中,分支就是一个副本(注意区别工作副本)。

    比如说,当前仓库中项目的位置是file:///users/xiaoming/repos/ios(本地仓库),准备把它拷贝到位置file:///users/xiaoming/repos/ios-branch-dev,那么指令是:

    svn copy file:///users/xiaoming/repos/ios file:///users/xiaoming/repos/ios-branch-dev -m 'create branch dev'
    

    那么,副本file:///users/xiaoming/repos/ios-branch-dev就是我们的分支了。

    那么怎么使用分支呢?因为分支其实是仓库中的一个副本,所以需要将这个分支检出工作副本,还是老样子,在工作副本中工作。假设要检出到本地的路径是/users/xiaoming/ios-dev

    svn checkout file:///users/xiaoming/repos/ios-branch-dev /users/xiaoming/ios-dev --username=xiaoming --password=xm666
    

    如果你要使用分支,仓库的目录结构最好调整一下。前面我们创建的仓库目录结构是:

    简单的仓库目录结构

    使用分支后,行业中比较推荐的目录结构是:

    推荐的目录结构

    之前我们直接在iOS文件夹里放我们的项目文件,但是使用分支后,建议改为在iOS文件夹里放两个文件夹:trunk文件夹和branches文件夹,trunk相当于主分支,branches文件夹里存放的是你的其他分支。

    合并分支

    前面我们通过svn copy的方式在仓库里创建了分支,而且在在本地检出了分支的工作副本。在分支工作副本上工作时,建议经常将分支工作副本仓库主分支合并一下,因为其他人可能已经更改了主分支,你需要通过合并来及时解决冲突,保证你的分支和主分支的同步。

    我们使用svn merge指令来合并分支:

    svn merge [仓库分支路径] [工作副本分支路径] 
    

    注意svn merge指令只能将仓库中的分支合并到工作副本的分支,而不能反过来将工作副本的分支合并到仓库中的分支。具体指令是:

    svn merge file:///users/xiaoming/repos/ios/trunk /users/xiaoming/ios-dev
    

    如果合并出现冲突,就需要先解决冲突。解决冲突有很多方式。假设我们使用手动解决冲突的方式,在出现冲突的文件中手动修改了出现冲突的地方。然后需要:

    svn resolve –accept working [出现冲突的文件的路径]
    

    取消冲突错误提示,然后才能:

    svn commit -m 'fix conflict'
    

    提交版本。

    现在我们知道怎么合并分支了。那么当分支的内容完成后,要将分支内容合并到主分支应该怎么做呢?

    前面我们知道,合并操作只能从仓库上的分支合并到工作副本的分支。所以我们先要检出主分支的工作副本,然后再和分支进行合并,具体操作这里就不再赘述了。

    远程仓库

    上面演示的都是本地仓库,那么怎样创建一个仓库,让其他人可以通过网络来访问呢?

    如果你已经通过上面的方法创建了一个本地仓库,那你只需要使用svnserve就能让你的仓库能够远程访问:

    svnserve -d -r [服务器目录] --listen-port [服务端口号]
    

    其中[服务端口号]可以缺省,svn默认监听端口3690。这里重点要说的是[服务器目录]。前面我们说过,如果你有多个项目需要使用svn进行版本管理,你可以创建一个仓库来存放所有项目,也可以创建多个仓库,一个仓库放一个项目。对于第一种情况,[服务器目录]就是你的仓库目录。对于第二种情况,建议把所有仓库放到同一个文件夹里,然后这个文件夹就是[服务器目录]

    上面我们使用的是一个仓库存放所有项目的情况,所以为该仓库开启远程服务的指令是:

    svnserve -d -r /users/xiaoming/repos
    

    这样我们的仓库就支持远程访问了。使用svnserve开启服务后,访问仓库的协议是svn://,所以访问仓库的路径是(在本地访问本地的远程仓库)svn://localhost/ios。假设你的电脑的IP是192.168.1.6,那么另一台电脑访问你电脑的远程仓库的地址是svn://192.168.1.6/ios

    参考文档

    svn功能非常强大,前面只是粗略地介绍一些基本知识和用法。需要深入了解svn的,可以去看一下《svn官方手册》,是中文的。

    相关文章

      网友评论

          本文标题:Mac环境下SVN快速入门

          本文链接:https://www.haomeiwen.com/subject/hrqzuhtx.html