SVN 学习笔记(三 SVN高级操作 下)
认证和授权
?
在此之前,我们并没有提到SVN的安全方面的东西。并非说这不重要,而是因为根据不同的配置,可能我们会有不同的认证和授权。SVN提供三种配置。我们这里不详细说明。
?
首先,我们是可以通过网络来访问SVN库的。那么我们就需要通过一些网络协议。SVN支持HTTP(s), SSH等协议。这些协议中各自的认证授权又有不同。
其次,SVN利用操作系统的特性来缓存密码。也就是说,我们的密码是缓存在SVN服务器上的。当然有的还可能是明文。如果不想缓存,使用 --no-auth-cache?
在此,使用 --username --password选项来与服务器认证。--username 和 --password是两个全局选项,大多数的SVN命令都支持。
?
分支与合并
?
如果在某一个时刻,我们突然发现需要针对不同的需求,基于原来的代码开发一个新的东西,那么我们可能需要一个分支。
之前忘了说,我们的库中的目录布局,一般会创建两个目录,叫做Trunk 和Branches。
Trunk自然是主干,Branches 就是分支了。
?
?
首先创建分支:
$svn copy file:////repos/idp/trunk ?file:///epos/idp/branches/mybranch -m "shaoxin 's branches "
Commited revision 532
?
创建分支使用的是copy,注意这里,我们使用的是从库到库的copy,这样的速度是很快的。因为这只是一个Hard link
?
然后check到Working Copy
$svn checkout file://repos/idp/branches/mybranch
...
...
...
?
然后我们就可以在分支中大展身手了。注意,分支和主线共用一个版本历史。但是分支以后的历史,主线没有。在回头看看创建分支,很简单吧。Copy命令告诉我们,SVN的分支,其实就是一个普通目录而已。仅此而已。一个术语而已,对于分支到分支的复制,我们叫 Merging,使用svn merge来实现。
?
分支并非一直都这样分下去。如果我们的分支功能开发好了,那么也许主线觉得不错,那就合并过来吧。如果要合并,那么一个前提,我们要随时和主线保持同步,不然你突然重新合并分支,可能冲突就泛滥成灾了。下面说如何保证分支和主线同步。
?
之前说的,分支到分支的复制叫Merging,分支其实就是目录,那么目录到目录的复制就是merging,我们用svn merge,分支到主线也一样。
首先。确保自己在分支目录下。
$pwd
/home/madic/mybranch
然后开始merge吧。
$svn merge ?file:////repos/idp/trunk
...
...
...
同步完成,我们查看是否有冲突。
$svn status
...
...
..
如果有冲突,就解决冲突。一切OK,那我们提交
$svn commit -m "Merge lastest trunk change"
?
经过无数次同步,我们的分支终于不再开发了。我们也许想合并到主线。SVN叫做reintegrate
?
首先,更新主线
$svn update 主线目录
...
...
...
合并分支
$svn merge --reintegrate file:///repos/idp/branches/mybranch
...
...
...
提交
$svn commit -m "merge mybranche back into trunk"
...
...
...
?
完成合并后,分支是否要删除?
这是一个问题,但是有一点可以确定,分支不能再被使用。当然他的历史信息,是否是需要的呢?因为分支和主线的历史,一旦建立分支后,之后的历史他们是各自独立的。
如果此时我们又想念分支了,我们要在启用分支,那么很简单:
$svn delete mybranches
$svn copy trunk branch
$svn switch brances
这里 switch把我们切换到分支。Switch 是一个切换库的命令。这里我们要知道,分支实际上只是一个对主线的Hardlink,实际上我们在一个working copy,但是确实两个库同事管理。我们通过switch切换,那么我们在执行svn命令时,不指定库,默认的就是switch的那个库了。
?
Merge信息,我们可以通过 svn mergeinfo 来查看。
$svn mergeinfo ?/repos/idp/trunk
R341
R342
R343
这表示的已经合并的版本。
?
$svn merginfo /repos/idp/runk --show-revs eligible
R391
R392?
表示还可以合并的。eligible 还可以使用merged替换,表示已经合并的。
?
恢复删除
如果不小心删除了某个文件,而这个文件已经不再HEAD版本了。那么我们如何恢复呢?
方法一:
$svn copy ?/repos/idp/remove.c@807 ./remove.c
这表示在把808版本的remove.c恢复到当前目录
$svn status?
A ?+ ?remove.c ?
这里加号表示 从历史版本恢复,而不是新加的。
增加后要提交
$svn commit -m "rescurrected remove.c from r807" remove.c
Adding remove.c
...
...
如果我们不想要remove的历史信息了。可以用第二种方法。
$svn cat /repos/idp/remove.c@807 > ./remove.c
$svn add remove.c
$svn commit remove.c -m " rescurrected remove.c from r807" remove.c
?
?
既然可以从Working Copy添加,也可以直接拷贝到库。
$svn copy /repos/idp/remove.c@807 /repos/idp/
$ svn update
A ? remove.c
?
?
这里,我们可以看到一个URL或者PATH后面跟着@版本号。这是因为路径和URL并不是唯一指定一个文件的,因为我们的SVN是时光机,文件也是有时间的。好比某个房子里并不是一直住着一个人,时间不同,可能住的人不同。所以,我们使用@版本号来唯一确定一个历史文件。
?
稀疏目录
我们都知道checkout的功能了。但是实际上checkout远远不止这些。我们可以通过各种选项,使得checkout具有更多的功能,来符合我们的实际要求。
?
$svn checkout URL ---depth empty|files|immediates|infinity
?
--depth的参数
empty ?只包含目标文件或目录,不包含子目录
files ? ?只包含目标文件和子文件
immediates 只包含目标文件及相邻的文件,目录
infinity 所有文件,目录,子目录。
?
同样,我们在svn update的时候,也可以这样使用。
?
锁机制
?
我们前面提到,使用SVN的一种模式 Lock-Modify-Unlock。现在我们说说SVN的锁。
SVN有三种锁的概念。
避免多用户同时提交的锁
WorkingCopy的锁,组织多个Subversion同事操作一个WoringCopy
SVN库阻止多个程序并发访问的锁。
?
我们讨论的是如何与其他同事和谐开发的锁。也就是第一种锁。SVN对于二进制文件,是不能Merge的,所以我们在修改二进制文件时,如果不上锁,遇到冲突,那么是无法解决的。比如,我在修改一张图,而另外一个同事也在修改,即使我们可能修改的位置不一样,但是,也不可能合并。而且,如果我修改了半天,他突然提交了。那么我这半天的工作,就不能合并到SVN库中。这对于我的工作来说,只能是白费劲。
所以,在遇到一些二进制文件时,我们最好使用Lock-Modify-Unlock 机制。
?
$svn lock apple.jpe -m "Editing file for painting"
这样就锁住了文件。并且在本地有缓存了一个lock token
$svn info apple.jpg
...
...
Lock Token :opaquelocktoken:0c056006-88f9-03109e48
?
LockToken是公开的,以表面在某个WorkingCopy中某人锁住了文件。而不是一个异常。
?
LockToken跟随WorkingCopy的。如果你在办公室的WorkingCopy锁住了一个文件,那么你回到家的时候,你发现,你不能提交了。因为锁认证是需要两个条件:
?
你是锁的拥有者
你有LockToken
?
如果你在认证通过后,提交了文件,锁自动解开。并且,在同一个目录下的锁都会解开。当然,你如果只是提交一个功能,还想继续锁住,编写下一个功能,那么使用 --no-unlock
如果你不想提交,也不想锁住文件那么使用
?$svn unlock file
就可以解锁。
?
我们可以通过
$svn status -u
M ?O ?32 ?apple.jpg
O表示被其他人锁住了(other)。
?
如果你急需编辑文件,或者加锁的人渡假去了,而我们必需要完成他未完成的功能,那么我们是可以干掉这个锁的。
两种方法,一是找管理员。
$svnadmin lslocks /var/svn/idp
$svnadmin rmlocks /var/svn/idp/apple.jpg
?
或者我们自己来
?$svn status -u
?$svn unlock --force /var/svn/idp/apple.jpg
使用--force,很暴力。使用svn status查看
$svn status -u
B ? 32 ? apple.jpg
B 表示锁坏了(broken)
?
SVN在设计的时候,这里有两个争论。就是是否只有管理员能解锁?还是其他用户也能解锁。SVN 使用了灵活的方式,我们可以用户解锁,但是也可以使用 Repostory hook来设置只有管理员可以解锁。关于hook的问题,我们就不多说了。