###安装svn(centos)
一般情况下是已经安装过的
1 | svn --version |
如果上述命令没有查到svn,则需要安装
yum -y install subversion //经测试 yum -y install svn也行
安装成功之后检查是否正确安装。
版本控制系统的生命周期
创建版本库(creat)
版本库相当于一个集中的空间,用于存放开发者所有的工作成果。版本库不仅能存放文件,还包括了每次修改的历史,即每个文件的变动历史。
Create 操作是用来创建一个新的版本库。大多数情况下这个操作只会执行一次。当你创建一个新的版本库的时候,你的版本控制系统会让你提供一些信息来标识版本库,例如创建的位置和版本库的名字。
####检出(checkout)
Checkout 操作是用来从版本库创建一个工作副本。工作副本是开发者私人的工作空间,可以进行内容的修改,然后提交到版本库中。
####更新(update)
顾名思义,update 操作是用来更新版本库的。这个操作将工作副本与版本库进行同步。由于版本库是由整个团队共用的,当其他人提交了他们的改动之后,你的工作副本就会过期。
让我们假设 Tom 和 Jerry 是一个项目的两个开发者。他们同时从版本库中检出了最新的版本并开始工作。此时,工作副本是与版本库完全同步的。然后,Jerry 很高效的完成了他的工作并提交了更改到版本库中。
此时 Tom 的工作副本就过期了。更新操作将会从版本库中拉取 Jerry 的最新改动并将 Tom 的工作副本进行更新。
####执行变更(commit、rename)
当检出之后,你就可以做很多操作来执行变更。编辑是最常用的操作。你可以编辑已存在的文件来,例如进行文件的添加/删除操作。
你可以添加文件/目录。但是这些添加的文件目录不会立刻成为版本库的一部分,而是被添加进待变更列表中,直到执行了 commit 操作后才会成为版本库的一部分。
同样地你可以删除文件/目录。删除操作立刻将文件从工作副本中删除掉,但该文件的实际删除只是被添加到了待变更列表中,直到执行了 commit 操作后才会真正删除。
Rename 操作可以更改文件/目录的名字。”移动”操作用来将文件/目录从一处移动到版本库中的另一处。
####复查变化(status、diff)
当你检出工作副本或者更新工作副本后,你的工作副本就跟版本库完全同步了。但是当你对工作副本进行一些修改之后,你的工作副本会比版本库要新。在 commit 操作之前复查下你的修改是一个很好的习惯。
Status 操作列出了工作副本中所进行的变动。正如我们之前提到的,你对工作副本的任何改动都会成为待变更列表的一部分。Status 操作就是用来查看这个待变更列表。
Status 操作只是提供了一个变动列表,但并不提供变动的详细信息。你可以用 diff 操作来查看这些变动的详细信息。
####修复错误(revert)
我们来假设你对工作副本做了许多修改,但是现在你不想要这些修改了,这时候 revert 操作将会帮助你。
Revert 操作重置了对工作副本的修改。它可以重置一个或多个文件/目录。当然它也可以重置整个工作副本。在这种情况下,revert 操作将会销毁待变更列表并将工作副本恢复到原始状态。
####解决冲突(merge、resolve)
合并的时候可能会发生冲突。Merge操作会自动处理可以安全合并的东西。其它的会被当做冲突。例如,”hello.c”文件在一个分支上被修改,在另一个分支上被删除了。这种情况就需要人为处理。Resolve操作就是用来帮助用户找出冲突并告诉版本库如何处理这些冲突。
####提交更改(commit)
Commit 操作是用来将更改从工作副本到版本库。这个操作会修改版本库的内容,其它开发者可以通过更新他们的工作副本来查看这些修改。
在提交之前,你必须将文件/目录添加到待变更列表中。列表中记录了将会被提交的改动。当提交的时候,我们通常会提供一个注释来说明为什么会进行这些改动。这个注释也会成为版本库历史记录的一部分。Commit是一个原子操作,也就是说要么完全提交成功,要么失败回滚。用户不会看到成功提交一半的情况。
svn启动模式
基础命令
首先在服务端进行svn的相关配置
手动新建版本库
1 | mkdir /opt/svn |
利用svn命令创建版本库
1 | svnadmin create /opt/svn/runoob |
利用命令runserver启动服务
1 | runserver -d -r 目录 --listen-port 端口号 |
####配置介绍
-r 配置方式决定了版本库的访问方式
–listen-port 制定svn的监听端口,不加参数,svn默认监听3690
由于-r 配置方式的不一样,SVN启动就可以有两种不同的访问方式
方式一:-r直接指定到版本库(称之为单库svnserve方式)
1 | svnserve -d -r /opt/svn/runoob |
在这种情况下,一个svnserve只能为一个版本库工作。
authz配置文件中对版本库权限的配置应这样写:
1 | [groups] |
使用类似这样的URL:svn://192.168.0.1/ 即可访问runoob版本库
方式二:指定到版本库的上级目录(称之为多库svnserve方式)
1 | svnserve -d -r /opt/svn |
这种情况,一个svnserve可以为多个版本库工作
authz配置文件中对版本库权限的配置应这样写:
1 | [groups] |
如果此时你还用[/],则表示所有库的根目录,同理,[/src]表示所有库的根目录下的src目录。
使用类似这样的URL:svn://192.168.0.1/runoob 即可访问runoob版本库。
###svn创建版本库
####使用svn命令创建资源库
1 | [root@alitiger opt]# svnadmin create /opt/svn/runoob01 |
进入/opt/svn/runoob01/conf目录,修改默认配置文件配置,包括svnserver.conf、passwd、authz配置相关用户和权限。
####svn服务配置文件svnserver.conf
svn服务配置文件为版本库目录中的文件conf/svnserver.conf,该文件仅有一个[general]配置段组成(在ecs测试时有两个配置段[general][sasl])
1 | [general] |
1 | anon-access:控制匿名用户访问版本库的权限,取值范围是“write(可读可写)”、“read(可读)”和“none(无访问权限)”,默认值是read |
####用户名口令文件passwd
用户口令文件有svnserver.conf的配置项passwd-db指定,默认为conf目录下的passwd,该文件仅有一个[user]配置段组成
[user]配置段的配置行格式为:<用户名>=<口令>
1 | [users] |
####权限配置文件authz
权限配置文件有svnserver.conf的配置项authz-db指定,默认为conf目录中的authz。该文件有一个个[group]配置段和若干版本库路径权限段组成。
[group]配置段的配置行格式为:<用户组>=<用户列表>
版本库路径权限段的段名格式如下:[<版本库名>=<路径>]
1 | [groups] |
本例是使用svnsever -d -r /opt/svn 以多库的方式启动SVN, 所以URL为:svn://10.18.44.209/runoob01/
###svn检出操作
之前我创建了版本库runoob01,URL为svn://10.18.44.209/runoob01,svn用户tiger拥有读写权限,我们就可以在客户端通过这个URL对版本库进行版本操作。
svn checkout http://svn.server.com/svn/project_repo –username=user01 以上命令将产生如下结果(使用阿里云记得开端口默认3690端口):
1 | [root@alitiger ~]# svn checkout svn://10.18.44.209/runoob01 --username=user01 |
检出成功后在当前目录下生成runoob01副本目录。查看检出的内容
1 | [root@alitiger ~]# ll runoob01/ |
你想查看更多关于版本库的信息,执行 info 命令。
###svn解决冲突
版本冲突问题
假设 A、B 两个用户都在版本号为 100 的时候,更新了 kingtuns.txt 这个文件,A 用户在修改完成之后提交kingtuns.txt到服务器,这个时候提交成功,这个时候kingtuns.txt文件的版本号已经变成101了。同时B用户在版本号为100的 kingtuns.txt文件上作修改,修改完成之后提交到服务器时,由于不是在当前最新的101版本上作的修改,所以导致提交失败。
我们已在本地检出 runoob01库,下面我们将实现版本冲突的解决方法。
我们发现 HelloWorld.html文件存在错误,需要修改文件并提交到版本库中。
我们将HelloWorld.html的内容修改为”HelloWorld!http://www.runoob.com/"。
1 | [root@alitiger ~/svn/runoob01/trunk]# cat HelloWorld.html |
用下面的命令进行查看更改:
1 | [root@alitiger ~/svn/runoob01/trunk]# svn diff |
尝试使用下面的命令来提交他的更改:
1 | [root@alitiger ~/svn/runoob01/trunk]# svn commit -m "change HelloWorld.html first" |
这时我发现提交失败了。
因为此时,HelloWorld.html已经被five修改并提交到了仓库。Subversion 不会允许tiger(本例使用的svn账号)提交更改,因为five已经修改了仓库,所以我们的工作副本已经失效。
为了避免两人的代码被互相覆盖,Subversion不允许我们进行这样的操作。所以我们在提交更改之前必须先更新工作副本。所以使用update命令,如下:
1 | [root@alitiger ~/svn/runoob01/trunk]# svn update |
这边输入”mc”,以本地的文件为主。你也可以使用其选项对冲突的文件进行不同的操作。
默认是更新到最新的版本,我们也可以指定更新到哪个版本
1 | svn update -r6 |
此时工作副本是和仓库已经同步,可以安全地提交更改了
1 | [root@alitiger ~/svn/runoob01/trunk]# svn commit -m "change HelloWorld.html second" |
###svn提交操作
在之前,我们检出了版本库runood01,对应的目录放在/home/tiger/runood01中,下面我们针对这个库进行版本控制。
我们在版本库中,需要借助一个readme的说明文件,
1 | [root@alitiger ~/svn/runoob01/trunk]# cat readme |
查看工作副本中的状态。
1 | [root@alitiger ~/svn/runoob01/trunk]# svn status |
此时readme的状态为?,说明他还没有加到版本控制中
将文件readme加到版本控制,等待提交到版本库
1 | [root@alitiger ~/svn/runoob01/trunk]# svn add readme |
查看工作副本中的状态
1 | [root@alitiger ~/svn/runoob01/trunk]# svn status |
此时 readme的状态为A,它意味着这个文件已经被成功地添加到了版本控制中。
为了把 readme 存储到版本库中,使用 commit -m 加上注释信息来提交。
如果你忽略了 -m 选项, SVN会打开一个可以输入多行的文本编辑器来让你输入提交信息。
1 | [root@alitiger ~/svn/runoob01/trunk]# svn commit -m "SVN readme." |
现在 readme 被成功地添加到了版本库中,并且修订版本号自动增加了1。
###svn版本回退
当我们想放弃对文件的修改,可以使用 SVN revert 命令。
svn revert 操作将撤销任何文件或目录里的局部更改。
我们对文件 readme 进行修改,查看文件状态。
1 | [root@alitiger ~/svn/runoob01/trunk]# svn status |
这时候我们发现修改错误,要撤销修改,通过svn revert文件readme回归到未修改状态
1 | [root@alitiger ~/svn/runoob01/trunk]# svn revert readme |
再查看状态。
1 | [root@alitiger ~/svn/runoob01/trunk]# svn status |
进行revert操作之后,readme文件恢复了原始的状态。revert操作不单单可以使单个文件恢复原状,而且可以使整个目录恢复原状。恢复目录用 -R 命令,如下。
1 | svn revert -R trunk |
但是,假如我们想恢复一个已经提交的版本怎么办。
为了消除一个旧版本,我们必须撤销旧版本里的所有更改然后提交一个新版本。这种操作叫做 reverse merge。
首先,找到仓库的当前版本,现在是版本22,我们要撤销回之前的版本,比如版本 21。
1 | svn merge -r 22:21 readme |
###svn查看历史信息
通过svn命令可以根据时间或修订号去除过去的版本,或者某一版本所做的具体的修改。以下四个命令可以用来查看svn 的历史:
1 | svn log: 用来展示svn 的版本作者、日期、路径等等。 |
####svn log
可以显示所有的信息,如果只希望查看特定的某两个版本之间的信息,可以使用:
1 | [root@alitiger ~/svn/runoob01/trunk]# svn log -r 6:8 |
如果只想查看某一个文件的版本修改信息,可以使用svn log文件路径。
1 | [root@alitiger ~/svn/runoob01]# svn log trunk/HelloWorld.html |
如果希望得到目录的信息要加-v
如果希望显示限定N条记录的目录信息,使用svn log -l N -v。
1 | [root@alitiger ~/svn/runoob01/trunk]# svn diff |
####svn diff
用来检测历史修改的详情
1 | 检查本地修改 |
如果用svn diff,不带任何参数,它将会比较你的工作文件与缓存文件在.svn的’原始’拷贝
1 | [root@alitiger ~/svn/runoob01/trunk]# svn diff |
比较工作拷贝与版本库
比较你的工作拷贝和版本库中版本号为 3 的文件 rule.txt。
1 | svn diff -r 3 rule.txt |
比较版本库与版本库
通过 -r(revision)传递两个通过冒号分开的版本号,这两个版本会进行比较。
比较 svn 工作版本中版本号2和3的这个文件的变化。
1 | svn diff -r 2:3 rule.txt |
####svn cat
如果只是希望检查一个过去版本,不希望查看他们的区别,可使用svn cat
1 | svn cat -r 版本号 rule.txt |
这个命令会显示在该版本号下的该文件内容
####svn list
svn list 可以在不下载文件到本地目录的情况下来察看目录中的文件:
1 | $ svn list http://192.168.0.1/runoob01 |
###svn分支
Branch 选项会给开发者创建出另外一条线路。当有人希望开发进程分开成两条不同的线路时,这个选项会非常有用。
比如项目 demo 下有两个小组,svn 下有一个 trunk 版。
由于客户需求突然变化,导致项目需要做较大改动,此时项目组决定由小组 1 继续完成原来正进行到一半的工作(某个模块),小组 2 进行新需求的开发。
那么此时,我们就可以为小组2建立一个分支,分支其实就是 trunk 版(主干线)的一个copy版,不过分支也是具有版本控制功能的,而且是和主干线相互独立的,当然,到最后我们可以通过(合并)功能,将分支合并到 trunk 上来,从而最后合并为一个项目。
我们在本地副本中创建一个 my_branch 分支。
1 | root@runoob:~/svn/runoob01# ls |
查看状态
1 | root@runoob:~/svn/runoob01# svn status |
提交新增的分支到版本库。
1 | root@runoob:~/svn/runoob01# svn commit -m "add my_branch" |
接着我就到新增的分支进行开发,切换到分支路径并创建index.html文件
1 | root@runoob:~/svn/runoob01# cd branches/my_branch/ |
将index.html加入到版本控制,并提交到版本库中。
1 | root@runoob:~/svn/runoob01/trunk# svn commit -m "add index.html" |
###svn标签(tag)
版本管理系统支持 tag 选项,通过使用 tag 的概念,我们可以给某一个具体版本的代码一个更加有意义的名字。
Tags 即标签主要用于项目开发中的里程碑,比如开发到一定阶段可以单独一个版本作为发布等,它往往代表一个可以固定的完整的版本,这跟 VSS 中的 Tag 大致相同。
我们在本地工作副本创建一个 tag。
1 | root@runoob:~/svn/runoob01# svn copy trunk/ tags/v1.0 |
上面的代码成功完成,新的目录将会被创建在 tags 目录下。
1 | root@runoob:~/svn/runoob01# ls tags/ |
查看状态
1 | root@runoob:~/svn/runoob01# svn status |
提交tag内容
1 | root@runoob:~/svn/runoob01# svn commit -m "tags v1.0" |