Bazaar

Bazaar

 




Wiki Tools

  • Find Page
  • Recent Changes
  • Page History
  • Attachments

Bazaar-NG 指南

~- (!) 参考自: {en} ["IntroductionToBzr"]-~ 术语对照表:

branch                  - 分支
centralized model       - 集中式模型
checkout                - 检出
commit                  - 提交
identifier              - 标识符
merge                   - 合并
repository              - 仓库
revision                - 修订,修订版,版本
revision control system - 版本控制系统
subcommand              - 子命令
version control system  - 版本控制系统

Current for bzr-0.8, 2006-04 (from repository: doc/tutorial.txt)

引言

如果您业已熟悉分散式版本控制(decentralized revision control),那么完全可以 放心大胆的直接跳到“了解 Bazaar-NG“一节。另外,如果您只是熟悉版本控制而非分散式 版本控制,那么请从”DRCS 有何不同“一节开始。否则,最好弄点咖啡或绿茶,调整状态, 准备迎头赶上吧。

版本控制的目的

System Message: WARNING/2 (<string>, line 43)

Title underline too short.

版本控制的目的
=============

您总会时不时需要处理一些文本数据--比如程序源代码,web 站点或是 Unix 系统管理员 必须面对的 /etc 下的配置文件。自然而然的,您很可能犯一些让自己懊恼的错误。也许您 一不小心删除了自己邮件服务器的配置文件,或者把某个小项目(pet project)的源代码 搞得一团糟。无论是何种情形,您已经删除了重要信息,却又没法要回来,徒叹“时运不济”。 凡此种种,如果您曾遭遇过,那么或许该考虑试试 Bazaar-NG。

版本控制系统(下文简称为 RCS)比如 Bazaar-NG 可以让您跟踪一个目录的变化(修改), 方法是将它转化成一个比目录稍稍复杂些的东西,我们称之为 分支 。分支不仅保存有 这个目录当前状态,还保存了过去各个不同时间点的状态。因此,当您不小心做了些违背 自己意愿的操作时,就可以把该目录恢复到过去某个时间点的状态。

只要“提交一个 修订 ”,版本控制系统就能让用户保存对一个分支所做的修改。所创建 的修订实际上是自上次整棵树被保存以来所有修改的摘要。

这些修订还有其它用途。例如,我们可以给修订添加注释以便记录最近做修改的用意,方法 是提供一可选的日志信息。实际使用中,日志信息类似于“修正 web 模板,令 table 闭合” 或是“增加 sftp 支持。修正 #595”。

我们记下这些日志以便日后如果出现 stfp 相关的问题,就可能找出问题是何时发生的。

DRCS 有何不同

多数版本控制系统(RCS)都存储在服务器上。如果想对存储在 RCS 里的代码进行修改, 就需要连接到服务器上并“检出”这些代码。随后就会取得一个目录,用户可以在这个目录 里进行修改然后提交。RCS 客户端便会连接到 RCS 服务器上,并保存用户所做的修改。 上述方法称为集中式模型。

集中式模型会有一些缺陷。无论何时,若想进行版本控制工作,则集中式 RCS 要求 使用者必须连接到服务器上。如果您的服务器位于互联网的其它机器上,而您又不在 那台机器上,麻烦就来了。或者,更糟糕的情形是--您 ''确确实实'' 能够上网, 那服务器却挂了!

Decentralized Revision Control Systems (which I'll call DRCS after this point) deal with this problem by keeping branches on the same machine as the client. In Bazaar-NG's case, the branch is kept in the same place as the code that is being version controlled. This allows the user to save his changes (commit) whenever he wants -- even if he is offline. The user only needs internet access when he wants to access the changes in someone else's branch that are somewhere else.

A common requirement that many people have is the need to keep track of the changes for a directory such as file and subdirectory changes. Performing this tracking by hand is a awkward process that over time becomes unwieldy. That is, until one considers version control tools such as Bazaar-NG. These tools automate the process of storing data by creating a revision of the directory tree whenever the user asks.

Revision control software such as Bazaar-NG can do much more than just storage and performing undo. For example, with Bazaar-NG developer can take the modifications in one branch of software and apply them to another, related, branch -- even if those changes exist in a branch owned by somebody else. This allows developers to cooperate without giving write access to repository.

Bazaar-NG remembers the ''ancestry'' of a revision: the previous revisions that it is based upon. A single revision may have more than one direct descendant, each with different changes, representing a divergence in the evolution of the tree. By branching, Bazaar-NG allows multiple people to cooperate on the evolution of a project, without all needing to work in strict lock-step. Branching can be useful even for a single developer.

了解 Bazaar-NG

Bazaar-NG 只安装了一个新命令 bzr ,其余皆为它的子命令。您可以使用`bzr help` 命令获得一些帮助。将来会有更丰富的帮助信息。

版本(version)控制系统的作用之一是跟踪谁做了怎样的修改。在分散式系统中,这就 要求每个作者有一个全球惟一的标识符。大多数人已经有了一种:email 地址。bzr 已经 相当智能,通过查看您的用户名和主机名,它能自动生成一个 email 地址。如果您不喜欢 Bazaar-NG 猜想的地址,可以通过如下三种方法进行设置:

1. 在 ~/.bazaar/bazaar.conf 中添加如下两行,设置 email 地址。请注意 [DEFAULT] 是区分大小写的:

[DEFAULT]
email= Your Name <email@isp.com>

1. Override the previous setting on a branch by branch basis by creating a branch section in ~/.bazaar/branches.conf by adding the following lines:

[/the/directory/to/the/branch]
email= Your Name <email@isp.com>

1. Overriding the two previous options by setting the global environment variable $BZREMAIL or $EMAIL ($BZREMAIL will take precedence) to your full email address.

创建分支

默认情况下,历史存储在分支的 .bzr 目录里。不过有工具能够把历史存储在独立且 可能是远程的仓库里。在一现有目录里执行 bzr init 命令,我们便能创建一个 新的分支:

% mkdir tutorial
% cd tutorial
% ls -a
./  ../
% pwd
/home/mbp/work/bzr.test/tutorial
%
% bzr init
% ls -aF
./  ../  .bzr/
%

和 CVS 一样,分支里共有三类文件:unknown(未知的), ignored(忽略的)和 versioned(受版本控制的)。 add 命令可以让文件变成受版本控制的 (versioned):即对该文件所做的任何修改都将被系统记录下来:

% echo 'hello world' > hello.txt
% bzr status
unknown:
  hello.txt
% bzr unknowns
hello.txt
% bzr add hello.txt
added hello.txt
% bzr unknowns

如果您加错了文件,只需使用 bzr remove 命令让它不再受版本控制 (unversioned)即可。该命令并不会删除工作副本(working copy)。

分支的位置

所有历史都存储在分支内,分支只是磁盘上一个包含控制文件的目录。默认情况下, 并不像 svn 或 svk 那样存在独立的仓库或数据库。只要愿意,您也可以选择创建 一个仓库(参看 bzr init-repo 命令)。如果您的分支非常庞大,或者某个 中等规模的项目有大量的分支,您也许会这么做。

通常您会访问自己电脑文件系统上的分支,只需指定包含该分支的目录名即可。 bzr 还支持访问 http 上的分支,例如:

% bzr log http://bazaar-ng.org/bzr/bzr.dev/

安装相关的 bzr 插件之后,您还能通过 sftp 或 rsync 协议访问分支。

检查更改情况

一旦完成部分工作,您就打算把它 提交 到版本历史中。经常进行提交是个不错 的习惯:无论是您打算开发一个新功能,修复一个缺陷或打算改进某些代码或文档。 还有个好习惯是:在提交之前要确保代码能够编译并顺利通过其测试套件,以保证 每个版本都处于一个可控、良好的状态。您还能检查/回顾(review)自己所做的修改, 以确保此次提交合乎自己的要求,也可以让您在永久记录自己所做工作前,再三思量 一把。

下面的两个 bzr 命令特别有用:**status** 和 diff

bzr status

status 命令会给出自上次修订以来,您对工作目录所做的修改:

% bzr status
modified:
   foo

默认情况下, bzr status 会隐藏那些"烦人"的文件,未作修改的 (unchanged)或被忽略的(ignored)。如欲查看所有文件,可使用 --all 选项。status 命令还可以随意指定要查看的文件或目录的名字。

bzr diff

diff 命令会像标准的 diff 工具那样显示对所有文件所做的全部修改。 其输出可以通过管道传给大量程序比如''patch'', ''diffstat'', ''filterdiff'' 和 ''colordiff'':

% bzr diff
*** added file 'hello.txt'
--- /dev/null
+++ hello.txt
@@ -1,0 +1,1 @@
+hello world

使用 ''-r'' 选项,整棵树可以和较早版本进行比较,或给出两个版本之间的 区别:

% bzr diff -r 1000..          # 自版本 1000 后的所有更改
% bzr diff -r 1000..1100      # 版本 1000 至 1100 的更改

--diff-options 选项可以让 bzr 运行外部的 diff 程序,并传入选项,例如:

% bzr diff --diff-options --side-by-side foo

有些项目偏爱这样的 patch:在新旧文件路径的开头还要给出前缀(prefix)。 --prefix 选项可以用来提供这样的前缀。简言之,``bzr diff -p1`` 会生成 命令 patch -p1 可用的格式。

提交更改

当工作树的状态令人满意时,它就可以被 提交 到分支上了,以便创建一个 持有该状态快照的新修订版(revision)。

bzr commit

commit 命令需要一条描述此次修订所做修改的消息。它还会记录您的 userid, 当前时间和时区,还有整棵树的详细目录和内容。提交消息(commit message)由 ''-m'' 或 ''--message'' 选项指定。您可以输入多行提交消息;在大部分 shell 里,您可以进行多行输入,只要不在本行末尾加闭合引号即可。

% bzr commit -m "added my first file"

您还可以使用 -F 选项传入取自文件的消息。有些人喜欢在工作时记一些提交消息的 注解,然后检查 diff 以保证自己的所为合乎心意。(当您在中断后再次开始自己的 工作时,该文件也能派上不小的用场。)

在编辑器中指定消息

System Message: WARNING/2 (<string>, line 264)

Title underline too short.

在编辑器中指定消息
=================

如果您既不用 -m 也不用 -F 选项,那么 bzr 就会打开一个编辑器让您输入消息。 运行的编辑器由您的 $EDITOR 环境变量控制,或者把 editor 加到 ~/.bazaar/bazaar.conf 配置文件中; $BZR_EDITOR 会覆盖上面提到的 editor 选项。如果您未作任何修改就退出编辑器,则该次提交便被撤销。

有选择提交

如果您在 commit 命令行后指定了文件或目录名,那么只有对执行文件所做的修改才会被 提交,例如:

% bzr commit -m "documentation fix" commit.py

默认情况下,bzr 总是提交对整棵树所做的所有修改,即使是在子目录里进行提交也不 例外。如欲只提交当前目录及子目录内所做修改,请使用如下命令:

% bzr commit .

移除未提交的更改

System Message: WARNING/2 (<string>, line 286)

Title underline too short.

移除未提交的更改
===============

如果您已经进行了一些更改,随后又不想保留这些更改,可以使用 revert 命令回复 到上一个 head 版本。不过在此之前最好先用 bzr diff 查看一下将要移除哪些内容。 revert(回复)命令缺省会回复整棵树(the whole tree);如果指定了文件名或目录名, 那么只会回复指定文件或目录。 revert 还会清除等待合并的修订版本(revision)。

忽略文件

许多源码树都包含一些不需要进行版本控制的文件,比如编辑器备份文件,目标文件或字节码 (bytecode)文件,还有编译产生的程序等等。您只要不添加它们即可,不过这样一来这些 文件总会以未知文件形式突然出现(always crop up as unknown files)。您还可以指定 bzr 忽略这些文件,只要将它们添加到源码树顶层目录内名为 ''.bzrignore'' 的文件即可。

该文件包含一个文件通配符(或 "glob")列表,每行一个。常见内容如下:

*.o
*~
*.tmp
*.py[co]

如果 glob 包含 / ,则它要么和这棵树顶层的整个路径匹配,要么只个该文件名匹配。 因此前面的示例会忽略所有子目录里扩展名为 .o 文件,而下面的例子则只会忽略 顶层的 config.h 文件和 doc/ 里的 HTML 文件:

./config.h
doc/*.html

欲获取被忽略文件及其所匹配模式的列表,可使用如下命令 ''bzr ignored'':

% bzr ignored
config.h                 ./config.h
configure.in~            *~

如果忽略模式(ignore pattern)和受版本控制的文件相匹配,或添加一个被忽略的 文件也是允许的。忽略模式对受版本控制的文件不起作用,它们只能决定不受版本控制 的文件是显示为未知的(unknow)还是被忽略的(ignored)。

一般情况下,''.bzrignore'' 文件也应进行版本控制,这样一来,该分支的新副本 也能使用同一模式:

% bzr add .bzrignore
% bzr commit -m "Add ignore patterns"

查看历史

bzr log

bzr log 命令会给出一个早先修订版列表。 bzr log --forward 命令的功能 类似,只不过是按年月日顺序排序,最新的修订版在最后输出。

和 bzr diff 一样,bzr log 也支持 -r 参数:

% bzr log -r 1000..          # 版本 1000 及其后的所有版本
% bzr log -r ..1000          # 版本 1000 及之前的所有版本
% bzr log -r 1000..1100      # 版本 1000 至 1100 的更改
% bzr log -r 1000            # 版本 1000 的更改

分支统计信息

System Message: WARNING/2 (<string>, line 350)

Title underline too short.

分支统计信息
===========

bzr info 命令能够显示一些工作树和分支历史相关的摘要信息。

对目录进行版本控制

System Message: WARNING/2 (<string>, line 356)

Title underline too short.

对目录进行版本控制
=================

bzr 对文件和目录进行的版本控制还能够跟踪重命名并将它们智能的合并起来:

% mkdir src
% echo 'int main() {}' > src/simple.c
% bzr add src
% bzr status
A       src/
?       src/simple.c
% bzr add src/simple.c
% bzr status
A       src/
A       src/simple.c

译注

Windows 下版本 .8 执行 bzr add src 后会将 src 目录及其内的文件都添加到
提交候选列表中。

删除和移除文件

直接在工作目录里删除文件或目录,您就可以删除它们。这和 CVS 有点不同,CVS 还要求 您执行 cvs remove

bzr remove 命令只是让文件不再受版本控制,但并不删除工作副本。当您加错了 文件或发现某个文件其实不需要进行版本控制,该命令就能派上用场了。
% rm -r src
% bzr remove -v hello.txt
?       hello.txt
% bzr status
?       hello.txt
D       src/
D       src/simple.c

如果您不小心移除错了文件,可以使用 bzr revert 命令恢复之。

分支

除从头开始自己的项目外,更常见的情况是您打算给一个已有项目提交自己的修改。 您可以通过如下方法获取已有分支的副本:复制其整个目录,解开一个 tarball, 或者使用类似 rsync 的工具取得一个远程副本。您还能使用 bzr 来获取一份副本。 由于这份新的副本是一个新分支,该命令被称为 branch

% bzr branch http://bazaar-ng.org/bzr/bzr.dev
% cd bzr.dev

该命令会把这个分支的完整历史拷贝下来,这样我们就能在本地执行所有操作:log, annotate, 制作和合并分支。如果您愿意,也可以使用选项只获取部分历史。

获取上游更改

通过“拖拉”(pull)双亲分支的修改,您可以和该分支保持同步:

% bzr pull

执行上述命令后,本地目录就成了源的一个镜像。包括 ''revision-history'' - 它是 一个该分支里所做提交的列表,而非和其它分支进行合并。

该命令只在下来情形下方才有效:如果您的本地(目的)分支只是双亲分支的一份旧副本, 同时未在本地做过提交;或者您在本地分支所做的最新提交已合并至双亲分支。

合并相关的分支

If two branches have diverged (both have unique changes) then bzr merge is the appropriate command to use. Merge will automatically calculate the changes that exist in the branch you're merging from that are not in your branch and attempt to apply them in your branch.

% bzr merge URL

If there is a conflict during a merge, 3 files with the same basename are created. The filename of the common base is appended with .BASE, the filename of the file containing your changes is appended .THIS and the filename with the changes from the other tree is appended .OTHER. Using a program such as kdiff3, you can now comfortably merge them into one file. To commit you have to rename it to the original basename and delete the other two files. As long as there exist files with .BASE, .THIS or .OTHER the commit command will complain.

[TODO: explain conflict markers within files]

发布您的分支

您不需要专门的服务器来发布 bzr 分支,只需普通的 web 服务器即可。只要把 所有文件包括 .bzr 目录镜像到您的服务器上就可以了。通过如下三种方法,我们 就可以添加(push)一个分支(或对分支所做的修改):

  • Rsync: rsync -avrz LOCALBRANCH servername.com/this/directory/here

    (或其它能把目录发布到 web 站点的工具)

  • bzr push sftp://servername.com/this/directory/here

    (目录必须已存在)

  • BzrTools 自带的 push 插件