学习Subversion
-- 主流版本管理系统的使用和管理
作者:Zoom.Quiet
1. 概述
本文包含了创建和使用Subversion 进行软件开发的基本知识,为有志于使用Subversion 这一方便的版本管理工具来支持规范化团队软件开发的程序员,在进行分布式协同开发时,如何组织版本控制提供了基础的建议和实用技巧;
2. 简介
- Subversion:
-
- 简称SVN 是 http://subversion.tigris.org/ 社区开发的,一个流行的用以代替CVS 的高效版本管理系统;和CVS 类似,也是一种"中央仓库式"的版本管理系统;不过,和CVS 相比 SVN 具有很多高级特性;
- 详细的信息,可以参考在线的 SVNBookv1.4
3. 安装SVN
当前最新版本是 1.5.5, SVN支持在各种操作系统中运行,安装前请从官方网站下载对应版本; 本文将以 Ubuntu 系统为例进行说明.
3.1. 环境准备
一个 7.04 以上版本的Ubuntu 环境,有root 权限即可;
3.2. 安装测试
因为SVN 已经包含在 Ubuntu 软件仓库中,安装SVN 仅需一个命令:
$ sudo apt-get install subversion
如果系统报告了依赖关系的错误,请找出相应的软件包并安装它们。如果存在其它问题,也请自行解决。如果您是再不能解决这些问题,可以考虑通过 Ubuntu 的网站、Wiki、论坛或邮件列表寻求支持。
3.3. 运营发布
SVN 可以提供多种协议的访问渠道,以下是模式列表:
| 模式 | 访问方法 |
|---|---|
| file:/// | 直接访问本地硬盘上文件仓库 |
| http:// | 通过 WebDAV 协议访问支持 Subversion 的 Apache 2 Web 服务器 |
| https:// | 类似 http://,支持 SSL 加密 |
| svn:// | 通过自带协议访问 svnserve 服务器 |
| svn+ssh:// | 类似 svn://,支持通过 SSH 通道 |
- 其中svn:// 是本文介绍的模式;
- 要想使用SVN,首先要初始化一个版本仓库:
$ svnadmin create /path/to/svn/myproj
- 然后,运行`svnserve`
$ svnserve -d -r /path/to/svn
- 这样,所有 `/path/to/svn` 目录中的SVN仓库都可以通过 svn:// 协议进行远程访问了
# 本地访问 $ svn co svn://localhost/myproj # 远程访问 $ svn co svn://host.example.org/myproj # 即刻下载,建立了本地工作复本,可以进行协同开发了
- 这样,所有 `/path/to/svn` 目录中的SVN仓库都可以通过 svn:// 协议进行远程访问了
3.4. 在线免费SVN仓库
事实上在网络中有很多SVN的免费空间可以使用,其中 http://code.google.com/intl/zh/ 是一个较轻便却完备的的项目管理环境,只要注册成功一个项目空间,就同时获得了一个维基,一个Issue ~ 提案追踪环境,和一个SVN仓库;
- 比如说,笔者管理的一个项目 OpenBookProject:
- http://code.google.com/p/openbookproject/
- 其SVN仓库的说明在:
- http://code.google.com/p/openbookproject/source/checkout
# 项目成员可写访问命令是 $ svn co https://openbookproject.googlecode.com/svn/trunk/ openbookproject --username Zoom.Quiet # 外部匿名读者只访问命令是 $ svn co http://openbookproject.googlecode.com/svn/trunk/ openbookproject-read-only
- http://code.google.com/p/openbookproject/source/checkout
- 在线代码游览入口:
- http://openbookproject.googlecode.com/svn/trunk/ 如果没有方便的主机资源,又想联合分布在各地的朋友共同来进行协同式软件项目开发的话,可以考虑使用 Google 公司贡献的这一服务.
4. 管理SVN
SVN 本身提供了丰富的管理工具, 在系统配置方面,仅仅有少量文件用以声明关键信息.
4.1. 关键配置
在仓库目录的 conf 目录中 svnserve.conf 是关键配置文件:
... [general] # 声明匿名用户权限 read|write anon-access = read # 声明登录用户权限 read|write auth-access = write # 声明登录用户口令信息文件 password-db = passwd.cfg # 声明登录用户仓库访问权限 authz-db = authz.cfg ...
4.2. 权限配置
配合svnserve.conf 的声明, SVN 通过理解两个文件来对仓库的访问进行控制:
4.2.1. password-db
声明的口令文件,定义了权限用户和口令:
[users] # 用户名=口令 的格式来逐行声明用户帐号 woodpecker = 1q2w3e4r@woodpecker.org ...
4.2.2. authz-db
声明的认证文件,定义了权限用户组和仓库不同部分的访问控制:
[groups] # 声明用户组 repomana 包含了几个用户 repomana = woodpecker,zoomq # 仓库目录权限声明 [仓库名:目录名] 格式引导多个权限声明 [woodpecker:/] # * 代表任何人 * = r # repoman 组成员可以读写 @repomana = rw [woodpecker:/foo] # 任何人可写 * = rw # river 用户只读 river = r ...
5. 使用SVN
作为标准意义上的版本管理系统,SVN 和其它任何版本管理系统日常使用并没有什么巨大的不同,是一个非常容易上手的工具系统;
5.1. 日常使用
以命令行形式说明日常通过SVN 进行协同开发时最常用的操作:
- 更新本地工作复本:
$ svn up
- 进行一些修订:
$ svn add~ 增补文件/目录$ svn del~ 删除文件/目录$ svn cp~ 复制文件/目录$ svn mv~ 移动文件/目录- 以上命令随时可以通过
--help获得充分的指示,例如:$ svn mv --help move (mv, rename, ren): 在工作副本或版本库中移动或改名文件或目录。 用法: move SRC... DST 当移动多个源时,它们作为 DST 的子节点增加,DST 必须是目录。 注意: 本子命令等同于先 “copy”,然后 “delete”。 注意: 此命令中 --revision 选项没有作用,已经淘汰。 SRC 可同时为工作副本(WC) 路径或 URL: WC -> WC : 移动并加入新增调度 (连同历史记录) URL -> URL : 完全是服务器端更名。 所有 SRC 必须是同一类型。 有效选项: -r [--revision] ARG : ARG (一些命令也接受ARG1:ARG2范围) 版本参数可以是如下之一: NUMBER 版本号 '{' DATE '}' 在指定时间以后的版本 'HEAD' 版本库中的最新版本 'BASE' 工作副本的基线版本 'COMMITTED' 最后提交或基线之前 'PREV' COMMITTED的前一版本 -q [--quiet] : 不打印信息,或只打印概要信息 --force : 强制操作运行 --parents : 创建中间目录 -m [--message] ARG : 指定日志信息ARG -F [--file] ARG : 从文件ARG读取日志信息 --force-log : 强制校验日志信息资源 --editor-cmd ARG : 使用 ARG 作为外部编辑器 --encoding ARG : 将ARG的值视为字符编码 --with-revprop ARG : 在新版本设置版本属性 ARG 使用格式 name[=value]
- 可能取消一些修改
$ svn revert- 详细帮助:
revert: 将工作副本文件恢复到原始版本(恢复大部份的本地修改)。 用法: revert PATH... 注意: 本子命令不会访问网络,它解除任何冲突的状态。 但是,它不恢复被删除的目录。 有效选项: --targets ARG : 传递文件 ARG 内容为附件参数 -R [--recursive] : 向下递归,与 --depth=infinity 相同 --depth ARG : 受深度参数 ARG(“empty”,“files”,“immediates”,或“infinity”) 约束的操作 -q [--quiet] : 不打印信息,或只打印概要信息 --changelist ARG : 只能对修改列表 ARG 成员操作 [aliases: --cl]
- 可能解决一些冲突:
$ svn resolved- 详细说明:
resolved: 删除工作副本中目录或文件的“冲突”状态。 用法: resolved PATH... 注意: 本子命令不会依语法来解决冲突或是删除冲突标记;它只是删除冲突相关的 附加文件,让 PATH 可以被再次提交。它已经过时,被 “svn resolve --accept working”取代。 有效选项: --targets ARG : 传递文件 ARG 内容为附件参数 -R [--recursive] : 向下递归,与 --depth=infinity 相同 --depth ARG : 受深度参数 ARG(“empty”,“files”,“immediates”,或“infinity”) 约束的操作 -q [--quiet] : 不打印信息,或只打印概要信息 - 可能的情景:
$ svn up C sandwich.txt Updated to revision 2. $ ls -1 sandwich.txt sandwich.txt.mine sandwich.txt.r1 sandwich.txt.r2
- 在这种情况下,SVN不会允许你提交
sandwich.txt,直到你解决冲突,可选的处置是:- “手动”合并冲突文本(检查和修改文件中的冲突标志)
- 运行
svn revert <filename>来放弃所有的本地修改 - 用某一个版本的 临时文件覆盖你的工作文件
<filename>.r*代表的是文件的第几个版本<filename>.mine代表的是本地我的文件版本<filename>是包含冲突标识的提示文件
- 在这种情况下,SVN不会允许你提交
- 提交修改:
$ svn ci -m "提交理由"然后,就是以上过程的不断循环
5.1.1. 对于 CVS 用户
特别的,对于从CVS系统迁移过来的用户,需要提升一些关键概念,来更好的使用 SVN:
- 版本号不同了
- 在CVS中,修订版本号是每文件的,这是因为CVS使用RCS文件保存数据,每个文件都在版本库有一个对应的RCS文件,版本库几乎就是根据项目树的结构创建。
- 在Subversion,版本库看起来像是一个单独的文件系统,每次提交导致一个新的文件系统;本质上,版本库是一堆树,每棵树都有一个单独的修订版本号。当有人谈论
“修订版本54”时,他们是在讨论一个特定的树(并且间接来说,文件系统在提交54次之后的样子)。 - 技术上讲,谈论
“文件foo.c的修订版本5”是不正确的,相反,一个人会说“foo.c在修订版本5出现”。同样,我们在假定文件的进展时也要小心,在CVS,文件foo.c的修订版本5和6一定是不同的,在Subversion,foo.c可能在修订版本5和6之间没有改变。 - 类似的,在CVS中标签或分支是文件的一种标注,或者是单个文件的版本信息,而在Subversion中,标签和分支是整个目录树的拷贝
- 版本库作为一个整体,每个文件的许多版本可见:每个分支的最新版本,每个标签的最新版本以及trunk本身的最新版本。所以,我们再精炼一下术语,我们说“foo.c在修订版本5出现在/branches/REL1”
- 目录有版本了
- 因为 SVN 的版本是针对整个仓库的变迁,所以:
svn add和svn delete现在也工作在目录上了,就像在文件上一样,还有svn copy和svn move也一样;然而,这些命令不会导致版本库即时的变化,相反,工作的项目只是“预定要”添加和删除,在运行svn commit之前没有版本库的修改- 目录不再是哑容器了;它们也有文件一样的修订版本号(更准确一点,谈论“修订版本5的目录foo/”是正确的)
- 因为 SVN 的版本是针对整个仓库的变迁,所以:
- 状态丰富并合理了
- 在Subversion,已经设法抹去
cvs status和cvs update之间的混乱。 cvs status命令有两个目的:- 第一,显示用户在工作拷贝的所有本地修改,
- 第二,显示给用户哪些文件是最新的。
- 很不幸,因为CVS难以阅读的状态输出,许多CVS用户并没有充分利用这个命令的好处。相反,他们慢慢习惯运行
cvs update或cvs -n update来快速查看区别,如果用户忘记使用-n选项,副作用就是将还没有准备好处理的版本库修改合并到工作拷贝。 - 对于Subversion,通过修改
svn status的输出使之同时满足阅读和解析的需要来努力消除这种混乱,同样,svn update只会打印将要更新的文件信息,而不是本地修改 - 详细说明:
status (stat, st): 显示工作副本中目录与文件的状态 用法: status [PATH...] 未指定参数时,只显示本地修改的条目(没有网络访问)。 使用 -q 时,只显示本地修改条目的摘要信息。 使用 -u 时,增加工作版本和服务器上版本过期信息。 使用 -v 时,显示每个条目的完整版本信息。 输出的前六栏各占一个字符宽度: 第一栏: 表示一个项目是增加、删除,还是修改 “ ” 无修改 “A” 增加 “C” 冲突 “D” 删除 “I” 忽略 “M” 改变 “R” 替换 “X” 未纳入版本控制,但被外部项目所用 “?” 未纳入版本控制 “!” 该项目已遗失(被非 svn 命令删除)或不完整 “~” 版本控制下的项目与其它类型的项目重名 第二栏: 显示目录或文件的属性状态 “ ” 无修改 “C” 冲突 “M” 改变 第三栏: 工作副本目录是否被锁定 “ ” 未锁定 “L” 锁定 第四栏: 已调度的提交是否包含副本历史 “ ” 没有包含 “+” 包含 第五栏: 该条目相对其父目录是否已切换 “ ” 正常 “S” 已切换 第六栏: 版本库锁定标记 (没有 -u) “ ” 没有锁定标记 “K” 存在锁定标记 (使用 -u) “ ” 没有在版本库中锁定,没有锁定标记 “K” 在版本库中被锁定,存在锁定标记 “O” 在版本库中被锁定,锁定标记在一些其他工作副本中 “T” 在版本库中被锁定,存在锁定标记但已被窃取 “B” 没有在版本库中被锁定,存在锁定标记但已被终止 是否过期的信息出现的位置是第八栏(与 -u 并用时): “*” 服务器上有更新版本 “ ” 工作副本是最新版的 剩余的栏位皆为变动宽度,并以空白隔开: 工作版本号(使用 -u 或 -v 时) 最后提交的版本与最后提交的作者(使用 -v 时) 工作副本路径总是最后一栏,所以它可以包含空白字符。 范例输出: svn status wc M wc/bar.c A + wc/qax.c svn status -u wc M 965 wc/bar.c * 965 wc/foo.c A + 965 wc/qax.c Status against revision: 981 svn status --show-updates --verbose wc M 965 938 kfogel wc/bar.c * 965 922 sussman wc/foo.c A + 965 687 joe wc/qax.c 965 687 joe wc/zig.c Status against revision: 981 有效选项: -u [--show-updates] : 显示更新信息 -v [--verbose] : 打印附加信息 -N [--non-recursive] : 过时;尝试 --depth=files 或 --depth=immediates --depth ARG : 受深度参数 ARG(“empty”,“files”,“immediates”,或“infinity”) 约束的操作 -q [--quiet] : 不打印信息,或只打印概要信息 --no-ignore : 忽略默认值和 svn:ignore 属性 --incremental : 给予适合串联的输出 --xml : 输出为 XML --ignore-externals : 忽略外部项目 --changelist ARG : 只能对修改列表 ARG 成员操作 [aliases: --cl]
- 在Subversion,已经设法抹去
- 分支和标签自然了
- Subversion不区分文件系统空间和“分支”空间;分支和标签都是普通的文件系统目录,这恐怕是CVS用户需要逾越的最大心理障碍;-)
- 带来的好处是
分支自然可见了!而标签不必要了!- 开辟分支,只是将目录复制到约定的分支容器中,比如说:
$ svn cp trunk branches/my-proj-branch_0.1
- 在CVS 中作为
changeset(修订集)来使用的标签在SVN 中,版本号天然就包含了这一特性, 完全可以用版本号来当 标签用!
- 开辟分支,只是将目录复制到约定的分支容器中,比如说:
- 注意:
因为Subversion把分支和标签看作普通目录看待,一直要记住检出项目的trunk(http://svn.example.com/repos/calc/trunk/), 而不是项目本身的(http://svn.example.com/repos/calc/)。 如果你错误的检出了项目本身,你会紧张的发现你的项目拷贝包含了所有的分支和标签
5.1.2. 迁移 CVS 到 SVN
- 要享用SVN 带来的便利,最直接的方法就是迁移原先的版本仓库到SVN来;
- 最流行的(好像是最成熟的)转化工具是cvs2svn(http://cvs2svn.tigris.org/),它是最初由Subversion自己的开发社区成员开发的一个Python脚本:它会多次扫描你的CVS版本库,并尽可能尝试推断提交,分支和标签,当它结束时,结果是可以代表代码历史的Subversion版本库或可移植的Subversion转储文件,关于指令和警告的详细信息可以看官方网站.
5.2. 客户端
SVN 有丰富的客户端软件可以选择,一般命令行内置工具已经足够好用,但是对习惯窗口界面的人,SVN 也有很多选择,其中最稳定和友好的是官方社区创建的:
- TortoiseSVN
- 这是和Windows 资源管理器紧密结合的工具,所有操作都包含在右键菜单中;
- 同时也包含了 合并,diff查阅,远程仓库浏览器 等等丰富的支持;
- 而且支持世界上大多数地区语言的界面; 建议Windows 中的用户下载体验;
5.3. 高级管理
SVN 作为成熟的版本管理系统,可以支持各种级别的开发支持; 当面对大型复杂系统开发时,作为基础配置管理支持系统,必须拥有一些高级功能来支撑复杂业务,这里介绍几方面常用知识;
5.3.1. 常用分支模式
- 版本控制在软件开发中广泛使用,这里是团队里程序员最常用的两种分支/合并模式的介绍,如果你不是使用Subversion软件开发,可随意跳过本小节,如果你是第一次使用版本控制的软件开发者,请更加注意,以下模式被许多老兵当作最佳实践,这个过程并不只是针对Subversion,在任何版本控制系统中都一样,但是在这里使用Subversion术语会感觉更方便一点。
5.3.1.1. 发布分支
- 大多数软件存在这样一个生命周期:编码、测试、发布,然后重复。这样有两个问题,第一,开发者需要在质量保证小组测试假定稳定版本时继续开发新特性,新工作在软件测试时不可以中断,第二,小组必须一直支持老的发布版本和软件;如果一个bug在最新的代码中发现,它一定也存在已发布的版本中,客户希望立刻得到错误修正而不必等到新版本发布。
- 这是版本控制可以做的帮助,典型的过程如下:
- 开发者提交所有的新特性到主干。 每日的修改提交到/trunk:新特性,bug修正和其他。
- 这个主干被拷贝到“发布”分支。 当小组认为软件已经做好发布的准备(如,版本1.0)然后/trunk会被拷贝到/branches/1.0。
- 项目组继续并行工作,一个小组开始对分支进行严酷的测试,同时另一个小组在/trunk继续新的工作(如,准备2.0),如果一个bug在任何一个位置被发现,错误修正需要来回运送。然而这个过程有时候也会结束,例如分支已经为发布前的最终测试“停滞”了。
- 分支已经作了标签并且发布,当测试结束,/branches/1.0作为引用快照已经拷贝到/tags/1.0.0,这个标签被打包发布给客户。
- 分支多次维护。当继续在/trunk上为版本2.0工作,bug修正继续从/trunk运送到/branches/1.0,如果积累了足够的bug修正,管理部门决定发布1.0.1版本:拷贝/branches/1.0到/tags/1.0.1,标签被打包发布。 整个过程随着软件的成熟不断重复:
- 当2.0完成,一个新的2.0分支被创建,测试、打标签和最终发布,
- 经过许多年,版本库结束了许多版本发布,进入了“维护”模式,许多标签代表了最终的发布版本。
5.3.1.2. 特性分支
- 一个特性分支是本章中那个重要例子中的分支,你正在那个分支上工作,而Sally还在/trunk继续工作,这是一个临时分支,用来作复杂的修改而不会干扰/trunk的稳定性,不象发布分支(也许要永远支持),特性分支出生,使用了一段时间,合并到主干,然后最终被删除掉,它们在有限的时间里有用。
- 还有,关于是否创建特性分支的项目政策也变化广泛,一些项目永远不使用特性分支:大家都可以提交到/trunk,好处是系统的简单—没有人需要知道分支和合并,坏处是主干会经常不稳定或者不可用,另外一些项目使用分支达到极限:没有修改曾经直接提交到主干,即使最细小的修改都要创建短暂的分支,然后小心的审核合并到主干,然后删除分支,这样系统保持主干一直稳定和可用,但是造成了巨大的负担。
- 许多项目采用折中的方式,坚持每次编译/trunk并进行回归测试,只有需要多次不稳定提交时才需要一个特性分支,这个规则可以用这样一个问题检验:如果开发者在好几天里独立工作,一次提交大量修改(这样/trunk就不会不稳定。),是否会有太多的修改要来回顾?如果答案是“是”,这些修改应该在特性分支上进行,因为开发者增量的提交修改,你可以容易的回头检查。
- 最终,有一个问题就是怎样保持一个特性分支“同步”于工作中的主干,在前面提到过,在一个分支上工作数周或几个月是很有风险的,主干的修改也许会持续涌入,因为这一点,两条线的开发会区别巨大,合并分支回到主干会成为一个噩梦。
- 这种情况最好通过有规律的将主干合并到分支来避免,制定这样一个政策:每周将上周的修改合并到分支,注意这样做时需要小心,需要手工记录合并的过程,以避免重复的合并(在“手工跟踪合并”一节描述过),你需要小心的撰写合并的日志信息,精确的描述合并包括的范围(在“合并分支到另一分支”一节中描述过),这看起来像是胁迫,可是实际上是容易做到的。
- 在一些时候,你已经准备好了将“同步的”特性分支合并回到主干,为此,开始做一次将主干最新修改和分支的最终合并,这样以后,除了你的分支修改的部分,最新的分支和主干将会绝对一致,所以在这个特别的例子里,你会通过直接比较分支和主干来进行合并:
$ cd trunk-working-copy $ svn update At revision 1910. $ svn merge http://svn.example.com/repos/calc/trunk@1910 \ http://svn.example.com/repos/calc/branches/mybranch@1910 U real.c U integer.c A newdirectory A newdirectory/newfile …通过比较HEAD修订版本的主干和HEAD修订版本的分支,你确定了只在分支上的增量信息,两条开发线都有了分枝的修改。
5.3.2. HOOKS
和CVS 类似SVN 同样为自动化事务响应开辟有"HOOKS"~钩子脚本支持;只是更加精简和规范化了;
一般提供9类标准钩子模板:
$ ls repos/hooks/ post-commit.tmpl post-unlock.tmpl pre-revprop-change.tmpl post-lock.tmpl pre-commit.tmpl pre-unlock.tmpl post-revprop-change.tmpl pre-lock.tmpl start-commit.tmpl
分别响应核心的四类操作:
| HOOK | 触发事件 | 参数 |
|---|---|---|
| start-commit | 提交事务产生前 | REPOS-PATH:到版本库的路径;USER:要进行提交的用户名 |
| pre-commit | 事务完成提交之前 | REPOS-PATH:版本库的路径;TXN-NAME正在提交的事务名称 |
| post-commit | 事务完成后 | REPOS-PATH:到版本库的路径;REV:被创建的新的修订版本号 |
| pre-revprop-change | 修订版本属性变更前 | REPOS-PATH:到版本库的路径;REVISION:要修改属性的修订版本;USER:经过认证的用户名;ACTION:属性自身的名字 |
| post-revprop-change | 修订版本属性被改变之后 | REPOS-PATH:到版本库的路径;REVISION:属性存在的修订版本;USER:经过校验的产生变化的用户名;ACTION:和属性自身的名字 |
| pre-lock | 尝试锁定文件时 | REPOS-PATH:到版本库的路径;PATH:锁定的路径;USER:企图执行锁定的用户 |
| post-lock | 路径被锁定后执行 | REPOS-PATH:到版本库的路径;USER:企图执行锁定的用户 |
| pre-unlock | 企图删除一个文件上的钩子时 | REPOS-PATH:到版本库的路径;PATH:锁定的路径;USER:企图解锁的用户 |
| post-unlock | 路径被解锁后 | REPOS-PATH:到版本库的路径;USER:企图解锁的用户 |
- 警告:
-
- 不要尝试用钩子脚本修改事务。一个常见的例子就是在提交时自动设置svn:eol-style或svn:mime-type这类属性。这看起来是个好主意,但它会引起问题。主要的问题是客户并不知道由钩子脚本进行的修改,同时没有办法通告客户它的数据是过时的,这种矛盾会导致出人意料和不能预测的行为。
- 作为尝试修改事务的替代,我们通过检查
pre-commit钩子的事务,在不满足要求时拒绝提交。
5.3.2.1. 强制写注释
举个实用的HOOKS 脚本实例:
- 将
pre-commit.tmpl重命名为:pre-commit并修订为以下内容:#!/bin/sh # PRE-COMMIT HOOK REPOS="$1" TXN="$2" SVNLOOK=/usr/local/bin/svnlook $SVNLOOK log -t "$TXN" "$REPOS" | \ grep "[a-zA-Z0-9]" > /dev/null if [ $? != 0 ]; then echo "$TXN $REPOS" 1>&2 echo "Alert! Commit message may not be empty." 1>&2 exit 1 fi exit 0 - 然后配置可执行属性,就可以自动拒绝空注释的检入事务,并送回对应提示:
"Alert! Commit message may not be empty."
5.4. 项目管理
SVN作为基础配置管理支撑系统,可以轻快的完成版本管理的全方位支持了,而且,进一步的配合Trac 可以完成项目管理的大部分流程支持!
5.4.1. Trac
Trac 是种轻型全功能项目管理环境,主要特性有:
- 以维基为核心的内容组织
- 以传票为核心的任务式流程
- 提供丰富的 TrackInks 维基字符约定,可以在任何场所方便的指向 SVN版本/传票/报表等等所有Trac 内部资源
- 类SQL语句的报表定制支持
- 里程碑综合视图
- 等等 详细的敬请期待哲思手册相关文章; PS: Trac中文化项目长期由 Zoom.Quiet 团队支持,推荐体验;
6. 文档版本
- v0.9 090308 ZoomQuiet 完成初稿
- v0.8 090303 ZoomQuiet 完成管理SVN部分,以及日常使用大部
- v0.7 090216 ZoomQuiet 增补文档大纲
- v0.6 090209 ZoomQuiet 认领写作
- v0.5 080301 zeuux 创建
| 动力源自:: txt2tags | 生成: 2009-03-09 00:16:15 | 介绍 | 原稿 |
|---|