SVN工作原理
一.SVN的工作模型:Subversion缺省使用复制-修改-合并模型
实际上是文件共享的问题,目前有两种策略:A.锁定-修改-解锁模型有一点问题就是限制太多,经常会成为用户的障碍:
锁定可能导致管理问题。有时候Harry会锁住文件然后忘了此事,这就是说Sally一直等待解锁来编辑这些文件,她在这里僵住了。然后Harry去旅行了,现在Sally只好去找管理员放开锁,这种情况会导致不必要的耽搁和时间浪费。
锁定可能导致不必要的线性化开发。如果Harry编辑一个文件的开始,Sally想编辑同一个文件的结尾,这种修改不会冲突,设想修改可以正确的合并到一起,他们可以轻松的并行工作而没有太多的坏处,没有必要让他们轮流工作。
锁定可能导致错误的安全状态。假设Harry锁定和编辑一个文件A??Sally锁定并编辑文件B,如果A和B互相依赖,这种变化是必须同时作的,这样A和B不能正确的工作了,锁定机制对防止此类问题将无能为力—从而产生了一种处于安全状态的假相。很容易想象Harry和Sally都以为自己锁住了文件,而且从一个安全,孤立的情况开始工作,因而没有尽早发现他们不匹配的修改。
B.复制-修改-合并(CVS,SVN采用)
在这种模型里,每一个客户读取项目版本库建立一个私有工作副本—版本库中文件和目录的本地映射。用户并行工作,修改各自的工作副本,最终,各个私有的复制合并在一起,成为最终的版本,这种系统通常可以辅助合并操作,但是最终要靠人工去确定正误。
二。分支的概念
我们再来看一下SVN管理中分支的概念。版本控制系统的一个特性是能够把各种修改分离出来放在开发品的一个分割线上。这条线被称为分支。分支经常被用来试验新的特性,而不会对开发有编译错误的干扰。当新的特性足够稳定之后,开发品的分支就可以混合回主分支里(主干线).
版本控制系统的另一个特性是能够标记特殊的版本(例如某个发布版本),所以你可以在任何时候重新建立一个特定的构件和环境。这个过程被称作标记。
分支中最重要的概念就是独立于主干进行开发,在合并前,不同分支提交的代码互相不可见,互不干扰。但是主干持有所有分支的版本记录,因此主干可以合并分支。比较适用不同团队独立开发各自模块。另外在分支合并的时候需要做回归测试
三。版本库的布局
SVN管理中版本库的布局情况,svn文档是有推荐的目录结构,适用大多数情况:)当然理解了分支的概念,心中有剑也无需受此限制。
如果一个版本库包含多个项目,人们通常按分支来安排布局:
- Therearesomestandard,recommendedwaystoorganizearepository
- .Mostpeoplecreateatrunkdirectorytoholdthe“mainline”ofdevelopment,abranchesdirectorytocontainbranchcopies
- ,andatagsdirectorytocontaintagcopies.Ifarepositoryholdsonlyoneproject
- ,thenoftenpeoplecreatethesetop-leveldirectories:
大致用法如下:
traceview项目有两个开发人员wya,htyoung,同时htyoung做为项目管理员.
1.项目开始时htyoung在trunk创建了最初的文件这个作为mainline,然后用
svncptrunktags/first_init
svncptags/first_initbranches/wya
svncptags/first_initbranches/htyoung
创建工作文件夹,我们的开发人员wya,htyoung只在他们的开发文件夹branches/wya,branches/htyoung内工作,也就是commit.
2.一段时间后由项目管理员(htyoung),merge所有的修改到主线trunk上,同时htyoung和wya同主线同步.
3.再过一段时间我们发布0.1版本,为了有一个记录项目管理员(htyoung)用以下命令建了一个tags
svncptrunktags/Release0.1.0
4.这时又有一个开发人员JRD来了,项目管理员(htyoung)基于0.1给她建了一个工作分支svncptags/Release0.1.0branches/jrd
5.在我们发布完0.2时来了一个测试员TA,我们用以下命令为TA建一个工作文件夹
svncptrunktags/Release0.2.0
svncptags/Release0.2.0branches/ta。
重要:
SVN不是记录每一个版本的实际内容,只是记录版本间的差异
SVN使用延迟拷贝来实现svn copy,其只是原始文件的一个链接,对拷贝的修改被svn记录为相对于原始文件的修改
SVN 基本命令
1.创建存储库
假设d:/dev/svnrepo为存放svn存储库的目录
svnadmin create d:/dev/svnrepo/test 创建一名为test的存储库
2.导入项目
假设你的项目在d:/dev/eclipse中的Test文件夹,你的当前目录为d:/dev/eclipse,你的svn存储库路径为http://localhost/svn/test
svn import Test http://localhost/svn/test/OnlyTest -m "Initial Import"
解释:导入的是Test文件夹下的内容 ;另外,注意要起一个路径名OnlyTest,否则全导入到http://localhost/svn/test下了;-m 为日志
3.导出项目
svn export <项目文件夹> <你的文件夹>
svn export -r <version> <项目文件夹> <你的文件夹>
-------------------------
4.取出
svn co(checkout) http://localhost/svn/test/OnlyTest --- 将OnlyTest文件夹其下的文件取出来并建立默认文件夹OnlyTest
svn co -r <url> -- 取出特定版本
svn co http://localhost/svn/test/OnlyTest MyTest -- 将OnlyTest文件夹下的文件取出,放入新建立的文件夹MyTest中
5.添加
svn add * -- svn会将未纳入版本控制的文件加入版本控制中(必须svn commit)
svn add --non-recursive * 非递归添加
6.删除
svn delete(rm,remove,del) <filename> -- 删除文件和目录(必须svn commit)
7.提交
svn commit -m "you log" -- 提交
svn commit --changelist <changelist name> -- 提交指定的changelist
8.创建目录
svn mkdir <dirname>
svn mkdir <url>
9.移动文件或目录
svn move <source_name> <dist_name>
svn move <source_url> <dist_url>
10.输出特定文件或URL的内容
svn cat <file or url> -- 输出特定文件或URL的内容
svn cat -r <version> <file or url>
------------------------------
11.显示本地或远程某一文件或目录的详细信息
svn info <filename>
svn info -r <version> <filename>
12.列表
svn list(ls)
svn list -r <version>
13.当前目录或文件的状态
svn status <filename>
svn status --show-updates(或-u) 从项目存储库中找出哪些文件有更新
状态:
第一列:指出条目的状态
空 无改动
A 添加
C 冲突
D 删除
G 合并
M 修改
X 无版本记录,被svn:externals使用
? 未用版本控制管理
第二列:属性状态
空 无改动
C 冲突
M 修改
第三列:工作拷贝是否被锁定
空 未锁
L 锁了
14.清理
svn cleanup -- 递归清理工作拷贝
15.帮助
svn help
svn help <subcommand> -- 显示子命令的帮助,如:svn help add
-----------------------
18.锁定某一目录或文件
svn propset svn:needs-lock true <二进制文件> -- 设定需要锁[svn会将其设置为只读,提示用户编辑这个文件前先加锁]
svn lock <dir or file>
svn lock --force <dir or file> -- 强制对文件加锁,即使此文件已被别人加锁
19.解锁
svn unlock <dir or file>
svn unlock --force <dir or file> -- 可以解锁其他用户锁定的文件
20.显示特定文件和URL每一行的作者和修订版本信息
svn blame <file or url> -- 每一行文本在开头都放了最后修改的作者(用户名)和修订版本号。
svn blame -r <version> <file or url>
21.更新
svn update -r<version> -- 改变到某一个版本
状态:
A 添加 add
D 删除 delete
U 更新 update
C 冲突 conflict
M 合并 merge
22.找不同
svn diff <file> -- 找出工作版本和最后更新的版本中的不同
svn diff -c <version> <file> 查看文件<file>
在修订版本<version>修改的内容,是version和version-1比较
svn diff -r <version> <file> 察看你的工作拷贝对旧的修订版本<version>的修改
svn diff -r <version1>:<version2> <file> 使用范围符号来比较修订版本<version1>和<version2>
svn diff -r <version1>:<version2> <url>
svn diff --changelist <changelist name>
23.拷贝
svn copy <source> <dist> -- 其中source和dist既可以是工作目录文件也可以是url
如:svn copy foo.txt bar.txt
svn copy near.txt file:///tmp/repos/test/far-away.txt -m "Remote copy."
svn copy file:///tmp/repos/test/far-away near-here
svn copy file:///tmp/repos/test/far-away file:///tmp/repos/test/over-there -m "remote copy."
24. 显示提交日志信息
svn log -r <version> <path>
svn log -r <version1>:<version2> <path>
svn log <path>
svn log -r {iso8601日期} <path>
svn log -r {iso8601日期}:{iso8601日期} <path>
svn log -v <path> 显示详细的信息(包括每个版本有哪些文件有变动)
svn log --stop-on-copy <path> 得出分支是什么时候创建的
25.删除工作拷贝文件或目录的“冲突”状态(相关的冲突文件文件)
svn resolved <path>
26.取消所有的本地编辑
svn revert <path>
svn revert --recursive <path> 递归
27.解决冲突
svn resolve --accept <status> <path>
status:
base:选择你更新你的工作拷贝前的你checkout出的未经修改的版本
working:手工处理后,选择当前你工作拷贝中的版本
mine-full:选择在你svn update前的工作拷贝
theirs-full:选择svn update取出的文件拷贝
28.将文件放入到一个改变列表中
svn changelist(cl) <changelist name> <path1> <path2> <path...>
svn commit --changelist <changelist name> -- 只提交此change list的文件
29.版本号标识
(1)号 87
(2){日期} {2009-09-09}
(3)HEAD 存储库中最新版本
(4)BASE 工作拷贝中你最后签出的版本
(5)COMMITED 最后改动版本,等于或早于BASE
(6)PREV COMMITED之前的一个版本
30.产生和应用补丁
svn diff > file.patch
patch <options> file.patch
31.svn项目组织
project/
trunk/ --主干
branches/ --分支
tags/ --标签
32.常用示例
(1)提交改动
svn update -- 更新到项目的当前状态
# resolve conflicts 解决冲突
编辑文件
svn resolved
# run tests 运行测试
svn commit -m "your logs" -- 提交
(2)简单bug修正
a.在一个分支中修正bug并提交
b.将其合并到存在此bug的其他分支中(svn merge -r<version1>:<version2>)
(3)复杂bug修正
a.创建一个bug修正分支(svn copy) name=bug-trackid
b.为这个修正分支在修正前打标签(svn copy) name=bugpre-trackid
c.修正bug
d.为这个修正在修正后打标签(svn copy) name=bugpost-trackid
e.合并此bug修正到其他分支(svn merge -r bugpre-trackid:bugpost-trackid)
a) check out
svn checkout http://server/svn
即可在当前目录下建立一个工作拷贝,目录名是svn
b) update
使用命令svn update可以用服务器的版本更新你的工作拷贝
c) add
使用命令 svn add filename可以把filename这个文件或者目录以及目录下面的所有文件标志为添加状态(实际上它并没有立即添加,你可以查看服务器,这些文件都还没有添加进去的!),下一次你提交(commit)这些文件的时候,服务器就会把他们添加到版本库。
d) stat
使用svn stat可以查看文件状态(也就是是否被修改等)
e) commit
使用svn commit filename --message "leave words about this commit",可以提交本地修改到服务器。如果不使用--message选项,则svn会自动打开一个配置文件所指向的编辑器,里面默认有一些修改信息,你可以把这些信息作为附注提交到服务器。或者你也可以不使用--message而使用--file 来指定一个文件作为提交时的附注。
f) switch
有时候管理员修改了版本库的地址,比如修改了主机地址,修改了url等,此时客户端也需要相应的修改:svn switch --relocate http://xiao/svnhttp://xiao:81/svn第一个地址是原来的版本库地址(用svn info可以看到),后面的是新的版本库地址