[ Topページへ戻る ]

Bazaarでバージョン管理

概要

 「分散リポジトリ方式」のバージョン管理ツール御三家の1つがこのBazaarです。GitやMercurialに比べてやや知名度が低いものの、日本語ファイル名の対応には一日の長があり、Windows/Unix混在環境で日本語ファイル名を扱う環境であれば、現時点ではBazaarに軍配が上がります。 

入手先

ホームページ

ドキュメント(日本語)

最新版の日本語訳ドキュメントが以下URLにあります。

ドキュメントのダウンロードの中に、日本語訳ドキュメントもあるので、ローカルで参照するときはそちらを入手するとよいでしょう。

インストール

2012年3月27日現在、Ver.2.5.0が最新です。

Windows

公式サイトから、Windows用バイナリが提供されています(2012年3月27日現在 Ver.2.5.0-1)。コマンドラインツール、GUIツール、TortoiseBZRが含まれています。また、プラグインもあらかじめ組み込まれています。

Linux

CentOS 5/Red Hat Enterprise Linux 5

標準では搭載されておらず、EPELリポジトリからVer.1.3.1がインストールできます。最新版を利用するにはソースコードを入手してビルドします。詳細は、CentOS 5用バイナリパッケージのページに記載しています。

CentOS 6/Red Hat Enterprise Linux 6

標準で搭載されています(Ver.2.1.1)。

最初の設定

ユーザー情報の設定

Bazaarをインストールして使用する最初に、ユーザー情報を設定します。以後、Bazaarはこのユーザー情報をリポジトリに記録します。

設定はコマンドで以下を実行します。

$ bzr whoami "Bazaar Taro <taro.bazaar@example.com>"
$ bzr whoami
Bazaar Taro <taro.bazaar@example.com>

無視ファイルの設定

リポジトリ個別のほか、そのユーザーで共通に無視ファイルを設定することができます。

共通の無視ファイルの定義場所は、OSによって以下となります。

なお、リポジトリ個別の無視ファイルについては、リポジトリのトップディレクトリ下に .bzrignore のファイル名で記述し、他のファイル同様コミットします。

無視ファイルの記述方法(glob)は、1行に1パターンずつ記述します。なお、bzr ignore --helpで説明を確認できます。

ファイル名のパターンは、すべてのディレクトリにおいてパターンに合致したファイルを無視します。*はワイルドカードです。

*.a
*.o
*.py[co]
*.so
*.sw[nop]
*~
.#*
[#]*#

無視ディレクトリの記述方法

bin
lib
**/bin
**/obj
src/test/**/*.java

正規表現を使ってパターンを指定する場合、RE: を行頭に指定します。

RE:^#
無視ファイル記述メモ

エディタの設定

T.B.D.

基本概念

分散リポジトリ管理ツールでよく聞く「クローン」は、Bazaarではブランチと呼びます。

Bazaarのバージョン管理モデル

「分散リポジトリ方式のバージョン管理」について調べると、とっても複雑でピンとこない説明が延々と出てきます。バージョン管理ツールもどんどん高機能になっているので、その仕組みを理解しようとしてもだんだん難しくなってきており、これではよっぽど相当バージョン管理に慣れた技術者でないと使いこなせそうにないと思ってしまいます。

複雑なことを理解しようとすると大抵挫折してしまい、今自分で出来るやり方でなんとか解決しようと、結局手作業での管理を始めてしまい、人間には誤りがつきものですから、バージョン管理作業ミスが発生して不具合につながってしまいます。

そこで、分散リポジトリの仕組みから理解するのではなく、バージョン管理を使いたいシーンに沿った機能から理解をしていくことにします。

個人で特定のディレクトリ/ファイルをバージョン管理する

 最も単純な使い方としては、ある一箇所のディレクトリだけをバージョン管理するモデルがあります。Bazaarは、既存のディレクトリを移動したりせずに後からBazaarの管理下に置くことができます。

個人で特定のディレクトリ/ファイルをバージョン管理するが、試行錯誤や状況によってディレクトリを複数作って作業する

 個人ベースでのプログラム開発時によくあるシナリオですが、CVSやSubversion等の中央集中リポジトリがある場合にも、コミットに至る前の試行錯誤で個人的な作業ディレクトリを作っている場合に当てはまります。

個人で特定のディレクトリ/ファイルをバージョン管理するが、作業マシンが複数あって(例:会社、モバイル、自宅)、それぞれで作業した内容を共有したい

 会社の開発室でのデスクトップマシン、外出/移動時のモバイルマシン、自宅のハイスペックマシンで同じディレクトリ/ファイルに対して一環して作業する場合です。それぞれのマシンの作業を同期できるようにします。

複数で共同開発するが、マスターリポジトリを置かずにピア・ツー・ピアな同期を行う

 複数開発者で共同作業する場合、それぞれの作業を頻繁に同期する必要があります。

複数で共同開発するが、マスターリポジトリを置いてネットワークで常時接続した環境でバージョン管理する

 Subversionのスタイルとほぼ一緒な集中リポジトリ方式をBazaarでも使用することができます。

複数で共同開発するが、マスターリポジトリを置いて、しかしネットワークに接続していない環境でもバージョン管理する

 分散リポジトリ方式のゴールとなる使い方です。

個人で特定のディレクトリ/ファイルをバージョン管理する

 リポジトリは作業ディレクトリと同じディレクトリに作られます。また、CVSやSubversionと違って、リポジトリは作業ディレクトリのトップディレクトリにのみ置かれ、サブディレクトリ以下には管理情報は置かれません。バージョン管理をやめるときはこのトップディレクトリにある管理情報用ディレクトリを削除してしまえばよいのです。

 また、リポジトリにインポート後、別なディレクトリに作業ディレクトリをチェックアウトせずに、そのままもとの場所が作業ディレクトリとして使用できます。そのため、既存のディレクトリの一部ファイルだけをリポジトリ管理下におくといった使い方ができます。

リポジトリを新規作成する

新たにディレクトリを作成し、そのディレクトリでbzr initコマンドを実行します。

~$ mkdir myrepo
~$ cd myrepo
myrepo$ bzr init
Created a standalone tree (format: 2a)

myrepo$ ls -a
.   ..   .bzr
myrepo$

デフォルトでは、"2a"と呼ばれるフォーマットでリポジトリが生成されます。

既存のディレクトリをリポジトリとする

上述の新規作成と同様にリポジトリを作成した後、既存のディレクトリ・ファイルをリポジトリに追加します。

リポジトリの新規作成

バージョン管理下に置きたいディレクトリのトップに移動して、そのディレクトリでbzr initコマンドを実行します。

~$ cd myproj
myproj$ bzr init
Created a standalone tree (format: 2a)

myproj$

ディレクトリ内のファイル/サブディレクトリをリポジトリに追加

トップディレクトリでbzr addコマンドを実行します。無視ファイルに該当しないファイル・ディレクトリがリポジトリに追加されます。

myproj$ bzr add
adding eveing
adding hello.txt
adding morning
adding noon
adding morning/breakfast.xt
adding noon/lanch.txt

myproj$

空ディレクトリも追加されています。

リポジトリ管理下のファイル/サブディレクトリの状況を調査

bzr statusコマンドで状況を調べます。

myproj$ bzr status
added:
  evening/
  hello.txt
  morning/
  morning/breakfast.txt
  noon/
  noon/lanch.txt

myproj$

addedは、リポジトリへ追加予定だが未コミットの状況のファイル・ディレクトリを示します。他には、unknown(バージョン管理外)、modified(修正中で未コミット)、deleted(削除予定で未コミット)、等があります。

無視パターンに合致しているものを調べるには、bzr ignoredコマンドを実行します。

myproj$ bzr ignored
hello.txt~                                         *~
morning/breakfast.o                                *.o

myproj$

無視パターンに合致すると、bzr statusコマンドには出てきません。

リポジトリへ追加したファイル/サブディレクトリをコミット

bzr commitコマンドで、それまでに指定していた操作をリポジトリへ反映します。

myproj$ bzr commit -m "最初のコミット"
Committing to: C:/Users/taro/Documents/myproj/
added evening
added hello.txt
added morning
added noon
added morning/breakfast.txt
added noon/lanch.txt
Committed revision 1.

myproj$

この状態で、先のbzr statusコマンドを実行しても、何も表示されません。

myproj$ bzr status
myproj$

リポジトリのログを表示

コミットを確認するためにログを表示します。bzr logコマンドを実行します。

myproj$ bzr log
------------------------------------------------------------
revno: 1
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj
timestamp: Tue 2010-12-21 07:40:54 +0900
message:
  最初のコミット

myproj$

デフォルトでは詳細表示されます。オプションで、短い形式(--short)、1行形式(--line)、GNU Changelog形式(--gnu-changelog)、xml形式(--xml)が指定できます。

myproj$ bzr log --short
    1 Bazaar Taro    2010-12-21
      最初のコミット

myproj$ bzr log --line
1: Bazaar Taro 2010-12-21 最初のコミット

myproj$ bzr log --gnu-changelog
2010-12-21  Bazaar Taro <taro.bazaar@example.com>

        最初のコミット

myproj$

リポジトリのログは、最新順に表示されます。古い順に表示させるには、オプションで --forward を指定します。最新の例えば10件のログを表示させるには、--l 10 を指定します。

日々の作業

作業ツリーの状況表示

先に述べたbzr statusコマンドで作業ツリーの状態を表示します。

作業ツリー上のファイル/ディレクトリの修正

コミット済みのファイルを修正すると、bzr statusコマンドで、"modified:"として表示されます。

myproj$ echo "こんにちは" >> hello.txt 
myproj$ bzr status
modified:
  hello.txt

myproj$

新しいファイル/ディレクトリを作成したときは、bzr addコマンドで追加します。
新しいファイル/ディレクトリを作成したときは、状態は"unknown:"となっています。bzr add コマンドを実行すると状態が"added:"に変わります。

myproj$ mkdir night
myproj$ bzr status
unknown:
  night/

myproj$ bzr add night
adding night
myproj$ bzr status
added:
  night/

myproj$

ファイル/ディレクトリを削除するときは、bzr rmコマンドで削除します。

myproj$ bzr rm evening
deleted evening

myproj$ bzr status
removed:
  evening/
added:
  night/

myproj$

ファイルの移動は、bzr move コマンドを使用します。

修正内容の確認

修正内容を確認するときは、bzr diff コマンドを実行します。

myproj$ bzr diff
=== modified file 'hello.txt'
--- hello.txt   2010-12-20 22:56:48 +0000
+++ hello.txt   2010-12-21 17:45:37 +0000
@@ -1,1 +1,2 @@
 こんにちは
+バージョン管理システム

myproj$

外部ツールで差分を見るときは、--usingオプションを使います。

bzr diff --using=c:/Program\ Files/WinMerge/WinMergeU.exe

修正の取り消し

コミット前であれば、修正を取り消すには bzr revert コマンドを実行します。

myproj$ bzr revert evening
+N  evening/

myproj$

修正のコミット

先に述べたbzr commitコマンドで修正をコミットします。

リポジトリへのタグ打ち

現在のリビジョンに対してタグを打つには、bzr tag コマンドを実行します。

myproj$ bzr tag Release-1.0
Created tag Release-1.0.

myproj$

リポジトリに打たれたタグを確認するには、bzr tags コマンドを実行します。

myproj$ bzr tags
Release-1.0          3

myproj$

タグ名と、そのタグが紐づいているリビジョン番号が表示されます。

個人で特定のディレクトリ/ファイルをバージョン管理するが、試行錯誤や状況によってディレクトリを複数作って作業する

 作業途中で、ちょっと横道にそれた修正をしたいのですが、オリジナルにその修正は反映させたくないということがあります。別なAPIを試してみるとか、新しい機能を実験してみるとか、デバッグ/パフォーマンスチューニングのためにprint文(ログ文)を入れたりといった、実験的色合いのある修正がその典型例です。

 Subversion、CVSなどの中央集権的なリポジトリではブランチをうまく活用しない場合、こうした作業をいったん自分のマシンで修正を行い、リポジトリに修正を反映するのは、その修正が正式採用となった暁に限られます。つまり、実験的作業はバージョン管理から外れるということになりがちです。
 しかし、本来バージョン管理をしたいのは、試行錯誤で行って戻ってを繰り返す実験的作業においてです。ツールの制約で人が楽できないというのは本末転倒です。

 分散リポジトリ方式では、いままでローカルで自己管理していたようなプライベートディレクトリを気軽に作成し、任意の時点で任意の部分を本元のリポジトリに反映(マージ)することが簡単になります。そこで、ちょっとした実験や改善を行う専用ブランチをいくつでも作って作業します。

ブランチの作成(ローカルディレクトリ)

ブランチの作成は、bzr branch コマンドを実行します。既に作成されているリポジトリ myproj から、実験用のリポジトリ myexp をブランチして作成します。

~$ ls
myproj
~$ bzr branch myproj myproj_branch1
Branched 3 revision(s).

~$ 

ブランチの情報を確認します。

~$ bzr info myproj_branch1
Standalone tree (format: 2a)
Location:
  branch root: myproj_branch1

Related branches:
  parent branch: myproj

~$

ブランチして作成した場合、リポジトリの情報に、"parent branch"という項目でブランチ元の情報が記載されています。

親ブランチとローカルブランチの変更の流れ

この時点で、親ブランチ(myproj)とローカルブランチ(myproj_branch1)のリビジョンの変遷は以下です。

親ブランチ(myproj)               開始→[1]→[2]→[3]
                                               ↓
ローカルブランチ(myproj_branch1)         merge

ブランチの修正とコミット

ブランチの修正は、ブランチ内で通常にファイルを変更し、コミット作業を行います。ここでコミットした内容はあくまでブランチしたリポジトリにのみ反映されるので、元のリポジトリには影響を与えません。

~$ cd myproj_branch1
myproj_branch1$ vi morning/breakfast.txt
   修正作業
myproj_branch1$ bzr diff
=== modified file 'morning/breakfast.txt'
--- morning/breakfast.txt       2010-12-20 22:40:54 +0000
+++ morning/breakfast.txt       2010-12-26 08:46:58 +0000
@@ -0,0 +1,4 @@
+御飯
+味噌汁
+アジの開き
+白菜の漬物

myproj_branch1$ bzr commit -m "朝食メニューの記述"
Committing to: C:/Users/taro/Documents/myproj_branch1/
modified morning/breakfast.txt
Committed revision 4.

myproj_branch1$

修正・コミットを複数行ってみます。朝食メニューを少し豪華にしましょう。

myproj_branch1$ vi morning/breakfast.txt
   修正作業
myproj_branch1$ bzr diff
=== modified file 'morning/breakfast.txt'
--- morning/breakfast.txt       2010-12-27 00:53:07 +0000
+++ morning/breakfast.txt       2010-12-27 00:56:50 +0000
@@ -1,4 +1,5 @@
 御飯
 味噌汁
 アジの開き
+焼き海苔
 白菜の漬物

myproj_branch1$ bzr commit -m "朝食のおかずを追加"
Committing to: C:/Users/taro/Documents/myproj_branch1/
modified morning/breakfast.txt
Committed revision 5.

myproj_branch1$ 

ブランチの履歴(ログ)

この時点で、親ブランチ(myproj)とローカルブランチ(myproj_branch1)のリビジョンの変遷は以下です。

親ブランチ(myproj)          開始→[1]→[2]→[3]
                                              ↓
ローカルブランチ(myproj_branch1)           branch→[4]→[5]

ここで、ログを見てみることにしましょう。

myproj_branch1$ bzr log
------------------------------------------------------------
revno: 5
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj_branch1
timestamp: Mon 2010-12-27 09:57:53 +0900
message:
  朝食のおかずを追加
------------------------------------------------------------
revno: 4
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj_branch1
timestamp: Mon 2010-12-27 09:53:07 +0900
message:
  朝食のメニューは和食としました
------------------------------------------------------------
revno: 3
tags: Release-1.0
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj
timestamp: Wed 2010-12-22 03:09:49 +0900
message:
  挨拶文に追記
------------------------------------------------------------
revno: 2
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj
timestamp: Tue 2010-12-21 07:56:48 +0900
message:
  挨拶追加
------------------------------------------------------------
revno: 1
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj
timestamp: Tue 2010-12-21 07:40:54 +0900
message:
  最初のコミット

myproj_branch1$ 

まず、ブランチを作成する前に、元のリポジトリである親ブランチ(myproj)に3つの修正がコミットされていました。この3つについては、"branch nick"が親ブランチ名"myproj"となっています。ブランチを作成するときは、親ブランチの修正履歴を継承していることが分かります。

次に、ブランチを作成した以降に修正をコミットした分については、"branch nick"が新しいブランチであるローカルブランチ名"myproj_branch1"となっています。

ブランチの修正を元のリポジトリへマージ

ブランチでの作業結果を、本元に反映したい場合は、マージを行います。大まかな流れは以下です。

  1. 本元のリポジトリ(親ブランチ)の最新修正を、今作業しているブランチ(ローカルブランチ)に取り込む(マージ)
  2. ローカルブランチの修正を親ブランチへ反映する(プッシュ)

本元のリポジトリの最新修正を取り込み

Bazaarには、ブランチ間の修正情報の授受に関する以下コマンドがあります。

ブランチ元(親ブランチ)で修正された情報をブランチ(ローカルブランチ)に取り込むには、bzr pullコマンドがよさそうに思えます。しかし、bzr pullコマンドは、以下の条件のいずれかが満たされていないと失敗します。

すなわち、ローカルブランチを事実上修正していないときしかbzr pullコマンドは使えません。そこで、通常はbzr mergeコマンドを使います。

myproj_branch1$ bzr merge
Merging from remembered parent location C:/Users/taro/Documents/myproj_branch1/
Nothing to do.

myproj_branch1$ 

親ブランチで新たな修正がなければ、"Nothing to do"と表示されます。

親ブランチで新たな修正があるときは、以下のような実行結果になります。

myproj_branch1$ bzr merge
Merging from remembered parent location C:/Users/taro/Documents/myproj_branch1/
+N  evening/dinner.txt
All changes applied successfully.

myproj_branch1$ bzr status
added:
  evening/dinner.txt
pending merge tips: (use -v to see all merge revisions)
  Bazaar Taro 2010-12-27 夕食ファイルを追加

この例では、親ブランチで新たに追加されたファイルがローカルブランチに取り込まれます。bzr mergeコマンドを実行しただけでは、コミット済み状態にはならず、bzr statusコマンドで見るとローカルブランチに対する修正として扱われています。親ブランチから取り込んだ修正はローカルブランチにコミットします。

myproj_branch1$ bzr commit -m "親ブランチの最新を取り込み"
Committing to: C:/Users/taro/Documents/myproj_branch1/
added evening/dinner.txt
Committed revision 7.

親ブランチから取り込んだ修正は、ログ上では次のように表示されます。

myproj_branch1$ bzr log
------------------------------------------------------------
revno: 7 [merge]
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj_branch1
timestamp: Tue 2010-12-28 07:59:08 +0900
message:
  親ブランチの最新を取り込み
:(略)

revno: のところに数字の後ろに[merge]となっています。

ローカルブランチの修正を親ブランチへ反映

ローカルブランチの修正を親ブランチに反映するには、bzr pushコマンドを使用します。

myproj_branch1$ bzr push
bzr: ERROR: No push location known or specified.

myproj_branch1$ 

ブランチを作成後、最初のpush時は、デフォルトのpush先が未設定のため明示的にpush先を指定しないとエラーになります。(2回目からは、push先を覚えているので省略化)

myproj_branch1$ $ bzr push ../myproj
All changes applied successfully.
Pushed up to revision 5.

myproj_branch1$ 

この時点で、親ブランチ(myproj)とローカルブランチ(myproj_branch1)のリビジョンの変遷は以下です。

親ブランチ(myproj)          開始→[1]→[2]→[3]ーーー→merge
                                              ↓      ↑
ローカルブランチ(myproj_branch1)           branch→[4]→[5]

親ブランチへ移動し、ログを見てみます。

myproj$ bzr log
------------------------------------------------------------
revno: 5
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj_branch1
timestamp: Mon 2010-12-27 09:57:53 +0900
message:
  朝食のおかずを追加
------------------------------------------------------------
revno: 4
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj_branch1
timestamp: Mon 2010-12-27 09:53:07 +0900
message:
  朝食のメニューは和食としました
------------------------------------------------------------
revno: 3
tags: Release-1.0
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj
timestamp: Wed 2010-12-22 03:09:49 +0900
message:
  挨拶文に追記
------------------------------------------------------------
revno: 2
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj
timestamp: Tue 2010-12-21 07:56:48 +0900
message:
  挨拶追加
------------------------------------------------------------
revno: 1
committer: Bazaar Taro <taro.bazaar@example.com>
branch nick: myproj
timestamp: Tue 2010-12-21 07:40:54 +0900
message:
  最初のコミット

myproj$ 

ローカルブランチでの作業履歴もきっちり引き継いでいます。

親ブランチ・ローカルブランチ双方で修正を行った場合の親ブランチへ反映

親ブランチでrevno: 5まで変更が加えられた状態から、今度は親ブランチとローカルブランチと双方で修正を行い、それを親ブランチに反映(統合)するという流れを見てみます。

親ブランチでの修正とコミット

親ブランチで、ファイルを新たに作成します。

myproj$ vi evening/dinner.txt
  :
myproj$ bzr add evening/dinner.txt 
adding evening/dinner.txt

myproj$ bzr commit -m "夕食ファイルを追加"
Committing to: C:/Users/taro/Documents/myproj/
added evening/dinner.txt
Committed revision 6.

myproj$

この時点で、親ブランチ(myproj)とローカルブランチ(myproj_branch1)のリビジョンの変遷は以下です。

親ブランチ(myproj)          開始→[1]→[2]→[3]ーーー→merge→[6]
                                              ↓      ↑
ローカルブランチ(myproj_branch1)           brance→[4]→[5]

この時点で親ブランチのログを見ると

myproj$ bzr log --line
6: Bazaar Taro 2010-12-28 夕食ファイルを追加
5: Bazaar Taro 2010-12-27 朝食のおかずを追加
4: Bazaar Taro 2010-12-27 朝食のメニューは和食としました
3: Bazaar Taro 2010-12-22 {Release-1.0} 挨拶文に追記
2: Bazaar Taro 2010-12-21 挨拶追加
1: Bazaar Taro 2010-12-21 最初のコミット

となっています。

ローカルブランチでの修正とコミット

ローカルブランチで、別な修正を行います。

myproj_branch1$ vi noon/lance.txt
   :
myproj_branch1$ bzr commit -m "昼食を追記"
Committing to: C:/Users/taro/Documents/myproj_brance1/
modified noon/lanch.txt
Committed revision 6.

myproj_branch1$ 

この時点で、親ブランチ(myproj)とローカルブランチ(myproj_branch1)のリビジョンの変遷は以下です。

親ブランチ(myproj)          開始→[1]→[2]→[3]ーーー→merge→[6]
                                              ↓      ↑
ローカルブランチ(myproj_branch1)           brance→[4]→[5]→[6]

この時点でローカルブランチのログを見ると

myproj_branch1$ bzr log --line
6: Bazaar Taro 2010-12-28 昼食を追記
5: Bazaar Taro 2010-12-27 朝食のおかずを追加
4: Bazaar Taro 2010-12-27 朝食のメニューは和食としました
3: Bazaar Taro 2010-12-22 {Release-1.0} 挨拶文に追記
2: Bazaar Taro 2010-12-21 挨拶追加
1: Bazaar Taro 2010-12-21 最初のコミット

となっています。

ここで、親ブランチとローカルブランチには、それぞれ別の修正がリビジョン6として反映されています。

ローカルブランチに、親ブランチの修正を取り込み

親ブランチの修正をbzr mergeコマンドを実行して取り込みます。

myproj_branch1$ bzr merge
Merging from remembered parent location C:/Users/taro/Documents/myproj/
+N  evening/dinner.txt
All changes applied successfully.

myproj_branch1$ bzr status
added:
  evening/dinner.txt
pending merge tips: (use -v to see all merge revisions)
  Bazaar Taro 2010-12-27 夕食ファイルを追加

myproj_branch1$

ローカルブランチに親ブランチから取り込んだ修正をコミットします。

myproj_branch1$ bzr commit -m "親ブランチの最新を取り込み"
Committing to: C:/Users/taro/Documents/myproj_brance1/
added evening/dinner.txt
Committed revision 7.

この時点で、親ブランチ(myproj)とローカルブランチ(myproj_branch1)のリビジョンの変遷は以下です。

親ブランチ(myproj)          開始→[1]→[2]→[3]ーーー→mergeーー→[6]
                                              ↓      ↑        ↓ 
ローカルブランチ(myproj_branch1)           brance→[4]→[5]→[6]→merge[7]

この時点でローカルブランチのログを見ると

myproj_branch1$ bzr log --line
7: Bazaar Taro 2010-12-28 [merge] 親ブランチの最新を取り込み
6: Bazaar Taro 2010-12-28 昼食を追記
5: Bazaar Taro 2010-12-27 朝食のおかずを追加
4: Bazaar Taro 2010-12-27 朝食のメニューは和食としました
3: Bazaar Taro 2010-12-22 {Release-1.0} 挨拶文に追記
2: Bazaar Taro 2010-12-21 挨拶追加
1: Bazaar Taro 2010-12-21 最初のコミット

マージしてきた場合、オプション--include-mergesを指定すると、マージで取り込んだ修正の中に含まれる履歴情報も表示されます。

myproj_branch1$ bzr log --line --include-merges
7: Bazaar Taro 2010-12-28 [merge] 親ブランチの最新を取り込み
  5.1.1: Bazaar Taro 2010-12-27 夕食ファイルを追加
6: Bazaar Taro 2010-12-28 昼食を追記
5: Bazaar Taro 2010-12-27 朝食のおかずを追加
4: Bazaar Taro 2010-12-27 朝食のメニューは和食としました
3: Bazaar Taro 2010-12-22 {Release-1.0} 挨拶文に追記
2: Bazaar Taro 2010-12-21 挨拶追加
1: Bazaar Taro 2010-12-21 最初のコミット

これによると、親ブランチでの修正(レビジョン6)は、5.1.1として記録されています。

ローカルブランチに取り込んだ親ブランチの修正をマージし、親ブランチへ反映

ローカルブランチから親ブランチへ push した場合の例です。

myproj_branch1$ bzr push
All changes applied successfully.
Pushed up to revision 7.
Using saved push location: C:/Users/taro/Documents/myproj/

親ブランチでは、

myproj$ bzr log --line --include-merges
7: Bazaar Taro 2010-12-28 [merge] 親ブランチの最新を取り込み
  5.1.1: Bazaar Taro 2010-12-27 夕食ファイルを追加
6: Bazaar Taro 2010-12-28 昼食を追記
5: Bazaar Taro 2010-12-27 朝食のおかずを追加
4: Bazaar Taro 2010-12-27 朝食のメニューは和食としました
3: Bazaar Taro 2010-12-22 {Release-1.0} 挨拶文に追記
2: Bazaar Taro 2010-12-21 挨拶追加
1: Bazaar Taro 2010-12-21 最初のコミット

とマージによりレビジョンの経緯がpush元のローカルブランチと一致するようになりました。

親ブランチの過去のリビジョンから分岐する

親ブランチの、過去のある時点から別な変更をしたいことがあります。別なやり方を試すといった用途です。

親ブランチ(myproj)のrevno:4 を指定してブランチする場合の例です。

~$ bzr branch -r revno:4 myproj myproj_planb
Branched 4 revision(s).

~$

個人で特定のディレクトリ/ファイルをバージョン管理するが、作業マシンが複数あって(例:会社、モバイル、自宅)、それぞれで作業した内容を共有したい

違うマシンで一つの作業をする場合、端的にはディレクトリ丸ごとコピーし、そこで作業し、またディレクトリを丸ごとコピーして、という形があります。作業マシンを変えるときに必ずディレクトリをコピーして移動できれば問題ないのですが、往々にして、コピーしてないけど作業してしまう、ということがあります。そうなると、コピー方式は破たんです。あっちのマシンでいじったところ、こっちのマシンでいじったところを手作業でマージする羽目に陥ります。

先に紹介した「個人で特定のディレクトリ/ファイルをバージョン管理するが、試行錯誤や状況によってディレクトリを複数作って作業する」との違いは、同一PC上でのディレクトリ間での差分情報の授受ではなく、PCをまたがったディレクトリ間での差分情報の授受となる点です。

ブランチの作成

作業するPCとは別のマシン上にあるリポジトリをブランチします。PCをまたがるので、ブランチにあたってはネットワーク通信が発生します。bazaarの公式ドキュメントには、通信プロトコルとして以下を使用できるとあります。

file://
bzr+ssh://
sftp://
bzr://
ftp://
http://
https://

個人レベルでの使用において、Linuxマシンでは標準でSSHが構築されていることが多いので、sftp://を使うのがお手軽です。一方Windowsは標準ではSSHを持たないので、bzr://がお手軽です。

Windowsマシン上に作成したbzrリポジトリのブランチをbzr://で作成する

WindowsではSSHが標準ではないので、bzrサーバーを動かしてリモートからのアクセスを受け付けます。

まず、ブランチ元となるWindows PC上で、bzrサーバーを実行します。リポジトリは、C:\Users\torutk\Documents\myproj にある場合、リポジトリの基点となるディレクトリを指定します。相対パスで指定しても動作していました。

C:\Users\torutk\Documents> bzr serve --directory . --port 0.0.0.0:4155
listening on port: 4155

なお、IPv6が有効なマシンでは、デフォルトではIPv6で待ち受けしてしまうので、IPv4で通信したい場合は明示的にIPv4で0.0.0.0およびポート番号を指定します。なお、4155はbzrサーバーのデフォルトのポート番号です。

次は、ブランチを作成したいPC(WindowsでもLinuxでも)において、bzr:// を指定してブランチを作成します。

$ branch bzr://winhost/myproj
Branched 3 revision(s).
$

別なバージョン管理システムとの相互運用

Subversionとの連携

bzr-svnプラグインを使用すると、Subversionリポジトリからブランチを生成し、修正をpushすることができます。

SubversionリポジトリからBazaarのリポジトリをブランチする

$ bzr branch svn+http://repo.example.com/svn/proje/trunk

SubversionリポジトリURLの先頭にsvn+と付与すると、Subversionリポジトリにアクセスすることができます。