SVN常用总结:

分支,主干,合并,标签创建一个分支或者标签时,采用一种”延迟拷贝”的技术,即只创建指向同一版本的链接,当其中某个文件有所改动时,
再去复制那个文件或者目录。一般地来讲,分支是用来做准备发布的,而不是并行开发。

1. 创建一个项目仓库
svnadmin create /home/huzza/test_svn
2. import初始文件到项目仓库中
svn import -m source_file_path URL本例 URL:file:///home/huzza/test_svn/sesame/trunkfile:// ——> 告诉svn是本地目录
3. checkout文件到本地目录
svn checkout(co) file:///home/huzza/test_svn/sesame/trunk sesame
4. 检查文件状态或者日至
svn status [文件/目录]svn log [文件/目录]
svn log -r6:8 [文件/目录] 查看版本6到版本8之间的日志
5. 文件/目录比较(工作拷贝与项目创库中的比较)
svn diff [文件/目录] 或者 svn diff –rHEAD [文件/目录] –rHEAD:表示最新版本
6. 更新本地工作拷贝,提交工作修改
svn update(up) [文件/目录]
svn checkin(in) -m”comments” [文件/目录]update时的一些文件标志:
U —— 表示文件被更新
G —— 表示项目创库中的文件和本地工作拷贝的文件合并到了一起
C —— 表示合并时,有冲突产生
A —— 新加入了一个文件
D —— 删除了一个文件
? —— 表示该文件或者目录没有被svn管理
M —— 该文件被修改
7. 冲突。当svn update时,如果存在某个文件存在冲突,打开冲突的文件,<<<<<<<>>>>>>> 表明了冲突发生的地方。当冲突发生时,
A.如果想使用项目仓库中的版本,而放弃本地拷贝的修改,可以使用以下命令:
a、svn revert [冲突的文件/目录]
b、svn update [冲突的文件/目录](svn resolved [文件/目录] && svn updata [文件/目录],似乎也是ok的,需要confirm一下)
B.如果想保留本地工作拷贝的修改,而放弃项目仓库中版本的修改,可以如下:
a、cp 文件/目录.mine 文件/目录
b、svn resolved 文件/目录
c、svn ci -m “use my version please” 文件/目录(在上面的三个步骤中,似乎不用做步骤a也可以达到目的)
8. 使svn项目仓库联网启动svn服务器:
svnserve –daemon –root /home/huzza/test_svn列服务器资源:
svn list svn://192.168.0.4/sesame/trunk出来后面的URL不同,其他操作的各部分均相同
svn+ssh 访问:svn list svn+ssh://192.168.0.4/sesame/trunk (需要在服务器上支持ssh访问)
9. 得到特定版本的工作拷贝svn checkout -rVersionNum list svn://192.168.0.4/sesame/trunk butterflysvn info butterfly(查看当前版本拷贝的状态)
10.拷贝/移动文件svn copy filename newfilesvn move oldfile newfilesvn ci -m “add or move some files” [修改文件所在的目录](这里确保服务器上也作跟本地拷贝相同的动作)
11.版本的符号
HEAD ——— 项目仓库中的最新版本
BASE ——— 工作拷贝的基准版本(也就是checkout出来时的版本)
COMMITTED —- 最后一次checkin的版本
PREV ——— COMMITTED之前的一个版本
12.查找版本之间的差异
svn diff -r2:4 [文件/目录]
svn diff > diffname.patch (生成patch文件)
使用patch文件: patch -p0 -i diffname.patch
13.删除后一个版本对前一个版本的修改
svn merge -r27:26 [文件/目录] && svn ci -m “undo the work of version 27″撤销版本27所做的修改
14.创建分支/标签
svn mkdir -m “Create branches” svn://192.168.0.4/sesame/branchessvn copy -m “Create release branches for version 1.0″ svn://192.168.0.4/sesame/trunk svn://192.168.0.4/sesame/branches/release-1.0

举例:创建主干,分支,标签
[oracle@LBA ~]$ svn co http://svn.mchz.com.cn/svn/incubator/owlet
A owlet/memaudit
A owlet/memaudit/MemoryAuditc
A owlet/memaudit/MemoryAuditc/log
A owlet/memaudit/MemoryAuditc/log/Makefile.am

[oracle@LBA owlet]$ svn del memaudit/
D memaudit/MemoryAuditc/log/Makefile.am
D memaudit/MemoryAuditc/log
D memaudit/MemoryAuditc/script/isopen.sh
D memaudit/MemoryAuditc/script/Makefile.am
D memaudit/MemoryAuditc/script/memoryAuditClient.ini

[oracle@LBA owlet]$ svn del -m “delete old memaudit, and add with new version of taizhou mobile…” memaudit
删除 memaudit
提交后的修订版为 152。
[oracle@LBA owlet]$ svn commit -m “commit….”
–之后服务器上的memaudit目录就被删掉了!

–添加分支和版本
[oracle@LBA owlet]$ svn mkdir -m “create owlet trunk” http://svn.mchz.com.cn/svn/incubator/owlet/trunk
提交后的修订版为 161。
[oracle@LBA owlet]$ svn mkdir -m “create owlet branches” http://svn.mchz.com.cn/svn/incubator/owlet/branches
提交后的修订版为 162。
[oracle@LBA owlet]$ svn mkdir -m “create owlet tags” http://svn.mchz.com.cn/svn/incubator/owlet/tags
提交后的修订版为 163。
[oracle@LBA owlet]$ svn cp http://172.16.4.98/svn/incubator/owlet/capaa-govern http://svn.mchz.com.cn/svn/incubator/owlet/trunk
svn: 来源与目的似乎不在同一个档案库中 (来源:“http://172.16.4.98/svn/incubator/owlet/capaa-govern”;目的:“http://svn.mchz.com.cn/svn/incubator/owlet/trunk”)
[oracle@LBA owlet]$ svn cp capaa-govern/ capaa-owlet/ http://svn.mchz.com.cn/svn/incubator/owlet/trunk
copy (cp): 在工作拷贝或档案库中复制数据,恢复历史。错了!!!

注: 这里需要一个一个的拷贝,而且还要加注释…

[oracle@LBA owlet]$ svn cp -m “copy capaa-govern to trunk.” capaa-govern/ http://svn.mchz.com.cn/svn/incubator/owlet/trunk
提交后的修订版为 164。
[oracle@LBA owlet]$ svn cp -m “copy capaa-owlet to trunk.” capaa-owlet/ http://svn.mchz.com.cn/svn/incubator/owlet/trunk
提交后的修订版为 165。
[oracle@LBA owlet]$ svn commit -m “commit all the operations…”
将要发布版本打个标签: 即从trunk李拷贝一份到tags里
[oracle@LBA owlet]$ svn cp -m “copy release version from trunk to tags for taizhou mobile…” http://svn.mchz.com.cn/svn/incubator/owlet/trunk http://svn.mchz.com.cn/svn/incubator/owlet/tags/taizhou-1.0

[oracle@LBA ~]$ svnadmin create http://svn.mchz.com.cn/svn/incubator/capaa-sensor
svnadmin: “http://svn.mchz.com.cn/svn/incubator/capaa-sensor”是地址(URL),但是应该是路径
create: 用法:svnadmin create REPOS_PATH于 REPOS_PATH 建立一个新的,空的 Subversion 档案库。

SVN简易使用手册
Subversion是一个免费的开源的版本管理系统,它是作为CVS(Concurrent Versions System)的取代品出现的。
本文简单介绍了Subversion在Fedora上的安装过程及其基本概念和使用方法。您可以到O’Reilly出版的 开源书籍Version Control with Subversion
的主页在线阅读(中、英文版本都有),以获取更多信息。

1 在Fedora上安装Subversion
[aaronwong@localhost ~]$ sudo yum -y install subversion
[aaronwong@localhost ~]$ rpm -ql subversion
//上面的命令可查询subversion软件包在系统上所安装的文件列表
[aaronwong@localhost ~]$ sudo yum -y install mod_dav_svn
//mod_dav_svn不是必须安装的,它是Apache HTTP Server的一个插件,你本地仓库(repository)的文件必须通过它才能在网络上与别人共享。
//subversion的组件列表点此查看。

[aaronwong@localhost ~]$ svn –version
svn,版本 1.4.3 (r23084)
编译于 Mar 23 2007,09:29:55

版权所有 (C) 2000-2007 CollabNet。
Subversion 是开放源代码软件,请参阅 http://subversion.tigris.org/
此产品包含由 CollabNet (http://www.Collab.Net/)开发的软件。

可使用以下的仓库存取 (RA) 模块:

* ra_dav : 通过WebDAV(DeltaV)协议访问仓库的模块。
– 处理“http”方案
– 处理“https”方案
* ra_svn : 使用svn网络协议访问仓库的模块。
– 处理“svn”方案
* ra_local : 访问本地磁盘的仓库模块。
– 处理“file”方案

2 使用Subversion管理本地project
作为程序开发人员,我们没有必要了解Subversion的所有特性的方方面面,我们的目的是使用它来对我们的project进行方便的简单的版本管理,因此,强烈推荐阅读Subversion Quick-Start Guid和Basic Usage。
以下是笔者参照上述Guide进行一个简单的本地project的版本管理的示例。假定工程名为hello。
(1)建立本地工程hello的subversion仓库
Subversion把工程的各个版本的数据集中放在一个仓库(repository)中。假定我们要建立一个本地工程,叫做hello,为了使用subversion对它进行版本管理,首先要为该工程建立一个仓库。
[aaronwong@localhost ~]$ svnadmin create .subversion/repos/hello
//subversion安装后会生成一个~/.subversion目录,这里,我们将工程hello的数据仓库建立在~/.subversion/repos/hello目录。

[aaronwong@localhost ~]$ ls -p .subversion/repos/hello/
conf/ dav/ db/ format hooks/ locks/ README.txt

(2)按照subversion的要求组建本地工程hello的工作目录
假定工程hello的顶层目录为~/projects/hello(这里~代表/home/aaronwong/),则应如下组建工程的工作目录:~/projects/hello/branches
~/projects/hello/tags
~/projects/hello/trunk/
hello.c
//trunk目录是实际上的工程顶层目录,工程中的所有文件和文件夹都在该目录下组织。
[aaronwong@localhost ~]$ cd projects/hello/
[aaronwong@localhost hello]$ ls -p
branches/ tags/ trunk/
[aaronwong@localhost hello]$ cat trunk/hello.c
//This is a original version.

#include

int main()
{
printf(“Hello world!\n”);

}
(3)将本地工程hello导入本地的Subversion的工程仓库
由于是首次导入,因此要加信息-m “initial import”。[aaronwong@localhost trunk]$ svn import ~/projects/hello/ file:///home/aaronwong/.subversion/repos/hello/ -m “initial improt”
新增 /home/aaronwong/projects/hello/trunk
新增 /home/aaronwong/projects/hello/trunk/hello.c
新增 /home/aaronwong/projects/hello/branches
新增 /home/aaronwong/projects/hello/tags

提交后的版本为 1。

注意,完成导入后,原目录~/projects/hello并不转换为“工作副本(working copy)”,而且该项目已经转由该仓库接管,即该仓库中已经包含了首次导入的工程的所有信息,与源目录~/project/hello再无任何关系,我 们完全可以删除这一目录而不必担心丢失工程项目数据。注意,如果源目录并不是一个“工作副本”,那么就无法用svn进行管理,在其中所作的任何变动都无法 提交到仓库。
要用subversion对工程进行版本管理,那么工程项目的开发必须在一个“工作副本”中进行,即首先要从仓库获取一个“工作副本”。

(4)工程开发过程中的版本管理与控制
使用subversion对工程进行版本管理的一般流程如下:
a)建立工程的数据仓库,并导入工程的最初版本(前面已经完成);
b)从仓库获取一个“工作副本”(svn checkout,可以获取最新版本也可以获取以前的某个版本),在这个“工作副本”中进行工程开发,修改完毕将变动提交到仓库。
下面简单介绍b)步骤。
由于工程hello已经导入到仓库,因此原目录可以删除。我们删除原目录,并从仓库获取工程hello的一个“工作副本”(working copy);当然,如果你当心这样做会造成数据丢失,完全可以重新建立一个目录,将“工作副本”保存到那里。[aaronwong@localhost projects]$ rm -rf hello/
[aaronwong@localhost projects]$ svn checkout file:///home/aaronwong/.subversion/repos/hello/trunk hello
A hello/hello.c
取出版本 1。
//注意,我们用红色标出了”trunk”,如果不指定这一目录,则会取出除工程源文件外的其他不必要的目录如branches和tags。
[aaronwong@localhost projects]$ ls -a hello/
. .. hello.c .svn
//可以看到“工作副本”下有一个.svn隐藏目录,其中就包含了subversion用來进行版本管理的信息。

下面可以对工程hello的内容进行编辑和修改。注意,如果要在工程中增加或删除某一文件或目录(包括复制和移动),必须使用svn add/delete/mkdir/copy/move等相关命令进行标记。[aaronwong@localhost hello]$ pwd
/home/aaronwong/projects/hello
[aaronwong@localhost hello]$ vim hello.c
[aaronwong@localhost hello]$ cat hello.c
//This is the second version.

#include

int main()
{
printf(“Hello world!\n”);
return;
}
[aaronwong@localhost hello]$ mkdir doc
[aaronwong@localhost hello]$ vim doc/readme.txt
[aaronwong@localhost hello]$ svn add doc
A doc
A doc/readme.txt
//说明:如果svn add的对象是一个目录,则该目录及其子目录和其下的文件都会被添加到工程。

对工程编辑完毕,你可以检查一下该次编辑对工程(实际上是对你的”工作副本”)做了哪些改动。[aaronwong@localhost hello]$ svn status
M hello.c
A doc
A doc/readme.txt
[aaronwong@localhost hello]$ svn diff
Index: hello.c
===================================================================
— hello.c (版本 1)
+++ hello.c (工作副本)
@@ -1,10 +1,10 @@
-//This is a original version.
+//This is the second version.

#include

int main()
{
printf(“Hello world!\n”);
-
+ return;
}

Index: doc/readme.txt
===================================================================
— doc/readme.txt (版本 0)
+++ doc/readme.txt (版本 0)
@@ -0,0 +1,2 @@
+This is an example for subversion tutorial.
+
//可以看到,svn diff提供了更详细的改动信息,并且很容易的将该命令的输出重定向为一个patch补丁。

检查确认无误后,便可提交此次更改,同时要附加此次更改的说明注释信息。[aaronwong@localhost hello]$ svn commit -m “documents added.”
新增 doc
新增 doc/readme.txt
正在发送 hello.c
传输文件数据..
提交后的版本为 2。

现在工程仓库中已经保存了上面所提交的版本2的工程的所有信息,因此,上面的“工作副本”也可以被删除:当然,如果下次你还要继续使用这个“工作副本”进 行工作,则可以保留这个副本,不过需要注意的是,如果你是在一个开发团队中,开发团队的任一成员都可能在你不知情的情况下更新了工程版本,因此,在团队开 发中,进入已有的“工作副本”进行编辑前,应该先使用”svn update”命令将当前“工作副本”更新到仓库中的最新版本。

3 使用svn获取开源项目源代码
这实际上是获取一个“工作副本”的过程。例如我需要下载ffmpeg的最新源代码,就可以使用svn checkout命令来完成:
[aaronwong@localhost ~]$ svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
A ffmpeg/configure
A ffmpeg/Doxyfile
A ffmpeg/ffmpeg.c
A ffmpeg/vhook
A ffmpeg/vhook/imlib2.c
A ffmpeg/vhook/drawtext.c
A ffmpeg/vhook/fish.c
A ffmpeg/vhook/null.c
……

Subversion有许多特性、选项和华而不实的高级功能,但日常的工作中你只使用其中的一小部分,有一些只在特殊情况才会使用,在这一节里,我们会介绍许多你在日常工作中常见的命令。

典型的工作周期是这样的:

更新你的工作拷贝

svn update

做出修改

svn add

svn delete

svn copy

svn move

检验修改

svn status

svn diff

svn revert

合并别人的修改到工作拷贝

svn update

svn resolved

提交你的修改

svn commit
更新你的工作拷贝

当你在一个团队的项目里工作时,你希望更新你的工作拷贝得到所有其他人这段时间作出的修改,使用svn update让你的工作拷贝与最新的版本同步。
$ svn update
U foo.c
U bar.c
Updated to revision 2.

这种情况下,其他人在你上次更新之后提交了对foo.c和bar.c的修改,因此Subversion更新你的工作拷贝来引入这些更改。

让我们认真检查svn update的输出,当服务器发送修改到你的工作拷贝,一个字母显示在每一个项目之前,来让你知道Subversion对你的工作拷贝做了什么操作:
U foo

文件foo更新了(从服务器收到修改)。
A foo

文件或目录foo被添加到工作拷贝。
D foo

文件或目录foo在工作拷贝被删除了。
R foo

文件或目录foo在工作拷贝已经被替换了,这是说,foo被删除,而一个新的同样名字的项目添加进来,它们具有同样的名字,但是版本库会把它们看作具备不同历史的不同对象。
G foo

文件foo接收到版本库的更改,你的本地版本也已经修改,但改变没有互相影响,Subversion成功的将版本库和本地文件合并,没有发生任何问题。
C foo

文件foo的修改与服务器冲突,服务器的修改与你的修改交迭在一起,不要恐慌,这种冲突需要人(你)来解决,我们在后面的章节讨论这种情况。
修改你的工作拷贝

现在你可以开始工作并且修改你的工作拷贝了,你很容易决定作出一个修改(或者是一组),像写一个新的特性,修正一个错误等等。这时可以使用的Subversion命令包括svn add、 svn delete、svn copy和svn move。如果你只是修改版本库中已经存在的文件,在你提交之前,不必使用上面的任何一个命令。你可以对工作备份作的修改包括:
文件修改

这是最简单的一种修改,你不必告诉Subversion你想修改哪一个文件,只需要去修改,然后Subversion会自动地探测到哪些文件已经更改了。
目录树修改

你可以“标记”目录或者文件为预定要删除、增加、复制或者移动,也许这些改动在你的工作拷贝马上发生,而版本库只在你提交的时候才发生改变。

修改文件,可以使用文本编辑器、字处理软件、图形程序或任何你常用的工具,Subverion处理二进制文件像同文本文件一样—效率也一样。

这些是常用的可以修改目录树结构的子命令(我们会在后面包括svn import和svn mkdir)。
警告

你可以使用任何你喜欢的工具编辑文件,但你不可以在修改目录结构时不通知Subversion,需要使用svn copy、svn delete和svn move命令修改工作拷贝的结构,使用svn add增加版本控制的新文件或目录。
svn add foo

预定将文件、目录或者符号链foo添加到版本库,当你下次提交后,foo会成为其父目录的一个子对象。注意,如果foo是目录,所有foo中的内容也会预定添加进去,如果你只想添加foo本身,使用–non-recursive(-N)参数。
svn delete foo

预定将文件、目录或者符号链foo从版本库中删除掉,如果foo是文件,它马上从工作拷贝中删除,如果是目录,不会被删除,但是Subversion准备好删除了,当你提交你的修改,foo就会在你的工作拷贝和版本库中被删除。[2]
svn copy foo bar

建立一个新的项目bar作为foo的复制品,当在下次提交时会将bar添加到版本库,这种拷贝历史会记录下来(按照来自foo的方式记录),svn copy并不建立中介目录。
svn move foo bar

这个命令与与运行svn copy foo bar; svn delete foo完全相同,bar作为foo的拷贝准备添加,foo已经预定要被删除,svn move不建立中介的目录。

不通过工作拷贝修改版本库

本章的前面曾经说过,为了使版本库反映你的改动,你应该提交所有改动。这并不完全正确—有一些方式是可以直接操作版本库的,当然只有子命令直接操作URL而不是本地拷贝路径时才可以实现,通常svn mkdir、svn copy、svn move、和 svn delete可以使用URL工作。

指定URL的操作方式有一些区别,因为在使用工作拷贝的运作方式时,工作拷贝成为一个“集结地”,可以在提交之前整理组织所要做的修改,直接对URL操作就没有这种奢侈,所以当你直接操作URL的时候,所有以上的动作代表一个立即的提交。
检查你的修改

当你完成修改,你需要提交他们到版本库,但是在此之前,检查一下做过什么修改是个好主意,通过提交前的检查,你可以整理一份精确的日志信息,你也可以发现你不小心修改的文件,给了你一次恢复修改的机会。此外,这是一个审查和仔细察看修改的好机会,你可通过命令svn status、svn diff和svn revert精确地察看所做的修改。你可以使用前两个命令察看工作拷贝中的修改,使用第三个来撤销部分(或全部)的修改。

Subversion已经被优化来帮助你完成这个任务,可以在不与版本库通讯的情况下做许多事情,详细来说,对于每一个文件,你的的工作拷贝在.svn包含了一个“原始的”拷贝,所以Subversion可以快速的告诉你那些文件修改了,甚至允许你在不与版本库通讯的情况下恢复修改。
svn status

相对于其他命令,你会更多地使用这个svn status命令。

CVS用户:控制另类的更新!

你也许使用cvs update来看你做了哪些修改,svn status会给你所有你做的改变—而不需要访问版本库,并且不会在不知情的情况下与其他用户作的更改比较。

在Subversion,update只是做这件事—将工作拷贝更新到版本库的最新版本,你可以消除使用update察看本地修改的习惯。

如果你在工作拷贝的顶级目录运行不带参数的svn status命令,它会检测你做的所有的文件或目录的修改,以下的例子是来展示svn status可能返回的状态码(注意,#之后的不是svn status打印的)。
L abc.c # svn已经在.svn目录锁定了abc.c
M bar.c # bar.c的内容已经在本地修改过了
M baz.c # baz.c属性有修改,但没有内容修改
X 3rd_party # 这个目录是外部定义的一部分
? foo.o # svn并没有管理foo.o
! some_dir # svn管理这个,但它可能丢失或者不完整
~ qux # 作为file/dir/link进行了版本控制,但类型已经改变
I .screenrc # svn不管理这个,配置确定要忽略它
A + moved_dir # 包含历史的添加,历史记录了它的来历
M + moved_dir/README # 包含历史的添加,并有了本地修改
D stuff/fish.c # 这个文件预定要删除
A stuff/loot/bloo.h # 这个文件预定要添加
C stuff/loot/lump.c # 这个文件在更新时发生冲突
R xyz.c # 这个文件预定要被替换
S stuff/squawk # 这个文件已经跳转到了分支

在这种格式下,svn status打印五列字符,紧跟一些空格,接着是文件或者目录名。第一列告诉一个文件的状态或它的内容,返回代码解释如下:
A item

文件、目录或是符号链item预定加入到版本库。
C item

文件item发生冲突,在从服务器更新时与本地版本发生交迭,在你提交到版本库前,必须手工的解决冲突。
D item

文件、目录或是符号链item预定从版本库中删除。
M item

文件item的内容被修改了。
R item

文件、目录或是符号链item预定将要替换版本库中的item,这意味着这个对象首先要被删除,另外一个同名的对象将要被添加,所有的操作发生在一个修订版本。
X item

目录没有版本化,但是与Subversion的外部定义关联,关于外部定义,可以看“外部定义”一节。
? item

文件、目录或是符号链item不在版本控制之下,你可以通过使用svn status的–quiet(-q)参数或父目录的svn:ignore属性忽略这个问题,关于忽略文件的使用,见“svn:ignore”一节。
! item

文件、目录或是符号链item在版本控制之下,但是已经丢失或者不完整,这可能因为使用非Subversion命令删除造成的,如果是一个目录,有可能是检出或是更新时的中断造成的,使用svn update可以重新从版本库获得文件或者目录,也可以使用svn revert file恢复原来的文件。
~ item

文件、目录或是符号链item在版本库已经存在,但你的工作拷贝中的是另一个。举一个例子,你删除了一个版本库的文件,新建了一个在原来的位置,而且整个过程中没有使用svn delete或是svn add。
I item

文件、目录或是符号链item不在版本控制下,Subversion已经配置好了会在svn add、svn import和svn status命令忽略这个文件,关于忽略文件,见“svn:ignore”一节。注意,这个符号只会在使用svn status的参数–no-ignore时才会出现—否则这个文件会被忽略且不会显示!

第二列说明文件或目录的属性的状态(更多细节可以看“属性”一节),如果一个M出现在第二列,说明属性被修改了,否则显示空白。

第三列只显示空白或者L,L表示Subversion已经在.svn工作区域锁定了这个项目,当你的svn commit正在运行的时候—也许正在输入log信息,运行svn status你可以看到L标记,如果这时候Subversion并没有运行,可以推测Subversion发生中断并且已经锁定,你必须运行svn cleanup来清除锁定(本节后面将有更多论述)。

第四列只会显示空白或+,+的意思是一个有附加历史信息的文件或目录预定添加或者修改到版本库,通常出现在svn move或是svn copy时,如果是看到A +就是说要包含历史的增加,它可以是一个文件或是拷贝的根目录。+表示它是即将包含历史增加到版本库的目录的一部分,也就是说他的父目录要拷贝,它只是跟着一起的。 M +表示将要包含历史的增加,并且已经更改了。当你提交时,首先会随父目录进行包含历史的增加,然后本地的修改提交到更改后的版本。

第五列只显示空白或是S,表示这个目录或文件已经转到了一个分支下了(使用svn switch)。

如果你传递一个路径给svn status,它只给你这个项目的信息:
$ svn status stuff/fish.c
D stuff/fish.c

svn status也有一个–verbose(-v)选项,它可以显示工作拷贝中的所有项目,即使没有改变过:
$ svn status –verbose
M 44 23 sally README
44 30 sally INSTALL
M 44 20 harry bar.c
44 18 ira stuff
44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
44 21 sally stuff/things
A 0 ? ? stuff/things/bloo.h
44 36 harry stuff/things/gloo.c

这是svn status的“加长形式”,第一列保持相同,第二列显示一个工作版本号,第三和第四列显示最后一次修改的版本号和修改人。

上面所有的svn status调用并没有联系版本库,只是与.svn中的元数据进行比较的结果,最后,是–show-updates(-u)参数,它将会联系版本库为已经过时的数据添加新信息:
$ svn status –show-updates –verbose
M * 44 23 sally README
M 44 20 harry bar.c
* 44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
A 0 ? ? stuff/things/bloo.h
Status against revision: 46

注意这两个星号:如果你现在执行svn update,你的README和trout.c会被更新,这告诉你许多有用的信息—你可以在提交之前,需要使用更新操作得到文件README的更新,或者说文件已经过时,版本库会拒绝了你的提交。(后面还有更多关于此主题)。
svn diff

另一种检查修改的方式是svn diff命令,你可以通过不带参数的svn diff精确的找出你所做的修改,这会输出统一区别格式:[3]
$ svn diff
Index: bar.c
===================================================================
— bar.c (revision 3)
+++ bar.c (working copy)
@@ -1,7 +1,12 @@
+#include
+#include
+#include
+
+#include

int main(void) {
- printf(“Sixty-four slices of American Cheese…\n”);
+ printf(“Sixty-five slices of American Cheese…\n”);
return 0;
}

Index: README
===================================================================
— README (revision 3)
+++ README (working copy)
@@ -193,3 +193,4 @@
+Note to self: pick up laundry.

Index: stuff/fish.c
===================================================================
— stuff/fish.c (revision 1)
+++ stuff/fish.c (working copy)
-Welcome to the file known as ‘fish’.
-Information on fish will be here soon.

Index: stuff/things/bloo.h
===================================================================
— stuff/things/bloo.h (revision 8)
+++ stuff/things/bloo.h (working copy)
+Here is a new file to describe
+things about bloo.

svn diff命令通过比较你的文件和.svn的“原始”文件来输出信息,预定要增加的文件会显示所有增加的文本,要删除的文件会显示所有要删除的文本。

输出的格式为统一区别格式(unified diff format),删除的行前面加一个-,添加的行前面有一个+,svn diff命令也打印文件名和打补丁需要的信息,所以你可以通过重定向一个区别文件来生成“补丁”:
$ svn diff > patchfile

举个例子,你可以把补丁文件发送邮件到其他开发者,在提交之前审核和测试。
svn revert

假设你通过上面的diff输出发现你不小心用编辑器在README中输入了一些字符。

这是使用svn revert的好机会。
$ svn revert README
Reverted ‘README’

Subversion把文件恢复到未修改的状态,叫做.svn目录的“原始”拷贝,应该知道svn revert可以恢复任何预定要做的操作,举个例子,你不再想添加一个文件:
$ svn status foo
? foo

$ svn add foo
A foo

$ svn revert foo
Reverted ‘foo’

$ svn status foo
? foo
注意

svn revert ITEM的效果与删除ITEM然后执行svn update -r BASE ITEM完全一样,但是,如果你使用svn revert它不必通知版本库就可以恢复文件。

或许你不小心删除了一个文件:
$ svn status README
README

$ svn delete README
D README

$ svn revert README
Reverted ‘README’

$ svn status README
README

看!没有网络!

这三个命令(svn status、svn diff和 svn revert)都可以在没有网络的情况下工作,这让你在没有网络连接时的管理修改过程更加简单,像在飞机上旅行,乘坐火车往返或是在海滩上奋力工作时。

Subversion通过在.svn管理区域使用原始的版本缓存来做到这一点,这使得恢复本地版本而不必访问网络,这个缓存(叫做“text-base”)也允许Subversion可以根据原始版本生成一个压缩的增量(“区别”) 提交—即使你有个非常快的网络,有这样一个缓存有极大的好处,非常的快,只向服务器提交修改的部分,这一点乍一看好像并不重要,但当你要提交一个400M大小的文件的修改时,你就会明白!
解决冲突(合并别人的修改)

我们可以使用svn status -u来预测冲突,当你运行svn update一些有趣的事情发生了:
$ svn update
U INSTALL
G README
C bar.c
Updated to revision 46.

U和G没必要关心,文件干净的接受了版本库的变化,文件标示为U表明本地没有修改,文件已经根据版本库更新。G标示合并,标示本地已经修改过,与版本库没有重迭的地方,已经合并。

但是C表示冲突,说明服务器上的改动同你的改动冲突了,你需要自己手工去解决。

当冲突发生了,有三件事可以帮助你注意到这种情况和解决问题:

Subversion打印C标记,并且标记这个文件已冲突。

如果Subversion认为这个文件是可合并的,它会置入冲突标记—特殊的横线分开冲突的“两面”—在文件里可视化的描述重叠的部分(Subversion使用svn:mime-type属性来决定一个文件是否可以使用上下文的,以行为基础合并,更多信息可以看“svn:mime-type”一节)。

对于每一个冲突的文件,Subversion放置三个额外的未版本化文件到你的工作拷贝:
filename.mine

你更新前的文件,没有冲突标志,只是你最新更改的内容。(如果Subversion认为这个文件不可以合并,.mine文件不会创建,因为它和工作文件相同。)
filename.rOLDREV

这是你的做更新操作以前的BASE版本文件,就是你在上次更新之后未作更改的版本。
filename.rNEWREV

这是你的Subversion客户端从服务器刚刚收到的版本,这个文件对应版本库的HEAD版本。

这里OLDREV是你的.svn目录中的修订版本号,NEWREV是版本库中HEAD的版本号。

举一个例子,Sally修改了sandwich.txt,Harry刚刚改变了他的本地拷贝中的这个文件并且提交到服务器,Sally在提交之前更新它的工作拷贝得到了冲突:
$ svn update
C sandwich.txt
Updated to revision 2.
$ ls -1
sandwich.txt
sandwich.txt.mine
sandwich.txt.r1
sandwich.txt.r2

在这种情况下,Subversion不会允许你提交sandwich.txt,直到你的三个临时文件被删掉。
$ svn commit –message “Add a few more things”
svn: Commit failed (details follow):
svn: Aborting commit: ‘/home/sally/svn-work/sandwich.txt’ remains in conflict

如果你遇到冲突,三件事你可以选择:

“手动”合并冲突文本(检查和修改文件中的冲突标志)。

用某一个临时文件覆盖你的工作文件。

运行svn revert 来放弃所有的修改。

一旦你解决了冲突,你需要通过命令svn resolved让Subversion知道,这样就会删除三个临时文件,Subversion就不会认为这个文件是在冲突状态了。[4]
$ svn resolved sandwich.txt
Resolved conflicted state of ’sandwich.txt’
手工合并冲突

第一次尝试解决冲突让人感觉很害怕,但经过一点训练,它简单的像是骑着车子下坡。

这里一个简单的例子,由于不良的交流,你和同事Sally,同时编辑了sandwich.txt。Sally提交了修改,当你准备更新你的版本,冲突发生了,我们不得不去修改sandwich.txt来解决这个问题。首先,看一下这个文件:
$ cat sandwich.txt
Top piece of bread
Mayonnaise
Lettuce
Tomato
Provolone
<<<<<<>>>>>> .r2
Creole Mustard
Bottom piece of bread

小于号、等于号和大于号串是冲突标记,并不是冲突的数据,你一定要确定这些内容在下次提交之前得到删除,前两组标志中间的内容是你在冲突区所做的修改:
<<<<<<>>>>>> .r2

通常你并不希望只是删除冲突标志和Sally的修改—当她收到三明治时,会非常的吃惊。所以你应该走到她的办公室或是拿起电话告诉Sally,你没办法从从意大利熟食店得到想要的泡菜。[5]一旦你们确认了提交内容后,修改文件并且删除冲突标志。
Top piece of bread
Mayonnaise
Lettuce
Tomato
Provolone
Salami
Mortadella
Prosciutto
Creole Mustard
Bottom piece of bread

现在运行svn resolved,你已经准备好提交了:
$ svn resolved sandwich.txt
$ svn commit -m “Go ahead and use my sandwich, discarding Sally’s edits.”

记住,如果你修改冲突时感到混乱,你可以参考subversion生成的三个文件—包括你未作更新的文件。你也可以使用第三方的合并工具检验这三个文件。
拷贝覆盖你的工作文件

如果你只是希望取消你的修改,你可以仅仅拷贝Subversion为你生成的文件替换你的工作拷贝:
$ svn update
C sandwich.txt
Updated to revision 2.
$ ls sandwich.*
sandwich.txt sandwich.txt.mine sandwich.txt.r2 sandwich.txt.r1
$ cp sandwich.txt.r2 sandwich.txt
$ svn resolved sandwich.txt
下注:使用svn revert

如果你得到冲突,经过检查你决定取消自己的修改并且重新编辑,你可以恢复你的修改:
$ svn revert sandwich.txt
Reverted ’sandwich.txt’
$ ls sandwich.*
sandwich.txt

注意,当你恢复一个冲突的文件时,不需要再运行svn resolved。

现在我们准备好提交修改了,注意svn resolved不像我们本章学过的其他命令一样需要参数,在任何你认为解决了冲突的时候,只需要小心运行svn resolved,—一旦删除了临时文件,Subversion会让你提交这文件,即使文件中还存在冲突标记。
提交你得修改

最后!你的修改结束了,你合并了服务器上所有的修改,你准备好提交修改到版本库。

svn commit命令发送所有的修改到版本库,当你提交修改时,你需要提供一些描述修改的日志信息,你的信息会附到这个修订版本上,如果信息很简短,你可以在命令行中使用–message(-m)选项:
$ svn commit –message “Corrected number of cheese slices.”
Sending sandwich.txt
Transmitting file data .
Committed revision 3.

然而,如果你把写日志信息当作工作的一部分,你也许会希望通过告诉Subversion一个文件名得到日志信息,使用–file选项:
$ svn commit –file logmsg
Sending sandwich.txt
Transmitting file data .
Committed revision 4.

如果你没有指定–message或者–file选项,Subversion会自动地启动你最喜欢的编辑器(见“config”一节的editor-cmd部分)来编辑日志信息。
提示

如果你使用编辑器撰写日志信息时希望取消提交,你可以直接关掉编辑器,不要保存,如果你已经做过保存,只要简单的删掉所有的文本并再次保存。
$ svn commit
Waiting for Emacs…Done

Log message unchanged or not specified
a)bort, c)ontinue, e)dit
a
$
版本库不知道也不关心你的修改作为一个整体是否有意义,它只检查是否有其他人修改了同一个文件,如果别人已经这样做了,你的整个提交会失败,并且提示你一个或多个文件已经过时了:
$ svn commit –message “Add another rule”
Sending rules.txt
svn: Commit failed (details follow):
svn: Out of date: ‘rules.txt’ in transaction ‘g’

此刻,你需要运行svn update来处理所有的合并和冲突,然后再尝试提交。
我们已经覆盖了Subversion基本的工作周期,还有许多其它特性可以管理你得版本库和工作拷贝,但是只使用前面介绍的命令你就可以很轻松的工作了。
[2] 当然没有任何东西是在版本库里被删除了—只是在版本库的HEAD里消失了,你可以通过检出(或者更新你的工作拷贝)你做出删除操作的前一个修订版本来找回所有的东西。
[3] Subversion使用内置区别引擎,缺省情况下输出为统一区别格式。如果你期望不同的输出格式,你可以使用–diff-cmd指定外置的区别程序,并且通过–extensions传递其他参数,举个例子,察看本地文件foo.c的区别,同时忽略空格修改,你可以运行svn diff –diff-cmd /usr/bin/diff –extensions ‘-bc’ foo.c。
[4] 你也可以手工的删除这三个临时文件,但是当Subversion会给你做时你会自己去做吗?我们是这样想的。
[5] 如果你向他们询问,他们非常有理由把你带到城外的铁轨上。

SVN服务器创建多个版本库

在svn服务器中为每个项目创建单独的版本库

1. 创建版本库目录

[root@mail var]# mkdir -p /var/svndata/huayuansoft_www

[root@mail var]# mkdir -p /var/svndata/huayuansoft_oa

2. 建立svn版本库

[root@mail var]# svnadmin create /var/svndata/huayuansoft_www

[root@mail var]# svnadmin create /var/svndata/huayuansoft_oa

3. 修改svn版本库配置文件

[root@mail var]# vi /var/svndata/huayuansoft_www/conf/svnserve.conf

内容

[general]

### These options control access to the repository for unauthenticated

### and authenticated users. Valid values are “write”, “read”,

### and “none”. The sample settings below are the defaults.

# anon-access = read

# auth-access = write

### The password-db option controls the location of the password

### database file. Unless you specify a path starting with a /,

### the file’s location is relative to the conf directory.

### Uncomment the line below to use the default password file.

# password-db = passwd

### The authz-db option controls the location of the authorization

### rules for path-based access control. Unless you specify a path

### starting with a /, the file’s location is relative to the conf

### directory. If you don’t specify an authz-db, no path-based access

### control is done.

### Uncomment the line below to use the default authorization file.

# authz-db = authz

### This option specifies the authentication realm of the repository.

### If two repositories have the same authentication realm, they should

### have the same password database, and vice versa. The default realm

### is repository’s uuid.

# realm = My First Repository

[general]

anon-access = none

auth-access = write

password-db = passwd

authz-db = authz

realm = huayuansoft_www

4. 配置允许访问的svn用户

[root@mail var]# vi /var/svndata/huayuansoft_www/conf/pwd.conf

文件格式如下:

[users]

=

=

其中,[users]是必须的。下面列出要访问svn的用户,每个用户一行。示例:

[users]

alan = password

king = hello

5. 配置svn用户访问权

[root@mail var]# vi /var/svndata/huayuansoft_www/conf/authz.conf

文件中定义用户组和版本库目录权限。

注意:

* 权限配置文件中出现的用户名必须已在用户配置文件中定义。

* 对权限配置文件的修改立即生效,不必重启svn。

用户组格式:

[groups]

= ,

其中,1个用户组可以包含1个或多个用户,用户间以逗号分隔。

版本库目录格式:

[:/项目/目录]

@ =

=

其中,方框号内部分可以有多种写法:

/,表示根目录及以下。根目录是svnserve启动时指定的,我们指定为/opt/svndata。这样,/就是表示对全部版本库设置权限。

repos1:/,表示对版本库1设置权限

repos2:/abc, ,表示对版本库2中的abc项目设置权限

repos2:/abc/aaa, ,表示对版本库2中的abc项目的aaa目录设置权限

权限主体可以是用户组、用户或*,用户组在前面加@,*表示全部用户。权限可以是w、r、wr和空,空表示没有任何权限。

示例:

[groups]

admin = alan

[/]

@admin = rw

[repos1:/abc/aaa]

king = rw

[repos2:/pass]

king =

6. 启动svn

可以直接启动

svnserve -d –listen-port 9999 -r /var/svndata

建立启动svn的用户useradd svn

passwd svn

根据提示为用户svn设置密码

允许用户svn访问版本库chown -R svn:svn /opt/svndata

chown -R svn:svn /opt/data

启动svnsu – svn -c “svnserve -d –listen-port 9999 -r /opt/svndata”

其中:

su – svn表示以用户svn的身份启动svn

-d表示以daemon方式(后台运行)运行

–listen-port 9999表示使用9999端口,可以换成你需要的端口。但注意,使用1024以下的端口需要root权限

-r /opt/svndata指定根目录是/opt/svndata

检查:

ps -ef|grep svnserve

如果显示如下,即为启动成功:

svn    6941   1 0 15:07 ?    00:00:00 svnserve -d –listen-port 9999 -r /opt/svndata




Related posts

coded by nessus
分享:  DeliciousGReader鲜果豆瓣CSDN网摘
Trackback

no comment untill now

Sorry, comments closed.

无觅相关文章插件