はじめに
Current for bzr-0.16, 2007-05
一箇所で集中管理しないやりかたのリビジョン管理システムに慣れているなら、Bazaarに慣れるのもたやすいことでしょう。 リビジョン管理システムに慣れているけれども、分散しているリビジョン管理に対してはそうでない場合には "DRCSはどう違う?"から初めて下さい。
リビジョン管理の目的
あなたは、テキストデータ処理をしたことがあるでしょう。それはソースコードであったりウェブサイトやUnix システムの管理車が扱うような/etcにある設定ファイルだったかもしれません。
深く後悔するような失敗をやらかすこともあるでしょう。 おそらくメールサーバーの設定ファイルを削除してしまったり、プロジェクトのソースコードをひどい状態にしてしまったりするのです。 なんであれ、重要な情報を削除してしまったら、元に戻すことを熱望することでしょう。 もし今までにそういうことがあったなら、Bazaarに向いています。
Bazaarのようなリビジョンコントロールシステム(以降RCS)はディレクトリをブランチと呼ばれるやや複雑なディレクトリ構成に変更を記録します。 ブランチはその時点のディレクトリの状態を保存するだけでなく、過去のとある時点においてどんなであったかも記録します。
それゆえ、望まないことをしてしまっても過去のとある時点へとディレクトリを復元することができるのです。
リビジョン管理システムはリビジョンをコミットすることによりブランチに修正を保存します。 生成されたリビジョンはツリーが保存された最後の瞬間からの変更をまとめたものです。
これらのリビジョンは他の利用法もあります。 たとえば、補足的なログメッセージを提供する意図で最近の修正を記録するためにリビジョンにコメントつけをすることができます。 実際にはログメッセージは"Webテンプレートをテーブルを閉じるように修正した"とか"sftpサポートを追加した。#595を修正。"などです。
これらのログを保存しているので、もしsftpにてなんらかの問題があっても問題の発生したであろう時間を特定することができます。
DRCSはどう違うのか
多くのリビジョンコントロールシステム(RCS)では(コミットした内容は)サーバーに保存されます。 RCSに保存されたコードで作業したければ、サーバーに接続してコードをチェックアウトする必要があります。 そうすることによって修正後、コミットすることができるのです。 RCSクライアントはRCSサーバーに接続し変更点を保存します。こういったやりかたは集中管理モデルとして知られています。
集中管理モデルにはいくつか不利な点があります。集中管理型RCSはバージョン管理をしたいときにはサーバーに接続可能であることが必要なのです。 これでは、サーバーがネットワーク上にあり自分のマシンがそうでない時や、その逆の場合には問題です。
非集中型管理リビジョン管理システム(以降DRCS)はこの問題をクライアントマシンにブランチを保持することによって対処します。 Bazaarでは、バージョンコントロール下にあるコードと同じところにブランチが保存されます。 これによりユーザーはいつでも修正をオフライン状態であってもコミットすることができるのです。 インターネットアクセスが必要になるのは誰か別のブランチの修正にアクセスしたいときだけです。
たいていの人はファイルやディレクトリの変更をディレクトリ内に履歴保存しています。 こういった作業を手で行うのは面倒です。Bazaarのようなバージョンコントロールツールの使用を考慮するまでは。
Bazaarのようなリビジョンコントロールソフトウェアは単なる保存ややりなおし以上の事ができます。 例えば、開発者はBazaarを使ってソフトウェアのとあるブランチの修正を関連する他のブランチへと適用することができます。 -- 誰か他の開発者のブランチにその修正が存在していても、です。 このことはリポジトリに書き込み権限を与えることなく開発者同士の協調作業することを可能にします。
(注:BazaarではリポジトリをWebサイトにアップロードするだけでリポジトリの公開ができるので、 各人がそれぞれリポジトリを用意しておけばいい、ということを意図しているんだと思います。)
Bazaarはリビジョンの "祖先" を覚えています: つまり元となった以前のリビジョンです。
あるリビジョンはツリーの発展における差異を表現する、ひとつ以上の(それぞれが異なる修正を含んだ)子孫を持つかもしれません。 ブランチによって厳密なロックで作業する必要なしに、プロジェクトの発展において、複数の開発者で協調することができます。 ブランチというものは、開発者が一人でも便利です。
Bazaar事始め
Bazaarはbzrなるコマンドをインストールします。 あらゆるコマンドはすべて、bzrのサブコマンドとなっています。 bzr helpでヘルプを参照できます。 いくつかの引数はトピックにまとめられています: 参照可能なトピックについてはbzr help topicsでわかります。今後さらにトピックが追加されていくことでしょう。
バージョンコントロールシステムの役割のひとつは、誰が何を修正したのかというのを記録することです。 分散システムにおいては、修正したそれぞれの人ごとに一意となる識別子が必要です。 たいていの人はすでにこの識別子を持っています: つまりEメールアドレスです。 Bzrは自動的にユーザー名とホスト名からEメールアドレスを生成したりもします。
(注:とは言っても、ログイン名@ホスト名なので実用においては再設定することになるでしょう。)
Bazaarが行なうアドレスの推測機能が気に入らなければ、以下の方法があります。
1. whoamiサブコマンドを経由して変更します。これが最も簡単なやりかたです。 グローバルな設定を行うには以下の通りにします:
% bzr whoami "Your Name <email@example.com>"
ブランチごとに設定したい場合にはブランチフォルダ内にて以下を実行します
% bzr whoami --branch "Your Name <email@example.com>"Eメールアドレスを~/.bazaar/bazaar.confに次の行を追加します: [DEFAULT]は大文字小文字の区別があります。
[DEFAULT] email=Your Name <email@isp.com>
上記のように、ブランチごとの設定を~/.bazaar/locations.confのブランチセクションに次の行を追加することで上書きできます。
[/the/path/to/the/branch] email=Your Name <email@isp.com>Overriding the two previous options by setting the global environment variable $BZR_EMAIL or $EMAIL ($BZR_EMAIL will take precedence) to your full email address.1(1, 2) On Windows, the users configuration files can be found in the application data directory. So instead of ~/.bazaar/branch.conf the configuration file can be found as: C:Documents and Settings<username>Application DataBazaar2.0branch.conf. The same is true for locations.conf, ignore, and the plugins directory.
Windows環境においては、ユーザーの設定ファイルはアプリケーションディレクトリに存在します。 したがって、~/.bazaar/branch.conf設定ファイルは C:/Documents and Settings/<username>/Application Data/Bazaar/2.0/branch.conf 同様のことは、locations.conf等の設定ファイルやpluginsディレクトリにも言えます。
ブランチの作成
履歴は通常ブランチディレクトリ内の.bzrディレクトリへと保存されます。 将来的にはリモートといったように別個のリポジトリへと保存する機能を備えることでしょう。
新規ブランチは既存のディレクトリ内でbzr initを実行します:
% mkdir tutorial % cd tutorial % ls -a ./ ../ % pwd /home/mbp/work/bzr.test/tutorial % % bzr init % ls -aF ./ ../ .bzr/ %
CVS同様に、ファイルの状態は3種類あります: unknown(不明)、ignored(無視)、そしてversioned(管理対象)です。
addコマンドによりそのファイルはバージョン管理対象となります: つまり、変更はシステムによって記録されます。
% echo 'hello world' > hello.txt % bzr status unknown: hello.txt % bzr add hello.txt added hello.txt % bzr status added: hello.txt
誤ってファイルを追加した場合には、単にbzr removeを使ってバージョン管理からはずします。 これによって作業コピーが削除されることはありません。
bzr removeはそのときバージョン管理されていれば作業コピーを削除しますが、最後にコミットされたバージョンには影響しません。 ファイルを削除したくないならば、--keepオプションをbzr removeに与えます。 あるいは常に削除するなら--forceオプションを使います。
ブランチのありか
すべての履歴はブランチの中にあり、管理ファイルを含むディレクトリ上に存在します。 デフォルトではsvnやsvkのように別個のリポジトリやデータベースはありません。 もし望むならば、(そういった)リポジトリをつくることもできます。(bzr init-repoコマンドを参照してください。) 非常に巨大なブランチや適度なサイズのプロジェクトのブランチが多くある場合にはそうすることを希望するかもしれません。
通常、コンピュータのファイルシステム上のブランチを(ブランチを含む)ディレクトリ名を与えることで参照します。 bzrはブランチをhttpやsftpを経由してアクセスすることもサポートしています。例:
% bzr log http://bazaar-vcs.org/bzr/bzr.dev/ % bzr log sftp://bazaar-vcs.org/bzr/bzr.dev/
bzrプラグインをインストールすることで、rsyncプロトコルを使うこともできます。
ある場所に保存しているブランチをどやって公開するかについては"ブランチを公開する"セクションを参照してください。
変更の確認
ひとまず作業が完了したら、履歴をコミットしたいことでしょう。 頻繁にコミットするのは良いやりかたです: 新機能や、バグ修正、コードの改善やドキュメント化をしたときなど。 コードがコンパイルでき、テストを通ることやすべてのリビジョンが問題ないことを確認するのは良い習慣です。
変更をレビューすることもできますし、意図したものをコミットしようとしているのか、恒久的に記録する前に考え直す機会もあります。
ここで便利なのは次の2つのコマンドです: status及びdiffです
bzr status
statusコマンドは最後のリビジョンから作業ディレクトリに加えられた変更を知らせます。
% bzr status modified: foo
bzr statusは未変更や無視されたファイルを隠します。 statusコマンドにはオプションとしてチェックしたいファイルやディレクトリ名を渡すこともできます。
bzr diff
diffコマンドはunified diff形式ですべてのファイルの変更を表示します。 これはpatchやdiffstat、filterdiffおよびcolordiffといったプログラムにパイプ経由で出力を渡すこともできます。
% bzr diff === added file 'hello.txt' --- hello.txt 1970-01-01 00:00:00 +0000 +++ hello.txt 2005-10-18 14:23:29 +0000 @@ -0,0 +1,1 @@ +hello world
-rオプションを指定すれば、ツリーは過去のバージョン、あるいは2つのバージョン間と比較されます。
% bzr diff -r 1000.. # r1000からの差分 % bzr diff -r 1000..1100 # r1000 から r1100までの差分
--diff-optionsオプションは外部のdiffコマンドを起動しそのときに渡すオプションを指定します。
% bzr diff --diff-options --side-by-side foo
Some projects prefer patches to show a prefix at the start of the path for old and new files. The --prefix option can be used to provide such a prefix. As a shortcut, bzr diff -p1 produces a form that works with the command patch -p1.
古いものと新しいもののパスの開始位置にプレフィクスを表示するのを好むプロジェクトもあります。 --prefixオプションはそういったプレフィクスを提供するために使われます。 短縮形として、bzr diff -p1はpatch -p1コマンドと共に使う形式のパッチを生成します。
(注:ここあまり自信なし)
変更のコミット
作業ツリーの状態に満足したら、ブランチにコミットされ、状態を保持した新しいリビジョンが作られます。
bzr commit
コミットコマンドはリビジョンの変更点の記述を引数として必要とします。 これはまたユーザ識別子や時刻、タイムゾーン、ツリーの一覧や内容を記録します。 コミットメッセージは-m や --messageオプションで指定します。 複数行のコミットメッセージを入力することもできます: たいていのシェルでは最初と最後をクウォートすることで入力できます。
% bzr commit -m "added my first file"
あるいはまた-Fオプションを使ってコミットメッセージをファイルから指定することもできます。 作業中にノートをとり、やったことを確かめるために差分をレビューするのを好む人もいます。 (中断の後、作業を再開する際には便利です。)
エディタからのメッセージ
-m や -F オプションのいずれも指定せずコミットしようとすると、メッセージを入力するためのエディタが起動します。
(注:Windowsならメモ帳が起動することでしょう)
このとき起動するエディタは$VISUALや$EDITOR環境変数によって制御されますが、設定ファイル~/.bazaar/bazaar.confによって上書きされます。
(注:Windowsではbazaar.confは%APPDATA%/bazaar/2.0/bazaar.confとなります。 つまり、ログイン名がkenであればC:/Documents and Settings/ken/Application Data/bazaar/2.0/bazaar.confとなります。)
$BZR_EDITOR環境変数は上記よりも優先されます。
何も入力せずにエディタを閉じればコミットはキャンセルされます。
コミット対象の選択
コミットコマンドにファイルかディレクトリ名を渡すと指定したもののみがコミットされます。
% bzr commit -m "documentation fix" commit.py
通常、bzrはサブディレクトリからbzrを実行しても、ツリーの変更をすべてコミットします。 カレントディレクトリ以下だけをコミットするには、以下のようにします:
% bzr commit .
未コミットの変更点の削除
いくつか変更をしたけれども、コミットしたくない場合、revertコマンドを用いて直近のHEADバージョンに戻します。 bzr diffを最初に実行して削除されるものを確認するのは良い考えです。 通常、revertコマンドはツリーの全てを戻します。 もしファイルやディレクトリを指定すればrevertの影響範囲が限定されます。 bzr revertは保留されているマージリビジョンのリストもクリアします。
無視するファイル
多くのソースツリーではバージョン管理する必要のないファイルを含んでいることがあります。 それはエディタのバックアップであったりオブジェクトやバイトコード、ビルド済みプログラムなどです。 追加しなければいいのですが、そうするとunknownファイルとして常に表示されます。 そこで、ツリーの上位に.bzrignoreと呼ばれるファイルを追加することで、それらのファイルをbzrが無視するようにすることができます。
このファイルはワイルドカードのリストを一行ごとに含んでいます。典型的な例はこの通りです:
*.o *~ *.tmp *.py[co]
グラブがスラッシュを含むなら、ツリーのトップからのすべてのパスに対してマッチします。 そうでなければファイル名にのみマッチします。 ゆえに先程のサンプルではすべてのディレクトリの.o拡張子のファイルを無視しますが、この例だとトップレベルのconfig.hとdocディレクトリ以下のHTMLファイルを無視します。
./config.h doc/*.html
どのファイルが無視され、どのパターンにマッチするか知るにはbzr ignoredを使ってください:
% bzr ignored config.h ./config.h configure.in~ *~
管理されたファイルにマッチする無視パターンか、無視するファイルがあれば良いです。 無視するパターンは管理下のファイルには影響しません。 管理されていないファイルのみが、unknownないしignoredとして報告されます。
.bzrignoreファイルは通常バージョン管理されるべきで、そうすれば新たなブランチにも適用されます。
% bzr add .bzrignore % bzr commit -m "Add ignore patterns"
全体で有効な無視設定
特定のプロジェクトに依存しないがユーザーによっては無視すべきファイルが存在することがあります。 エディタの一時ファイルや、個人的なテンポラリファイルなどです。 これらのファイルをプロジェクトごとに追加するよりも、bzrは全体で有効となる無視設定ファイル(~/.bazaar/ignore)をサポートしています。 このファイルはプロジェクトごとの無視ファイルと同様の文法です。
履歴の調査
bzr log
bzr logコマンドは以前のリビジョンのリストを示します。 bzr log --forwardコマンドは最近のリビジョンのログを最後に表示します。
bzr diffと同様、bzr logも-r引数をサポートしています。
% bzr log -r 1000.. # リビジョン1000とそれ以降 % bzr log -r ..1000 # r1000まで % bzr log -r 1000..1100 # 1000から1100までの変更 % bzr log -r 1000 # リビジョン1000のみ
ブランチの統計
bzr infoコマンドは作業ツリーとブランチの履歴情報を表示します。
(例えば、手元のとあるブランチだとこんな具合です。)
C:\(省略)>bzr info Standalone tree (format: dirstate) Location: branch root: file:///C:/(省略) Related branches: publish to branch: sftp://(省略)
ディレクトリのバージョン管理
bzrはファイルやディレクトリの名前を記録し、賢くマージできます。
% mkdir src
% echo 'int main() {}' > src/simple.c
% bzr add src
added src
added src/simple.c
% bzr status
added:
src/
src/simple.c
ファイルの削除と移動
ファイルやディレクトリの削除は単に作業ディレクトリ内で削除することによって行うことができます。 これはCVSとはちょっと違っています。CVSならcvs removeが必要です。
(bzr removeの実行とファイルやディレクトリの削除は同じ意味です。)
bzr removeはファイルをバージョン管理からはずしますが、作業ファイルをまず削除しません。 これは誤ったファイルの追加や実際にはバージョン管理しないファイルを決める際には便利です。
% rm -r src % bzr remove -v hello.txt ? hello.txt % bzr status removed: hello.txt src/ src/simple.c unknown: hello.txt
(hello.txtがバージョン管理からはずされている状態(removed)です。)
うっかり削除してしまっても、bzr revertを使って元に戻せます。
ブランチ
あなたが自分のプロジェクトをはじめるよりも、すでにあるプロジェクトに加えた修正を反映したいことでしょう。 これを行うには、既存のブランチのコピーを取得する必要があります。 この新しいコピーは新規ブランチとなる可能性を秘めているので、コマンドはブランチと呼ばれています:
% bzr branch http://bazaar-vcs.org/bzr/bzr.dev % cd bzr.dev
このコピーはブランチの履歴を完全に含んでいるので、ローカルですべての操作を実行できます: ログ、アノテーション、ブランチの作成やブランチからのマージなど。 望めば部分的に履歴を取得するためのオプションもあります。
上流の変更への追従
親のブランチを最新にするには変更点を"ひっぱってくる"ことで可能です。
% bzr pull
これを実行した後のローカルディレクトリはソースコードのミラーとなります。 このブランチは他のブランチからマージされたものだけでなく、ブランチで行なわれたリビジョンの履歴を含んでいます。
このコマンドはローカルのブランチが親のブランチより古く新しいコミットがないか、 ローカルブランチへのコミットが親のブランチへマージされているのならばうまくいきます。
関連ブランチからのマージ
もし2つのブランチがめいめいで独自の修正を行なっていたとしたら、bzr mergeを使うのが適切です。 mergeコマンドはマージしようとしているブランチの修正を評価し、自分のブランチへの適用を試みます。
% bzr merge URL
もしマージの際にコンフリクトが発生すれば、ベース名が同じ3つのファイルが生成されます。 共通の基準となるのが".BASE"で、修正点を含むのが".THIS"、そして他のツリーの修正を含むのが".OTHER"です。 kdiff3といったプログラムを使えば、安心してそれらを一つにマージすることができます。 コミットするためにはマージされた".THIS"ファイルを元のファイル名へとリネームする必要があります。 コンフリクトの解消をするにはresolveコマンドを使わなければなりません。 これは".OTHER"や".BASE"ファイルを削除します。 これらのファイルがある限り、コミットには失敗します。
% kdiff3 file.BASE file.OTHER file.THIS % mv file.THIS file % bzr resolve file
[TODO: explain conflict markers within files]
ブランチを公開する
bzrブランチを公開するのに、特別なサーバーは必要ありません。普通のウェブサーバーで十分です。 単にサーバーにファイルをミラーするだけです。.bzrディレクトリも含めて。 以下の3つの方法のいずれかでブランチにpushすることができます。
- 最もなやりかたはbzrを使うことです。
% bzr push sftp://servername.com/path/to/directory
(--create-prefixオプションが使われていないなら、push先のディレクトリはあらかじめ存在していないといけません。)
- あるいはBzrToolsに含まれるrspushプラグインを使い、リビジョン履歴と作業ツリーの変更をrsyncでpushすることです。
あるいはファイルをtarballやrsyncその他の手段でファイルを送り、手作業でコピーすることです。 このやりかたはpushを使うより間違いやすいですが、状況次第では簡単で、素早い手段です。
ツリー同士の変更の移動
(注:うっかり別のブランチで作業してしまったとき、どうやって変更内容を本来のブランチにパッチとして適用するか、という話です。)
誰にでもあること: 誤ったツリーに変更をくわえてしまうことがあります。きっと誤ったディレクトリで作業を開始してしまったのでしょう。 変更点は思ったよりも大きいとわかったので、そのために新たなブランチをつくります。
修正点を別のツリーに適用するには
% cd NEWDIR % bzr merge --uncommitted OLDDIR
これによりOLDDIRにある、まだコミットしていない修正はNEWDIRへと引き継がれます。 コミットされているものは、NEWDIRにその内容がそのままマージすることが可能であっても適用されません。
OLDDIRに修正が残ったままですが、NEWDIRに(問題なくマージされ)満足であれば、bzr revertを用いてその修正を元に戻すこともできます。
NEWDIRはOLDDIRのコピーである必要はありませんが、関連しているべきです。 違いがあればあるほど、コンフリクトの危険が増します。
Powered by docutils, and CSS Design by tri-star