SVN基本使用手册
安装服务器版的,且用默认的svnserve
1。下载安装:
在http://subversion.tigris.org/ 下载安装文件tar.gz。然后直接./configure; make; make install。具体在后面henkoo的文档中,可看到相关解释
2。客户端(windows下):
下载安装TortoiseSVN(http://tortoisesvn.tigris.org )。安装完毕后直接通过鼠标右键使用。
3。配置连接SVN的用户:
先创建仓库:svnadmin create /path/to/repo
在repo下面的conf中有个文件svnserve.conf,做如下修改:
anon-access = none
auth-access = write
password-db = passwd
然后在passwd文件中添加用户名和密码,形如:user:passwd
4。启动svnserve:
svnserve -d //后台方式启动
基本操作(windows下的):
用右键都能完成,比较简单。这里需要注意URL的写法:
Schema | Access Method |
---|---|
file:/// | direct repository access (on local disk) |
http:// | access via WebDAV protocol to Subversion-aware Apache server |
https:// | same as http://, but with SSL encryption. |
svn:// | access via custom protocol to an svnserve server |
svn+ssh:// | same as svn://, but through an SSH tunnel. |
以svn://为例:svn server的ip为192.168.0.213,目录是/home/svn/repository,则有:
svn://hostip/home/svn/repository
以下是henkoo的SVN笔记,版权所有,转载请注明地址(http://my.donews.com/henkoo/2006/03/13/svn-tutorial/ )
SVN: 使用说明(很基本和初级的使用说明)
SVN: 使用说明(很基本和初级的使用说明)
文档创建时间 :2006-2-23
适用说明 :
server : linux rh9 + subversion 1.2.3 , client : windows + TortoiseSVN 1.3.0
更多信息参考官方网站的文档和src包里的文档(INSTALL等)
补充:
中文站:http://www.subversion.org.cn (里面游svn-book的翻译)
--- Content ---
SVN安装
SVN管理
创建repository
启动svnserve
设置访问用户名和口令
项目中repos布局
SVN使用
svn使用基本流程
使用branches
merge操作的实质
版本(Revision)关键字
忽略列表(ignore-list)
解决冲突(conflict)
SVN安装 :
1. 去官方网站下tag.gz文件,tag.gz里包含了svn(subversion的客户端),svnserve(subversion自己的小型server,用于独立于apache使用),svnadmin(repository的管理工具)等
2. svn网络工作模式有两种(参考svn-book:Chapter6:Server Configuration:Overview):apache+mod_dav_svn和svnserve,这里选择使用svnserve模式,并且也不做ssl的支持。
3. 新建一个系统用户svn:svn(username : group)
4. ./configure
这里不用设置path,是希望在任何时候使用svn(或相关的svnserve等)时,可以直接用到,因为默认的安装,将可执行文件放在了/usr/local/bin这个默认的PATH里了
5. make
6. make install
至此安装完毕。
SVN 管理 :
这一部分主要是指管理repository,使用svnadmin等。
首先使用svn登录系统。下面的操作都在svn的主目录里进行。
1. 使用
$ svnadmin help
$ svnserve help
可以查看svnadmin和svnserve的帮助信息。
2. 创建repository
2.1 可以把所有的项目都放在一个repos里,
/path/to/repos/ProjectA,
/path/to/repos/ProjectB
然 后每个项目下再建立各自的trunk,branch,tag(这三个东西的含义参考svn-book:Chapter4:Branching and Merging,或者继续阅读下面的branch部分知道一个基本的意思)。这样的好处是对于svn使用时帐号的管理及其他一些hooks(此概念参考 svn-book:Chapter5:Repository Administration: Repository Creation and Configuration:Hook Scrips)等可以共享,管理起来只需一次,代价是灵活性可能不够或者达到某种灵活性需要复杂配置。
也可以每个项目建立独立的repos
/path/to/ProjectArepos
/path/to/ProjectBrepos
当然每个下面也建自己的trunk,branch,tag等。这种设置的好处显然就是有足够的灵活性,但是管理工作就多一些,特别是当有几个项目的设置相同时,修改了一个,就要修改其他的。
现在我的习惯是第二种,即每个项目有自己的repos,因为只是个人的简单的使用,做完一个算一个。
2.2 使用
$ svnadmin create /path/to/repos
默认创建的是FSFS型的repos,还有BerkerleyDB型的,使用--fs-type来指定类型。
$ svnadmin create --fs-type fsfs /path/to/repos
$ svnadmin create --fs-type bdb /path/to/repos
关 于FSFS和BerkerleyDB的内容参考svn-book:Chapter5:Repository Administration: Repository Basics:Repository Data Stores。看起来FSFS更好一些,而且Windows下好像FSFS麻烦更少。
现在假设项目名称叫MIS,建立repos如下:
$ svnadmin create –fs-type fsfs /home/svn/mis
这样svnadmin就生成了mis目录,其下还有许多辅助目录。这些目录的说明可以在svn-book:Chapter5:Repository Administration: Repository Creation and Configuration下找到。
其中/home/svn/mis/conf是这个repos的配置文件存放的地方,/home/svn/mis/hooks是hooks脚本的存放位置。
3 启动svnserve。 使用
$ svnserve -d -r /home/svn
来启动svnserve。其中-d参数是让svnserve以deamon模式运行在后台,-r参数使得客户端只能访问到后面指定的目录以下的内容(这里是/home/svn下的内容)。
4 设置访问用户名和口令
/home/svn/mis/conf里是mis这个repos的配置文件,svnserve.conf是主配置文件,默认的里面有(记得打开[general]前的注释,并且让[general]位于行首)
[general]
anon-access = read
auth-access = write
password-db = passwd
等
文档有良好的注释
这里将anon-access的访问权限从read改为none,然后就可以在passwd(password-db指定的,这里位置为/home/svn/mis/conf/passwd)里配置帐号和口令了。
在/home/svn/mis/conf/passwd里[user]下加入下面一行
deller = dellerpwd
这样就可以用deller:dellerpwd来访问了。
关于配置文件的更多信息,可以参考
$ man svnserve.conf,
google可以查到此页的翻译(目前在http://cmpp.linuxforum.net/cman-html/man5/svnserve.conf.5.html )
还有svn-book:Chapter7 Advanced Topics:Runtime Configuration Area:Configuration Options
5. 项目中repos布局
根据实践经验,一个项目的生存周期也不是单线的,常常有一些分支(分支剧情?)或者 稳定版发布或者特定功能的实验性加入等事件,repos的布局需要进行一定设计来支持这些“事件”。常见的布局是这样的
Project/trunk
Project/branches
Project/tags
trunk是项目主体存放位置
branches是项目的各种分支的存放
tag往往用于公开发布的版本的存档,类似与milestone。
(trunk,branch,tag这三个东西的含义参考svn-book:Chapter4:Branching and Merging)
建立这样的布局的方法有许多,svn-book上说可以用svn mkdir等命令逐一建立,然后提交。还有一个比较便捷的方法如下(使用svn import):
$ mkdir tmpdir
$ cd tmpdir
$ mkdir trunk
$ mkdir branches
$ mkdir tags
…
$ svn import . file:///path/to/repos --message 'Initial repository layout'
说明:
a. 这里仍然是按照前面的一个项目一个repos来做的,如果是多个项目共用一个repos时,就要在tmpdir下先建立这些项目,再在其下建立各自的trunk等
b. 注意最后的svn import一句中的file://这是不可少的,因为这个操作是在repos的服务器端,这样做Initial repository import时,可能svnserve没有启动,但是由于svn支持本地直接访问,所以可以完成,而这时,就是通过“file://”来告诉svn目前是 在操作本地repos的,比如linux下,/home/svn/mis为一个repos,那么应该写为“file:///home/svn/mis”
6. repos的删除,注意不是清空。
可能有svnadmin的命令吧,但其实只要删掉repos的目录就完全删除了,比如
$ rm -rf /home/svn/mis
7. 更多的管理功能包括 :
repos的查看(svnlook),repos的清除、恢复、备份、迁移(svnadmin)等主题,可以参考svn-book:Chapter5 Repository Administration
SVN使用:
1. 首先
是安装TortoiseSVN这个Win下的客户端(当然用subversion自己的svn这个客户端也可以完成所有操作,理论上)。这个客户端是集成到Explore里的,所以没有什么独立的窗体,所有操作右键菜单来完成。
2. svn使用基本流程:
下面说的命令都与TortoiseSVN菜单上的名称一致。
a. 初次(initial)取出(checkout)repos,建立本地工作拷贝(WC WorkingCopy)。
b. 与repos同步(update),保证将要进行的编辑是最新版本。
c. 编辑源代码(包括创建、修改、删除)。
d. 与repos同步(update),提交之前先要同步到最新的版本,保证所有在自己之前的有关提交已经在本地有所知晓。
e. 解决冲突(resolve conflict)。
f. 提交(commit),一定要写上这次提交的内容的摘要,便于以后查阅。
g. 继续b。
每次开始新的编辑前的同步repos很重要,另外经常地update没有坏处,特别是多人项目中。如果每次提交(commit)前不进行更新(update)的到最新的版本的话,svn会提示当前的拷贝过期,需要更新。
在 使用的过程中,时刻注意当前的工作拷贝(WC WorkingCopy)所对应的URL很重要,特别是当有了branches和tag等时候。使用svn info可以查看到这些信息。使用TortoiseSVN时,通过下面的操作查看这些信息:右键单击工作拷贝的根文件夹(不是上级文件夹),菜单中选择则 属性(不是TortoiseSVN那个菜单),然后在出现的对话框中选择Subversion标签就可以看到了。
3. 使用branches
(关于branches的内容可以在svn-book:Chapter4 Branching and Merging得到)
当 多个人合作(Sally和John)时,可能有这样的情况出现:John突然有个想法,跟原先的设计不太一致,可能是功能的添加或者日志格式的改进等等, 总而言之,这个想法可能需要花一段时间来完成,而这个过程中,John的一些操作可能会影响Sally的工作,John从现有的状态单独出一个 project的话,又不能及时得到Sally对已有代码做的修正,而且独立出来的话,John的尝试成功时,跟原来的合并也存在困难。这时最好的实践方 法是使用branches。John建立一个自己的branch,然后在里面实验,必要的时候从Sally的trunk里取得更新,或者将自己的阶段成果 汇集到trunk中。
附:TortoiseSVN帮助里的branch的说明:
One of the features of version control systems is the ability to isolate changes onto a separate line of development. This line is known as a branch. Branches are often used to try out new features without disturbing the main line of development with compiler errors and bugs. As soon as the new feature is stable enough then the development branch is merged back into the main branch (trunk).
3.1 创建branch
(详细的解释参考svn-book:Chapter4 Branching and Merging:Using Branches:Creating a Branch)
实际是svn copy操作
$ svn copy SourceURL/trunk
DestinationURL/branchName
-m "Creating a private branch of xxxx/trunk."
TorToiseSVN 操作更为简单,只要在working copy里右键空白,然后在TorToiseSVN菜单中选择Branches/Tags,就可将整个目录分支(branch)出去,或者点击某个文件将 文件单独分支(branch),而且有多种选择,指定是“直接在服务器端copy HEAD版本”、“直接在服务器端copy指定版本”(这两种相当于svn copy中源和目的都是URL)、“用当前的工作拷贝(WC Working Copy)生成”。同时还有一个checkbox用于在完成了这次分支(branch)后直接切换(switch)当前的工作拷贝(WC Working Copy)到分支。
3.2 使用merge来应用branch的修改
3.2.1 trunk的变化及时更新到branch
例子原型出自svn-book:Chapter 4:Branching and Merging:Copying Changes Between Branches:Copying Specific Changes
接 着前面的例子,John在实验过程中,Sally对原有的某个文件做了一些改动,如拼写检查等,John知道了,希望将这些改动也放到自己的当前的工作拷 贝(WC Working Copy)中。svn中使用merge指令来完成。假设Sally的修订使repos从Rev345到了Rev346,所以John就是要将 Rev345:Rev346(前:后)的变更应用到当前的WC。使用TortoiseSVN的操作就是在WC中右键空白处,然后在相关菜单中选择 “Merge...”,在弹出的对话框中,From指定比较前项的位置和版本(这里是trunk的Rev345),To指定后项的位置和版本(这里是 trunk的Rev346,可以使用一个复选框使的To的位置与From相同)。
相应的svn merge指令参考后面“merge操作实质”可知。
3.2.2 branch最终合并回trunk
例子原型出自svn-book:Chapter 4:Branching and Merging:Common Use-Cases:Merging a Whole Branch to Another
John经过尝试,终于实现了想法,并通过测试,现在他决定将所有的工作合并到trunk去。
这 里要注意的是,John打算合并的是自己的工作,假设John的branch(johnBranch)开始于Rev233,John的工作提交到 repos是Rev289,那么John的工作是将johnBranch:Rev233到johnBranch:Rev289的内容合并到trunk。而 不是johnBranch:Rev233到trunk:HEAD,因为这个变化包含了对John工作的增加和对trunk中其他人的工作的撤销(如果 John没有及时将他人在trunk的工作合并到自己的johnBranch的话)。
TortoiseSVN的操作是这样的,先checkout 出trunk(也可以switch到trunk),即保证当前的工作拷贝(WC WorkingCopy)是trunk,然后使用菜单中的“Merge...”,选择From为johnBranch:Rev233选择To为 johnBranch:Rev289。
相应的svn merge指令参考后面“merge操作实质”可知。
3.2.3 merge操作的实质
svn merge命令的原型如下
svn merge sourceURL1[@N] sourceURL2[@M] [WCPATH]
svn merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]
svn merge -r N:M SOURCE[@REV] [WCPATH]
In the first and second forms, the source paths (URLs in the first form, working copy paths in the second) are specified at revisions N and M. These are the two sources to be compared. The revisions default to HEAD if omitted.
In the third form, SOURCE can be a URL or working copy item, in which case the corresponding URL is used. This URL, at revisions N and M, defines the two sources to be compared.
WCPATH is the working copy path that will receive the changes. If WCPATH is omitted, a default value of “.” is assumed, unless the sources have identical basenames that match a file within “.”: in which case, the differences will be applied to that file.
可以看出merge实际是比较前后(源:目的)两个版本 (revision)之间的差别(用运算符就是 目的 – 源),然后将这些差别应用(施用)到工作拷贝(WC WorkingCopy)上的一个操作,根据源与目的版本号的先后,出现了“合并”、“撤销”(源版本号大于目的版本号)等不同效果,然后通过提交 (commit)来将这些效果保存到服务器端的repos中。
4. 版本(Revision)关键字
HEAD, BASE, COMMITTED, PREV是指定版本号时可以使用的一些保留字,含义如下:(参考svn-book:Chapter3:Guided Tour:Revisions:Numbers,Keywords)
HEAD:The latest revision in the repository.
BASE:The “pristine” revision of an item in a working copy.
COMMITTED:The last revision in which an item changed before (or at) BASE.
PREV:The revision just before the last revision in which an item changed. (Technically, COMMITTED - 1.)
说明:
a. 只有HEAD能用于URL,BASE,COMMITTED,PREV都是用于工作拷贝(WC Working Copy)的。
b. HEAD虽然含义是“当前最新的版本”,但用于WC时,当前未提交(即未进入版本管理)的变化是不包含在内的。所以比如:
刚 commit过main.txt为Rev10,即HEAD=10,COMMITTED=10,这时对main.txt进行一些编辑,然后svn diff -r HEAD:COMMITTED,不会显示刚刚的编辑操作,因为刚刚的编辑操作并没有纳入到版本管理,即HEAD没有反映出“当前最新”,实际是反映的“当 前版本管理中的最新”。
c. BASE的含义,上面的英文说得不够清楚,其实是指最后一次更新(update)操作 或者 取出(checkout)操作(当initial checkout)时取出的那些文件,这些被svn无修改地保留在.svn管理目录里。
5. 文件的添加、删除、重命名
当向项目里添加了一个新文件时,需要使用TortoiseSVN菜单中的“add”指令来为下一次commit做添加文件的准备,使得下次commit时知道有这样的事件发生。对应的svn命令行操作就是svn add。
当从项目里删除文件时,也需要显示地将这个事件告诉svn,方法就是右键单击要删除的文件,在TortoiseSVN菜单中选择删除,而不是简单地用os的删除。
文件重命名与删除同理。
6. 忽略列表
比 如一个VC的项目用subversion管理,vc会生成debug目录,release目录以及其下的编译临时文件,而我们可能只需要对源文件进行版本 管理,那些临时文件都不关心,这时可以把他们加入ignore list。同样使用TortoiseSVN菜单完成这个。对于错误的加入到了ignore list的文件,可以在TortoiseSVN菜单中的Remove from ignore list撤销。这个暂时不知道svn对应的命令。
7. 解决冲突(conflict)
所 谓冲突,简单地说,就是两个人改了同一个地方,而修改又不同。比如Sally和John同时Update到了最新的trunk,Rev5。Sally吧 main.txt的第一行改为了x=5,提交了,然后repos到了Rev6,同时John在自己的工作拷贝(WC WorkingCopy)中,把main.txt第一行改成了x=6,然后准备同步(update)repos然后提交,可是在update的时候就会提 示出现了冲突(conflict)。这时svn目录下出现了几个文件:main.txt.mine, main.txt.r5, main.txt.r6
按照svn-book的解释,含义如下:
filename.mine : This is your file as it existed in your working copy before you updated your working copy—that is, without conflict markers. This file has your latest changes in it and nothing else. (If Subversion considers the file to be unmergeable, then the .mine file isn't created, since it would be identical to the working file.)
filename.rOLDREV : This is the file that was the BASE revision before you updated your working copy. That is, the file that you checked out before you made your latest edits.
filename.rNEWREV : This is the file that your Subversion client just received from the server when you updated your working copy. This file corresponds to the HEAD revision of the repository.
其实就是main.txt.mine是John执行update之前的本地文件main.txt,main.txt.r5 是本地上次update时得到的,即BASE版,而main.txt.r6是这次update得到的。这时还有一个main.txt文件其实是包含了相互 冲突的内容的用于手工解决冲突的文件。
解决冲突有三个方法:
a. 手工解决。
编辑main.txt,保存其成为最终希望的版本。然后使用svn resolved去掉conflict标志。TortoiseSVN的操作这次要复杂一些,在main.txt上右键,菜单中选择 “resolved...”,在弹出的对话框中右键main.txt,然后在对话框中选择“resolved”,tortoiseSVN会要求确认一次, 选择yes之后会发现生成的三个临时文件没有了,而main.txt的冲突标记变成了修改。
b. 直接选用使用一个临时文件。命令行相当于这样:
$ cp main.txt.mine main.txt
然 后同样要用svn resolved去掉conflict标志。这个方法的TortoiseSVN的操作是在“resolved”对话框里,右键main.txt的菜单上选 择“Resolved conflict using mine”或者“Resolved conflict using theirs”
c. 撤销更改。这是John决定放弃自己对main.txt的更改并且接受Rev6版时的做法。用这种方法,如果是用svn这个client时,无需调用 svn resolved了,因为不打算提交新的内容到repos(当然如果其他的resolve决定提交新的内容时,还要对其他文件resolved的)。 TortoiseSVN里的操作是在冲突菜单(resolved对话框里右键单击要解决冲突的文件时出现的菜单)里选择Revert,同样 tortoise会让要求确认一次。
当有多个conflict时,需要一个一个resolve,TortoiseSVN的Resolved对话框里每次都是对一个对象进行操作,尽管前面的有复选框(复选框作用未知,猜测是跟lock有关)。