SVN使用说明

本文讲述svn的基本使用规则,分支策略等主题,本文论述内容适用于1.2以后。

目录
介绍
svn特点
基本工作流程
分支


介绍
svn属于cs构架的源代码管理工具,服务器保存了所有版本的代码,每个开发人员从服务器check out出代码,修改代码完成某项工作以后checkin修改的代码,在服务器中会记录一个新的软件版本

一般来说一个项目会有一个独立的代码库,代码库的建立很简单,使用
svnadmin create命令记录即可,svn手册建议项目使用以下的目录结构
project
   trunk
   branches
   tags

trunk目录记录代码的主线,branches目录存放为了某个工作目的创建的分支,tags目录记录软件发行的某个版本


svn的特点:
1.全局版本号
svn的一个代码库只有一个版本号,初始版本号为0,以后不管哪个目录发生了commit,
都会产生一个新的版本号,比如一开始大家可能不习惯,但是其实这样的策略有一个好处,就是每次你在本地svn up的时候,如果发现了版本号增加,那么就是说别人在代码库上有了新的修改,你很可能需要合并这个新的修改

2.提交是原子的
每次提交多个文件修改的记录的时候,如果成功,都只会生成一条版本记录,相当于完成某项功能的一个patch,如果提交不是原子的,版本管理很难实现

3.分支标记都使用svn copy命令
svn的分支标志是很高效的,几乎是立刻完成,因为svn在新的分支和标记上只是引用了原来代码库中的对象,这个和命令名似乎不太相符,因此大家可以放心使用svn copy命令,
而不需要担心性能上的问题

4.缺乏merge tracking,合并的版本需要自己记录
这是频繁合并分支的代码树所必需注意的,具体工作下面有一些简要的叙述



基本工作流程
下面使用一个本地的代码库示例日常的svn使用流程
首先我们在本地建议一个库,访问本地的库无须用户验证
mkdir ~/expe
cd ~/expe
svnadmin create repos
在~/expe/repos建立了代码库

首先建立代码库的的基本目录结构
mkdir working_copy
cd working_copy
mkdir trunk branches tags
把干净的纯代码等需要版本控制的文件拷贝到trunk目录

svn import . file:///home/kkmao/expe/repos -m "init import"
这时代码库中的就包含了本地的目录结构,以及trunk下面的代码了

把本地的内容删掉,checkout出svn的一个版本出来,为什么本地的没用了呢,这是因为本地的内容里面没有.svn的目录,因此不是一个有效的workingcopy,需要svn checkout出一个有效的版本

svn co file:///home/kkmao/expe/repos/trunk .
注:svn co 是(svn checkout的简写)

现在你已经建立好了一个可以试验的working copy和库了,每个本地目录都会有一个.svn目录,该目录包含了完整的某一个版本的代码树,任何本地的修改都可以svn diff查看,该命令直接跟本地的这个cache进行比较,不会发生对库的访问,提高效率。


svn info可以看到你的本地和哪个库相连以及当前版本

路径:.
地址(URL):file:///home/kkmao/expe/repos/trunk
档案库 UUID:1d2627a1-0526-0410-8f90-b8b4839c1c87
修订版:1
节点种类:目录
调度:正常
最后修改的作者:kkmao
最后修改的修订版:1
最后修改的时间: 2007-01-02 10:38:59 +0800 (二, 02   1月 2007)


我随便做了两个文件,准备加到库里面,作为本地修改的一个示例
kkmao@Loongson:~/expe/workingcopy$ cat hello
hello word.
I am kkmao, who are you.
kkmao@Loongson:~/expe/workingcopy$ svn add hello
A       hello
kkmao@Loongson:~/expe/workingcopy$ cat README
why not read me????
kkmao@Loongson:~/expe/workingcopy$ svn add README
A       hello

add只修改本地内容,并没有提交

这个时候我准备提交(commit)我的更改了,首先我会运行svn update查看别人是否对代码进行了修改
kkmao@Loongson:~/expe/workingcopy$ svn up
于修订版 1。

up是update的简写,update的作用是把别人修改的代码先取到本地,上面的结果是没有人进行了修改。

为什么要先up呢,这是因为如果有冲突的话,应该在本地解决冲突以后,再进行commit,事实上你可以直接svn ci(commit),但是如果别人和你修改了同一个文件,svn也不会让你成功提交,还是需要先进行本地的update。

现在我已经可以commit了,我先查看一下我需要commit什么,基本的规则是,patch应该一个一个的commit
怎么做呢,我会先查看我本地修改了什么,使用status -u命令
kkmao@Loongson:~/expe/workingcopy$ svn status -u
A             0 hello
A             0 README
状态于修订版:     1

详细查看一下更改的内容svn diff hello,svn diff README,我发现这两个是无关的更改,他们属于两个不同的patch,应该单独提交
因此我提交了两次,并指明提交的文件
kkmao@Loongson:~/expe/workingcopy$ svn commit hello -m "add hello"
新增           hello
传输文件数据.
提交后的修订版为 2。
kkmao@Loongson:~/expe/workingcopy$ svn commit README -m "add README"
新增           README
传输文件数据.
提交后的修订版为 3。
kkmao@Loongson:~/expe/workingcopy$

例子中的-m的内容也太过简单,每次提交都应该有详细的comment,特别是对bug的修复,应该详细说明bug的产生原因,修复的道理等

从上面看到,应该勤commit,不要等到修改了一大堆文件以后,才想起来要commit。



分支与合并
分支就是在另外一个地方管理代码的版本,而不影响主线(trunk)的代码。分支的原因有很多,第一次使用svn都希望建立一个分支,然后在自己的分支上工作,相当于自己的独立的工作空间,这种工作方式没有错,但是svn支持并不是很好,需要编写comment的时候记录下每次合并代码的版本号,因此我认为目前分支最佳的实践是为某个工作目的创建一个分支,功能实现以后立刻在trunk中合并这个内容,分支的使命完成后就可以删除了。

分支其实很简单,就是copy一下
kkmao@Loongson:~/expe/workingcopy$ svn copy file:///home/kkmao/expe/repos/trunk file:///home/kkmao/expe/repos/branches/hi

提交后的修订版为 4。

现在你可以选择把那个hi分支check out出来修改,这样子很简单直接,也可以把本地switch过去,省一点网络带宽
kkmao@Loongson:~/expe/workingcopy$ svn info | grep URL
地址(URL):file:///home/kkmao/expe/repos/trunk
kkmao@Loongson:~/expe/workingcopy$ svn switch file:///home/kkmao/expe/repos/branches/hi
于修订版 4。
kkmao@Loongson:~/expe/workingcopy$ svn info | grep URL
地址(URL):file:///home/kkmao/expe/repos/branches/hi

这个时候你本地的working copy已经和新的URL发生联系了,所有的commit都朝向新的URL

ok现在我开始修改,就是把hello换成hi。
kkmao@Loongson:~/expe/workingcopy$ cat hello
hi word.
I am kkmao, who are you.

但是我发现我错了,其实我是想加一行hi,我觉得我改了太多了太乱了,索性恢复到我checkout时候的版本
kkmao@Loongson:~/expe/workingcopy$ svn revert hello
已恢复“hello”

我加了一行以后重新commit
kkmao@Loongson:~/expe/workingcopy$ cat hello
hello world.
hi world, heihei~~~
I am kkmao, who are you.

kkmao@Loongson:~/expe/workingcopy$ svn ci hello
正在发送    hello
传输文件数据.
提交后的修订版为 5。

这个时候我转回去,开始合并
kkmao@Loongson:~/expe/workingcopy$ svn switch file:///home/kkmao/expe/repos/trunk
U hello
更新至修订版 5。
kkmao@Loongson:~/expe/workingcopy$ cat hello
hello word.
I am kkmao, who are you.

当然我不急于合并,我添加一个文件模拟主线仍然进行着有序的开发
kkmao@Loongson:~/expe/workingcopy$ vim accessory
kkmao@Loongson:~/expe/workingcopy$ svn add accessory
A       accessory
kkmao@Loongson:~/expe/workingcopy$ svn ci -m "add accessory"
新增           accessory
传输文件数据.
提交后的修订版为 6。

OK,开始合并
合并的过程一开始比较难理解,其实简单的说就是把分支上面两个版本之间所作的修改作为一个patch,然后应用到你的本地上面
记住你比较的是分支的两个版本,比如说分支开发是从r10到r20,执行svn merge的效果相当于把r20到r10两个版本树做一个diff -urN生成一个patch,然后执行patch -p1命令。问题是怎么找出这两个版本呢?
首先我们找出我们是从那个版本开始分支的
kkmao@Loongson:~/expe/workingcopy$ svn log --stop-on-copy file:///home/kkmao/expe/repos/branches/hi
------------------------------------------------------------------------
r5 | kkmao | 2007-01-02 11:52:56 +0800 (二, 02   1月 2007) | 2 lines

add hi

------------------------------------------------------------------------
r4 | kkmao | 2007-01-02 11:43:08 +0800 (二, 02   1月 2007) | 4 lines

hello to hi

------------------------------------------------------------------------

也就是说我们从r4开始我们的分支,到r5完成,因此我们执行
kkmao@Loongson:~/expe/workingcopy$ svn merge -r 4:5 file:///home/kkmao/expe/repos/branches/hi
U hello
kkmao@Loongson:~/expe/workingcopy$ cat hello
hello world.
hi world, heihei~~~
I am kkmao, who are you.
完成了合并,注意所有的更改都在本地,应该提交一次,并且要记录合并的版本
kkmao@Loongson:~/expe/workingcopy$ svn ci -m "merge file:///home/kkmao/expe/repos/branches/hi -r 4:5"
正在发送    hello
传输文件数据.
提交后的修订版为 7。

如果hi分支仍然继续开发,请注意下次合并应该从r5开始,避免合并重复的内容s

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值