使用 SVK 构建分布式版本控制环境

developerWorks
文档选项
将此页作为电子邮件发送

将此页作为电子邮件发送

样例代码



级别: 中级

吴 玥颢 (wuyuehao@cn.ibm.com), 软件工程师, IBM

2007 年 2 月 28 日

SVK 是一个基于 Subversion 构造的分布式的版本控制系统。通常的集中式管理系统,如 CVS,Subversion 已经得到广泛应用,但是集中式的管理存在相应的缺陷,例如对唯一的版本库过分依赖:一旦不能正常连接到集中式的版本库,整个系统陷入瘫痪。SVK 最大的能力就在于可以维护分布式的版本库,分散的开发人员可以通过 SVK 建立远程的 CVS,Subversion,P4 协议的版本库镜像,选择工作在自己合适的镜像版本库,这个镜像甚至可以是本地的,整个工作可以离线进行,然后在需要的时候同步镜像版本库到主版本库。

前言

SVK 在大部分的操作与设计思想上都与 Subversion 相似,本文假定读者对 Subversion 有一定的了解,将着重介绍 SVK 新增特性与功能,与 Subversion 重叠的部分就不再赘述。读者可以参考作者的另外一篇 关于 Subversion 的文章

历史

版本管理工具的历史由来已久,CVS 作为标准的版本管理控制工具已经得到了广泛应用。为改善 CVS 天生的缺陷,CollabNet 开发了 Subversion。Subversion 在目录版本化、原子提交、元数据、分支和标签等方面有了极大的改进,但遗憾的是它仍然是集中式的版本管理工具。不过幸运的是,由于 Subversion 灵活的设计,重用 Subversion 已有组件并扩展其功能成为了现实,SVK 就是这样一个基于 Subversion 的扩展实现。高嘉良先生一年时间的全职工作使 SVK 顺利诞生了。目前 SVK 项目已经被 Bestpractical 收录,读者可以访问其官方主页(请参阅 参考资源)。

License

SVK 是基于 Artistic License 发布的。Artistic License 目前基本被用于标准 Perl,CPAN 组件以及 Parrot 软件上。详细信息请参阅 参考资源

安装

SVK 由一组基于 SVN 的 Perl 绑定的 Perl5 的模块构成。Subversion 本身是构建于 Apache APR 之上,因此 SVK 可以在任何支持 Apache Http Server 的操作系统上运行,包括 Windows、Linux、Mac OS、Free BSD 以及 Netware。

最简单的安装方式是直接下载对应操作系统的的二进制版本。Windows 版本可以在 这里 找到,Linux 系统上也可以使用 deb 或者 rpm 的安装方式。目前 Cpan 已经提供有 2.0 版本的安装,通过 cpan 的安装方式如下:

首先需要安装 Subversion 的 Perl 绑定,cpan 没有提供这一模块,如果安装 Subversion 的时候没有选择安装 Perl 绑定则需要重新配置及安装 Subversion。

安装 Subversion 的 Perl 绑定需要 swig 的支持,swig 是 C/C++ 软件与其他高级语言的连接器,关于 swig 请参考http://www.swig.org/

安装 swig

下载 swig1.3.24 以上版本(需要 Perl 5.8.0 以上版本支持),解压后在 SWIG-1.3.xx 目录下运行如下命令,其中 /path/to/correct/perl/binary 应当指向 Perl 的可执行文件:

验证安装
可以用 swig --version 来验证安装是否成功。
./configure --with-perl5=/path/to/correct/perl/binary
make
make install

配置 Subversion

成功安装了 swig 后便可以安装 subverion 的 perl 绑定了,在 Subversion 源代码目录下运行如下命令:

验证安装
如果 Subversion 的 configure 找到了合适的 swig,将会生成名为 libsvn_swig_perl.so 的库文件。
./configure PERL=/path/to/correct/perl/binary

安装 Subversion 的 perl 绑定

make
make swig-pl
make check-swig-pl
make install
make install-swig-pl

通过 cpan 安装 SVK

通过如下命令,cpan 会自动寻找并提示安装所有相关模块。

>cpan
cpan> install SVK

如果全部安装成功。在命令行敲入 svk 便会得到如下的 SVK 帮助信息:

获取帮助

svk help commands 将会列出所有 SVK 支持的子命令。

对于某个特定的命令如 update,svk help update 将会得到关于 update 的说明。

svk help environment 将会列出所有与 SVK 相关的环境变量。

SVK Documentation - Main index:

If this is your first time using SVK, you should start by reading a
brief tutorial. When you're ready, type:

    svk help intro

Once you've done that, more in-depth help is available:

    svk help environment    Environment variables that alter svk's behavior
    svk help commands       A list of all available commands
    svk help view           svk view support
    svk help <command-name> Help for a specific command

For commercial support, contact sales@bestpractical.com. For up to date
information about SVK, visit http://svk.bestpractical.com/.

如果想要体验最新的版本,可以直接从 SVK 的版本库取出最新的源代码进行编译安装:

Perl 绑定安装部分同前述。

svn co http://code.bestpractical.com/svk/trunk/
cd trunk/
perl Makefile.PL
make
make test
make install
svk





回页首


新功能

相较于 Subversion 而言,SVK 增加了许多强劲的功能。

Depot

首先介绍一个新概念—— Depot,它是 SVK 进行版本管理的核心。SVK 使用 Subversion 的版本库实现 Depot。对本地 Depot 的引用是使用"//",由于它完全是 Subversion 兼容的,因此用户也可以很方便的将 Depot 通过 svnserve 或者 http 方式发布到网络上。

Patch

在 Subversion 中,用户可以使用重定向 svn diff 的输出来生成 patch 文件:

svn diff foo > patch.diff

在 SVK 中补丁的功能得到了加强。用户可以通过 commit 以及 smerge 中的 -P(--patch) 选项来创建补丁:

svk commit -m "this is log" --patch patch_name
svk smerge //foo //bar --patch patch_name

创建的补丁将存储在 Depot 同一目录下的 patch 子目录中,用户可以将这一补丁传递给其他用户使用。

同时 SVK 的补丁功能支持对二进制文件的补丁操作,例如:

touch foo
zip foo.zip foo
svk add foo.zip
svk commit -m "this is log" foo.zip --patch patch_name

生成补丁内容如下

==== Patch <patch_name> level 1
Source: [No source]
Target: 9bbf3572-454d-844a-a388-5e5c8078394f:/tony:1
        (http://localhost/repos)
Log:
this is log
=== foo.zip
==================================================================
Cannot display: file marked as a binary type.

Property changes on: foo.zip
___________________________________________________________________
Name: svn:mime-type
 +application/octet-stream


==== BEGIN SVK PATCH BLOCK ====
Version: svk v2.0.0 (MSWin32)

eJxNks1qE1EUx6c1qWIptMFqcaFFpoKLsXM/5iMphqhJKgY10EQUF5ObmZtkZDIzTm6DLVfIaKjF
J9AHENworly57EJbcO8LuPcFxHunFoRh4HDO/3fOPedfT1obFcDLZZ2rQOdbDxulUpMwd7AmItXk
1PNZlKgGD+iYBiriQdRXMQ/JkIosI0mfsnIZCLF9LK5lghMIlowuYVE4UosZzGEJpSrgsIJ4BXLx
FwEQySimoZNEEVMhN6FIOXIgN4hG1JFCWWzKYqjanHie0/MDqlq8F0XXd/1YUhwh1YBACqnxT+r5
CXXFRDuyQPY0ZNbk7oCEfZpBnDiJ4gwMEB+Nw9LQH1KN7cRUhZiTOA58lzA/Ctcjl1GmjcQTyPAY
ZGT5HYfR58yjASOSI+bQkVjHfUVR0uhqenGvmp/W8puFN9XCxL+TLuw9yqWbhWm1MK1deVVP56f1
869rhWbjVO6scvTitjmj7Cpgq0qVr2eU3Iex43odf5F0Onpnolxe7Xl59LiWHoSfnrxs36vfPfz9
/aez8uwIQKDr4Jz+efJ+beUPOkSTg8rT5cl09q02u9Sf7s+n15b3Vy5t3Pz10Vu8BR4sfZtT2q0F
5fSPGwe1ZmNm9sL80qryJRWdc+1WvtnIz80oFfGGdxX8/zWyxct1IciBbVrIw2bPI8TCwKIGMC2I
u7gIDewhOzsuAJwN/NGq+KR9BCiW7nCki8plyFUIj83TyvxUKrVDf0yTEQnWxMWxrB4I6yV0LILt
bd8TflwXnspuqiKTF7vdHjIsqGHRVLMxJhpBtq0Z1HBt3bJREff+AuTM7ls=
==== END SVK PATCH BLOCK ====

因而通常的patch工具不能支持SVK生成的补丁。SVK 提供了一个 patch 命令来应用补丁,patch 命令包含如下一些常用选项:

svk patch --list|--ls
查看当前所有的补丁
svk patch --cat|--view PATCHNAME
查看某一补丁的内容
svk patch --regenerate|--regen PATCHNAME
重新生成补丁
svk patch --apply PATCHNAME [TARGET] [-- MERGEOPTIONS]
应用补丁
svk patch --delete|--rm PATCHNAME
删除补丁

Mirror

SVK 的镜像功能支持如下流行的版本控制工具:

svk mirror [http|svn]://host/path DEPOTPATH
svk mirror cvs::pserver:user@host:/cvsroot:module/... DEPOTPATH
svk mirror p4:user@host:1666://path/... DEPOTPATH

常用的 mirror 选项包括:

--list (-l)
察看本机上的所有 mirror
--detach (-d)
取消一个 mirror
--relocate
将 mirror 的源路经重定向
--unlock
非正常操作导致 mirror 被锁住可以用这个选项解锁

star-merge(smart-merge)

smerge 是 SVK 的亮点之一,SVK 的核心功能都是围绕其展开的。主要操作选项列举如下:

 -I [--incremental]
 渐进式的合并。它可以忠实地记录源版本库的每一次 commit 操作。
 -B [--baseless]
 用最早的版本作为合并的初始点。一般用户新版本库同步的首次合并。
 -b [--base] BASE 
从指定版本开始合并。一般用于合并已有的版本库分支。
 -s [--sync]
 合并前同步 Depot 与源版本库。
 -P [--patch] NAME
 不进行真实的合并,而是将合并内容生成一个补丁。
 -C [--check-only]
 列举合并的内容而不进行真实的操作。

合并过程中难免会遇到冲突的代码,SVK 提供了一些解决冲突的支持。用 perldoc SVK::Resolve 可以列出合并相关的帮助信息:

NAME

    SVK::Resolve - Interactively resolve conflicts

DESCRIPTION

      Accept:
         a   : Accept the merged/edited file.
         y   : Keep only changes to your file.
         t   : Keep only changes to their file.
      Diff:
         d   : Diff your file against merged file.
         dm  : See merged changes.
         dy  : See your changes alone.
         dt  : See their changes alone.
      Edit:
         e   : Edit merged file with an editor.
         m   : Run an external merge tool to edit merged file.
      Misc:
         s   : Skip this file.
         h   : Print this help message.

      Environment variables:
        EDITOR     : Editor to use for 'e'.
        SVKMERGE   : External merge tool to always use for 'm'.
        SVKRESOLVE : The resolve action to take, instead of asking.


在合并的过程中遇到冲突 SVK 会中断操作并提示用户输入:

e)dit, d)iff, m)erge, s)kip, t)heirs, y)ours, h)elp? [e]

可以选择的操作有编辑当前文件,打印出差异,合并,跳过,保留源端文件以及保留目标端的文件。

选择了 merge 以后 SVK 会自动搜寻可以使用的合并工具:

Multiple merge tools found, choose one:
(to skip this question, set the SVKMERGE environment variable to one of them)
1)GVim, 2)TortoiseMerge, 3)Vim, q)uit?

用户可以使用任何一种合并工具来手动解决冲突。此外 SVK 提供了设定环境变量来定义默认解决冲突的方式,用户可以设定环境变量 SVKRESOLVE 为上述提到的任何一种操作,例如 s(kip),t(heirs),y(ours)。





回页首


性能

SVK 在大部分方面具有与 Subversion 相当的性能,而在某些可以离线的操作具有更出色的表现。例如 svk status, svk update 以及 svk switch。

CVS,SVK 以及 Subversion 详细的比较数据见 http://svk.bestpractical.com/view/SVKvsSVNvsCVS





回页首


完整的例子

这一部分介绍 SVK 的实际使用。

单独使用

假设有一个远程的版本库 http://remote/repos,用户经常需要离线的工作,则可以使用 SVK 在本地计算机上建立一个远程版本库的镜像 Depot:

svk mirror http://remote/repos //mirror/local

为此镜像做一个拷贝,所有本地工作都在这一拷贝上完成

svk cp //mirror/local //local

从本地 Depot 取出 working copy

svk co //local

在能连接到远程版本库的时候,同步远程的版本库到本地

svk sy //mirror/local
svk pull //local

当然,将 Depot 作为 Subversion 版本库发布出来以后用户便可以脱离 SVK,使用 Subversion 的客户端即可访问。 这样一来,所有对版本库的工作都可以在没有网络环境的情况下进行,在将来能够连上网络的时候使用如下命令便将所有在本地的更动反映到远程版本库中去:

svk push //local

版本库同步

现今流行的 Open source 开发模式限制了 committer 的数量,并非所有用户都具有 commit 的权限。假设现有一个远程的版本库 http://remote/repos,数个用户希望能够有权限自由的 commmit,自然的,我们可以利用上述的镜像方法获得一个属于自己的版本库,但是这一版本库必须位于某台服务器上而不是某人的个人电脑上,以使得所有用户都能访问到。如果这个版本库是在一台标准的 Subversion 版本服务器上(假设 URL 是 http://myremote/repos),通常用户对此服务器只有访问 Subversion 版本库的权限,也就是说,用户无法直接在这一台服务器上安装 SVK 而做镜像。SVK 很好的解决了这一问题。我们可以使用任何一台和可以很好的连接上这两台服务器的某一台机器作为中间服务器,定时进行同步,下面是主要操作步骤。

在安装有SVK的中间服务器上进行如下操作:

svk mirror http://remote/repos //remote
svk mirror http://myremote/repos //myremote

分别同步两个 depot 的内容

svk sy //remote
svk sy //myremote

定时从 //remote 同步到 //myremote

svk smerge //remote //myremote

同时本文也提供了一个 Perl 脚本 作为示例,读者可以配置它自动运行并生成 Html 格式的 Report。


图 1: 生成的报告
生成的报告




回页首


结束语

SVK 是目前唯一的分布式版本库系统,它成功的对分布式版本库领域进行了有效的探索并获得了成功,它的出现使得以往一些实现起来非常复杂的功能变的十分简单,给一些以往无法完成的操作带来了可能。如 P4,CVS 与 Subversion 版本库的同步与移植,版本库的离线访问,以及远程版本库的镜像和同步等等。期待本文能使更多的读者认识 SVK,并从中获得分布式版本管理的种种便利,使得日常工作更加完美与高效。同时也期待更多的读者与本人交流经验。






回页首


下载

描述名字大小下载方法
示例 Perl 脚本svksync.zip3KBHTTP
关于下载方法的信息


参考资料



关于作者

吴玥颢的照片

吴玥颢,目前就职于 IBM 中国开发中心 Harmony 开发团队。 除了对 Java 和脚本语言的热爱之外,他的兴趣还包括哲学、神话、历史与篮球。此外他还是个电脑游戏高手。您可以通过wuyuehao@cn.ibm.com联系到他。

::...
免责声明:
当前网页内容, 由 大妈 ZoomQuiet 使用工具: ScrapBook :: Firefox Extension 人工从互联网中收集并分享;
内容版权归原作者所有;
本人对内容的有效性/合法性不承担任何强制性责任.
若有不妥, 欢迎评注提醒:

或是邮件反馈可也:
askdama[AT]googlegroups.com



自怼圈/年番新

DU21.7
关于 ~ DebugUself with DAMA ;-)


关注公众号, 持续获得相关各种嗯哼:
zoomquiet


粤ICP备18025058号-1
公安备案号: 44049002000656 ...::