对话 UNIX:Bazaar

保存代码的好地方

软件开发的特点是重构、进退两难、发现缺陷、顿悟和突破;所以管理更改是必不可少的。Bazaar 是一种强大的新一代源代码控制系统,它能够适应任何开发团队的工作模式。本文简要介绍 Bazaar。

Martin Streicher, 软件开发人员, Pixel, Byte, and Comma

作者照片 - martin streicherMartin Streicher 是一位 Ruby on Rails 的自由开发人员和 Linux Magazine 的前任主编。Martin 毕业于 Purdue University 并获得计算机科学学位,从 1986 年起他一直从事 UNIX 类系统的编程工作。他喜欢收集艺术品和玩具。


developerWorks 投稿作者

2010 年 11 月 04 日

马克·吐温曾经说,“当您对一篇文章已经满意时,才是写作真正开始的时候。只有到那时,您才能清楚地认识到您真正想表达的是什么。” 这一观点非常正确,这也适用于软件。只有在编写应用程序之后,问题的性质、范围和微妙之处才会逐渐清晰起来。在输入第一行代码到最终打包发布之间会经历许多波折,包括发现最初的方法错误、遇到死路、重写、重构、进退两难、发现缺陷、顿悟和突破。

常用缩写词

  • API: Application programming interface
  • FTP: File Transfer Protocol
  • HTTP: Hypertext Transfer Protocol
  • SFTP: Secure File Transfer Protocol
  • URL: Uniform resource locator

在开发期间确实经常要进行更改,必须用特殊的软件跟踪更改。这种软件称为源代码控制 (或版本控制 )系统,它们记录对应用程序所做的每次修订。源代码控制系统允许对比修订、在文件的不同版本之间切换以及把修订收集在一个版本中。目前有许多专有和开放源码的源代码控制系统,尽管各个系统的特性、模式和最佳实践之间存在差异,但目标是相同的:审查谁在什么时候做了什么。流行的商业源代码控制软件包括 Perforce 和 AccuRev;比较先进的开放源码源代码控制软件包括 Subversion、Arch、Mercurial、Git 和 Bazaar(见 参考资料 中的链接)。

在开放源码软件中,Bazaar 很引人注目,因为 Ubuntu Linux® 发行版的开发采用了它,Ubuntu 是一个包含数千个组件的大型软件项目。Bazaar 之所以很特殊还因为它实际上可以适应任何团队的工作模式。例如,一些开发团队喜欢集中,他们把所有更改收集并应用于一个存储库(Subversion 是集中式的系统)。其他团队喜欢分散,团队中的每个开发人员有独立的存储库,可以像主存储库一样共享它们。在这种方案中,可以把一个全体共同拥有的存储库指定为用于集成的 “中心”,但是它与其他存储库的差异只在于约定(Git 是分散的系统)。另一种流行的工作风格是指定一个开发人员作为 “看门人”,只有他有权修改权威性存储库。更改都提交给看门人,他对更改进行组合、审查和批准并应用于主存储库。Bazaar 的灵活性非常强,可以适应所有这些工作风格。与 Subversion 一样,Bazaar 可以与中心存储库进行同步。与 Git 一样,可以在本地处理工作,不连接任何服务器。

Bazaar 还有其他许多出色的特性,比如用于与其他软件工具集成的 API、把 Bazaar 与 Git 和 Subversion 等系统集成起来的插件以及简单的分支编号方案(可以直接反映每个分支的衍生关系)。另外,可以非常快速地采用 Bazaar,这使它成为控制 shell “点” 文件、文档和系统配置文件的版本的理想选择。Bazaar 的文档也很出色 — 清晰、简洁且实用。

Bazaar 入门

Bazaar 适用于所有主流操作系统。如果愿意从头构建 Bazaar,可以从 Bazaar 的主页下载源代码,也可以下载适当的二进制代码(见 参考资料 中的链接)。Bazaar 由一组命令行实用程序组成,但是如果您喜欢鼠标操作,也可以选用 Bazaar 社区提供的多种图形化实用程序。可以先通过图形化工具快速地熟悉 Bazaar,然后根据需要改用命令行工具。

如果使用 UNIX® 或 Linux 系统,您的发行版很可能提供预先构建的 Bazaar 包 — 包名通常为缩写 bzr;与 Bazaar 相关的包使用这个缩写作为前缀。例如,如果使用 Ubuntu 或从 Debian 衍生出的任何 Linux 版本,那么可以使用 Advanced Packaging Tool (APT) 快速地找到并安装 Bazaar 软件。使用 apt-cache 搜索 bzr,见 清单 1

清单 1. 在 APT 存储库中寻找与 Bazaar 相关的所有工具
$ apt-cache search bzr
bzrtools - Collection of tools for bzr
bzr-builder - construct a bzr branch from a recipe
bzr-cvsps-import - CVS to Bazaar importer
bzr-email - Notification email plugin for Bazaar
bzr-fastimport - Fast-import/fast-export plugin for Bazaar
bzr-git - Bazaar plugin providing Git integration
bzr-gtk - provides graphical interfaces to Bazaar (bzr) version control
bzr-loom - Focused patch plugin support for Bazaar
bzr-pqm - bzr plugin to submit an email to a Patch Queue Manager
bzr-rebase - Rebase plugin for Bazaar
bzr-search - search plugin for Bazaar
bzr-stats - statistics plugin for Bazaar
bzr-svn - Bazaar plugin providing Subversion integration
bzr-upload - Bazaar plugin for uploading to web servers
...
bzr - easy to use distributed version control system

# Install the core bzr package
$ apt-get install bzr

后一个 shell 命令下载并安装核心 Bazaar 组件。

如果您的操作系统没有提供 Bazaar,也很容易从头构建它,尤其是在 UNIX 系统上。首先,下载 Bazaar 源代码压缩文件并把它解压到一个本地临时目录中。接下来,确认系统有 Python 2.5 或更高版本以及 cElementTreeparamikoPyrex 模块。有了源代码和这些模块之后,输入以下命令安装 Bazaar:

python setup.py install

安装过程把 Bazaar 添加到 /usr/local/bin 中。如果希望把这个软件安装在其他地方,那么使用 --home 选项并指定目录的完整路径名,比如 python setup.py install --home $HOME

$ wget http://launchpad.net/bzr/2.1/2.1.0/+download/bzr-2.1.0.tar.gz
$ tar xzf bzr-2.1.0.tar.gz
$ cd bzr-2.1.0
$ sudo python setup.py install

通过 bzr 实用程序控制 Bazaar。输入 bzr help 就会列出最常用的命令,见 清单 2。如果希望获得某个命令的帮助信息,那么输入 bzr help command,其中的 command 是命令名,比如 bzr help init

清单 2. 可用的 Bazaar 命令
$ bzr help
Bazaar -- a free distributed version-control tool
http://bazaar-vcs.org/

Basic commands:
  bzr init           makes this directory a versioned branch
  bzr branch         make a copy of another branch

  bzr add            make files or directories versioned
  bzr ignore         ignore a file or pattern
  bzr mv             move or rename a versioned file

  bzr status         summarize changes in working copy
  bzr diff           show detailed diffs

  bzr merge          pull in changes from another branch
  bzr commit         save some or all changes
  bzr send           send changes via email

  bzr log            show history of changes
  bzr check          validate storage

  bzr help init      more help on e.g. init command
  bzr help commands  list all commands
  bzr help topics    list all help topics

Bazaar 命令的序列称为诀窍(recipe),在线帮助提供许多诀窍,以此帮助用户快速掌握 Bazaar 的用法和传授最佳实践。例如,bzr help init 的内容中提供一个把任何目录转换为 Bazaar 存储库的诀窍,见 清单 3

清单 3. 把目录转换为 Bazaar 存储库的诀窍
$ cd ~/project
$ bzr init
$ bzr add .
$ bzr status
$ bzr commit -m "imported project"

该诀窍有五个步骤。要想按照它执行操作,首先把 project 目录改为您希望进行源代码控制的目录。接下来,运行 bzr init 在当前目录中添加子目录 .bzr,这个目录用来包含存储库的帐目元数据。bzr add . 命令递归地把 “点” 目录(当前目录)的内容添加到存储库管理的文件清单中。但是,它不创建当前文件状态的快照。bzr commit 记录存储库中所有文件的状态并添加简短的注释。可以通过 -m 选项的参数提供注释(一定要使用引号以保证文本完整不变),也可以忽略此选项并在您喜欢的文本编辑器中创建说明。bzr status 报告什么将要添加到存储库中、什么会改变、什么会被编辑等等。


核心概念

Bazaar 与其他源代码控制系统有许多共同点,但是它的实现不一样,而且利用了您已经熟悉的一些机制(比如 Secure Shell (SSH) 和 URL)。Bazaar 管理修订,可以分别通过分叉和合并创建和收集分支。下面是 Bazaar 中的一些关键概念:

  • 修订(revision) 是对一个或多个文件所做的更改的集合。可以通过修订修复 bug 或实现新特性。每个修订有惟一的 ID(稍后进一步讨论 ID)、一个提交者(committer)以及零个或更多个作者(author)。提交者是记录这个修订的开发人员,而作者是对这个修订有贡献的开发人员。图 1 显示一个修订。
    图 1. 一个 Bazaar 修订
    Bazaar 修订的示例
  • 通常情况下,每个修订有一个前身,即父修订。因此,可以把开发过程看作由修订组成的链条,每个修订基于其父修订中包含的更改。图 2 说明这种模式。
    图 2. 开发过程被看作一系列修订
    开发过程被看作一系列修订

    但是,开发过程很少如此有秩序,尤其是在许多开发人员同时工作的情况下。一个修订也可以有多个前身。在这种情况下,修订代表一次合并(见 图 3)。

    图 3. 开发线路的组合形成合并,即有多个父修订的修订
    开发线路的组合形成合并,即有多个父修订的修订
  • 正如前面提到的,修订 ID 直接反映修订的衍生关系。修订从 1 开始顺序编号,每当开发链出现分叉(即分支 )时添加后缀。例如,在 图 3 中,修订 2 分出两个分支:2.12.2。分支 2.1 中的第一个修订是 2.1.1;同一分支中的第二个修订是 2.1.2,以此类推。当合并两个或更多分支时,删除后缀,恢复原来的编号方案。修订 3 是合并两个分支的结果。图 4 显示一个图形化工具,它使用与 图 3 非常相似的方式显示 Bazaar 历史。Bazaar 的修订编号方案比 Git 等系统更有意义、更简洁,Git 使用很长的意义不明的 MD5 散列值作为惟一标识符。
    图 4. 图形化工具显示 Bazaar 历史
    图形化工具显示 Bazaar 历史
  • 分支(branch)末端修订(tip revision) 的指针,末端修订是在同一衍生链中没有后续修订的修订。在 图 3 中,修订 3 是分支,因为它是最后一个修订。另外,修订 2.1.2 和 2.2.2 也是分支,因为它们分别是 2.1 和 2.2 衍生链中的最后一个修订。

Bazaar 的优点之一是它重用了大家熟悉的现有模式。分支仅仅是文件夹。可以在 Bazaar 中找到其他符合常识的特性。例如,如果使用 Bugzilla 跟踪 bug,可以通过 --fixes 选项把修订标注为 bug 补丁。


执行典型的任务

在一般情况下,Bazaar 管理完整的文件目录。但是,如果希望从版本控制的范围中排除某些文件,或者只对某些文件或子目录进行控制,也是可以实现的。在最初创建存储库时或在其生命期内,不一定非使用点号 (.) 操作整个当前目录。许多 Bazaar 命令可以接受文件和目录名列表,只在指定的实体上操作。

例如,如果修改了 easy.c、medium.c 和 hard.c 文件,但是只希望提交 easy.c,那么只需在提交命令中指定此文件:

$ bzr commit -m "Fix bug no. 99." easy.c

更好的是,Bazaar 提供的一个特殊特性可以分组和隔离对某些文件的操作。视图 是文件和目录的集合。在启用视图时,只能看到集合中的文件。可以创建多个视图并在它们之间切换,可以根据需要禁用和启用视图以显示和隐藏文件。Bazaar 文档指出,“定义视图并不删除工作树中的其他文件 — 视图只是提供一个覆盖在工作树上的 ‘窗口’。” bzr commitbzr addbzr ls 等命令把操作范围限制在当前视图。其他命令操作文件系统,它们不受视图影响。

要想忽略某些类型的文件,比如编译时生成的对象文件或文本编辑器生成的备份文件,可以在存储库的最高层创建名为 .bzrignore忽略文件。把这个文件也置于版本控制之下,这有助于避免合作者在存储库中添加伪造的文件。bzr ignore 命令在此文件中添加条目。忽略文件并不排除已经置于版本控制之下的文件;它只排除存储库中还没有的文件。

bug 补丁或改进常常涉及多个文件和每个文件中的不同代码段。除非开发人员非常小心地执行不连续提交,否则特性会混在一起,很难把一批更改与某一 bug 报告或改进请求联系起来。更常见的另一种情况是,开发人员可能发现有必要让文件退回到某一状态以便隔离 bug。在这两种情况下,开发人员可能希望把一部分修订搁置起来。Bazaar 为此提供了 shelve 特性。可以对修订执行 shelve,即把它们搁置在一边;提交(如果需要的话);然后执行 unshelve,即把选出的更改恢复到原来离开的位置。Bazaar 可以搁置各种差异。

下面是一个可能出现的场景。假设 dictionary.txt 文件在最近一次提交到存储库之后做了三个更改。可以使用 bzr diff 对比您工作的当前状态和存储库中的内容,见 清单 4

清单 4. 对比当前工作和存储库版本
$ bzr diff
=== modified file 'dictionary.txt'
--- dictionary.txt	2010-04-10 23:57:00 +0000
+++ dictionary.txt	2010-04-10 23:58:40 +0000
@@ -1,2 +1,5 @@
+bonzo
 chico
 groucho
+harpo
+zeppo

输出表明第 1、4 和 5 行是新的。为了搁置这些更改,运行 bzr shelve。这个命令以交互方式提示您确定是保留还是搁置各个差异。如果希望给 shelve 加注释,可以提供 -m 选项,见 清单 5

清单 5. 给 shelve 加注释
$ cat dictionary.txt
bonzo
chico
groucho
harpo
zeppo

$ bzr shelve -m 'Save other brothers for later.'
--- dictionary.txt	2010-04-10 23:57:00 +0000
+++ dictionary.txt	2010-04-11 00:15:56 +0000
@@ -1,2 +1,5 @@
+bonzo
 chico
 groucho
+harpo
+zeppo
Shelve? [yNfq?] y
Selected changes:
 M  dictionary.txt
Shelve 1 change(s)? [yNfq?] y
Changes shelved with id "1".

如果现在查看此文件,应该只会看到两行。还可以使用 bzr shelve --list 列出可用的 shelve(见 清单 6)。

清单 6. 查看 shelve 的列表
$ cat dictionary.txt
chico
groucho

$ bzr shelve --list
  1: Save other brothers for later.

shelve 作用相反的命令是 unshelve。这个命令把文件恢复到以前的状态,见 清单 7

清单 7. 把文件恢复到以前的状态
$ bzr unshelve
Using changes with id "1".
Message: Save other brothers for later.
 M  dictionary.txt
All changes applied successfully.
Deleted changes with id "1".

$ cat dictionary.txt
bonzo
chico
groucho
harpo
zeppo

与别人共享您的工作

尽管 Bazaar 可以实现集中的版本控制方案,但是也能够很好地支持大规模分布式软件开发。共享极其简便,使用了许多现有的 UNIX 共享技术。

最简单的技术是本地文件系统,这也是默认技术,除非指定其他方式。可以使用句柄 file://path/to/your/branch 让另一个开发人员共享您的分支,其中的 path/to/your/branch 是您的分支的绝对路径名,比如 /Users/martin/code/emailer。有了句柄,另一个开发人员就可以创建基于您的工作的分支:

 $ bzr branch file://Users/martin/code/emailer

branch 命令复制这个分支的完整历史,可以得到合并、分叉和扫描历史所需的所有信息。因为分支只是文件夹,所以不一定非使用 bzr branch。也可以通过 cp -pr、展开压缩文件或使用 rsync 等命令执行远程复制来复制分支。还可以通过 SFTP、HTTP、FTP 和专门为 Bazaar 设计的协议 bzr::// 共享分支。(在命令行上输入 bzr help urlspec 就可以看到支持的协议的完整列表。)有了分支之后,可以使用 bzr pull 命令更新它,让它与原分支的状态匹配。

发布分支也很简单,只需共享分支的 URL。不需要通过特殊的服务器发布 Bazaar 分支,只需让别人可以通过前面提到的任何方法访问分支的文件和 .bzr 目录。还可以使用一个特殊的 Bazaar 命令推送分支(或对分支的更改):

$ bzr push sftp://servername.com/path/to/directory

操作分支的所有命令都可以接受 URL。


Bazaar 提供的丰富特性

Bazaar 的特性非常多,无法在这里一一列举。在 Bazaar 网站 上可以找到完整的介绍和兼容软件目录。Bazaar 还提供 “智能服务器”,它通过 SSH 实现一种特殊的 Bazaar 协议。您或系统管理员可以建立智能服务器,从而把项目驻留在自己的源代码服务器上。管理文档还解释了如何把 Bazaar 与插件组合起来以改进核心特性。另外,可以通过这个软件提供的钩子 注入自己的脚本和代码以执行其他任务,比如部署代码或运行连续集成测试。

参考资料

学习

  • 对话 UNIX:阅读本系列中的其他部分。
  • Bazaar 在线文档:学习如何使用 Bazaar。
  • Launchpad:这个免费开放源码驻留平台的意图是共享开放的源代码。它提供综合的 bug 跟踪、源代码审查、用于团队协作的邮件列表等。
  • Canonical:Bazaar 和 Launchpad 由 Ubuntu Linux 的商业赞助商 Canonical 赞助。
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。
  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
  • AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。
  • IBM Systems Magazine for AIX 中文版:本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM 的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。
  • 技术书店:阅读关于这些和其他技术主题的图书。

获得产品和技术

  • Bazaar:从项目主页下载 Bazaar 软件。
  • Git:Git 是一个流行的版本控制系统,Linux 内核和其他重要项目使用它进行开发协作。Git 是由 Linux 的创造者 Linus Torvalds 创建的。
  • Subversion:这个历史很长的开放源码版本控制系统适用于几乎所有操作系统。它的存储库是集中的。有许多图形化 Subversion 客户机。
  • Mercurial:Mercurial 是最近出现的开放源码版本控制系统。它可以在所有主流操作系统上运行。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=569906
ArticleTitle=对话 UNIX:Bazaar
publish-date=11042010