無為空間
むいむい(´ω`*)
Entries
# Subversionのpost-commitフック REPOS="$1" REV="$2" SVNLOOK=/usr/bin/svnlook CHANGED_DIRS=`$SVNLOOK dirs-changed -r $REV $REPOS` # trunkにコミットされたらHudosnにビルド要求を出す if echo $CHANGED_DIRS | grep "^trunk" > /dev/null then wget -q -O /dev/null "http://localhost:8080/job/test/build" fi
上記はSubversionのフックスクリプトだが、これをBazaarでやりたい。
リポジトリごとにフック置き場が用意されているSubversionとは違い、Bazaarのフックはプラグインの一種として「システム全体のプラグイン置き場」か「個人のプラグイン置き場」に置かなければならない。
それはつまりフックの中で「pushされたブランチの絶対パスを特定しなければならない」ということなので、まずは下記の様なフックを用い、ブランチの位置についてどのような情報を得られるのかを確認しておくことにする。
from bzrlib import branch def print_branch(param): import os os.system('echo "%s" >> /var/tmp/branch.txt' % param.branch); branch.Branch.hooks.install_named_hook('post_change_branch_tip', print_branch, 'print branch')
なお、このフックのトリガは「push」ではなく「tipの変更」である。よってcommitやuncommitでも動作する。
どちらかというとこちらの方が元々の用途にはあっているし、そもそもpushはクライアント側でしかフックできないため、pushされる側に置くことができない。
実行環境:
- MacOS X 10.6.5
- Python 2.6.1
- Bazaar 2.2.0
$ mkdir -p /var/tmp/bzr/local $ cd /var/tmp/bzr/local $ bzr init
まずはこうしてブランチを作って……
$ bzr commit --unchanged
BzrBranch7(file:///private/var/tmp/bzr/local/)
パスを省略したcommitの場合、パスはrealpathになる。
$ bzr commit --unchanged /var/tmp/bzr/local
BzrBranch7(file:///var/tmp/bzr/local/)
絶対パスを指定したcommitの場合、パスは指定した絶対パスになる。
$ bzr push bzr+ssh://idlysphere@localhost/var/tmp/bzr/remote
BzrBranch7(filtered-4319272656:///var/tmp/bzr/remote/) RemoteBranch(bzr+ssh://idlysphere@localhost/var/tmp/bzr/remote/)
bzr+sshの場合、サーバ側のフック(前者)はプロトコル部がフィルタされた絶対パスになる。
以上のことから考えると、たとえば /var/bzr/central のブランチを監視したい場合は
from bzrlib import branch def auto_build(param): import os from urlparse import urlparse if os.path.samefile(urlparse(param.branch.base).path, '/var/bzr/central'): import urllib urllib.urlopen('http://localhost:8080/job/test/build') branch.Branch.hooks.install_named_hook('post_change_branch_tip', auto_build, 'auto build')
こんな風に書いておけば良さそう?
- bzr 2.0.4
- bzr-rebase 0.5.4
- bzr-svn 1.0.0
で確認。
rebaseが使えると、Subversionで
$ svn checkout http://example.com/svn/tags/version1 # 安定版を落としてくる ……いろいろ編集する…… ……いろいろ編集する……(ローカルの版管理どうしよう……(~_~;)) $ svn switch http://example.com/svn/tags/version2 # 安定版が新しくリリースされたのでチェックアウトをそちらにswitchする
とかやっていたところを
$ bzr branch http://example.com/svn/tags/version1 # 安定版からローカルブランチを作成 ……いろいろ編集する…… $ bzr commit # 編集をローカルブランチにコミットする ……いろいろ編集する…… $ bzr commit # 編集をローカルブランチにコミットする $ bzr rebase http://example.com/svn/tags/version2 # 安定版が新しくリリースされたのでローカルブランチをそちらにrebaseする
こうできるので非常にありがたい。
bzr reconfigure directory
bzrディレクトリを任意のブランチ/ツリー/チェックアウト/リポジトリに再構成する。
bzr bind
や bzr unbind
、 bzr checkout .
はこれの機能限定簡略版。
これを使うと前回挙げたほとんどの構成を行き来できる。
また、(2.0.0時点では)再構成でしか作れないスタックチェックアウト(stacked checkout)なんてものもある。
$ ls -a # スタンドアロンツリー「hoge」が存在する . .. hoge $ bzr init-repo . # カレントディレクトリを共用リポジトリに Shared repository with trees (format: 2a) Location: shared repository: . $ bzr info hoge # hogeは「スタンドアロンツリー」である Standalone tree (format: 2a) Location: branch root: hoge $ ls hoge/.bzr # スタンドアロンツリーの.bzrの中身 branch branch-lock checkout readme repository branch-format $ bzr reconfigure --use-shared hoge # 共用リポジトリを使うようhogeを再構成 $ bzr info hoge # hogeは「リポジトリツリー」になった Repository tree (format: 2a) Location: shared repository: . repository branch: hoge $ ls hoge/.bzr # hoge/.bzr/repositoryがなくなった branch branch-format branch-lock checkout readme $ touch hoge/hoge.txt # hogeの作業ツリーにhoge.txtを追加 $ bzr status hoge # 作業ツリーに未管理のファイルがある unknown: hoge.txt $ bzr reconfigure --branch hoge # 作業ツリーを持たないようhogeを再構成 $ bzr info hoge # hogeは「リポジトリブランチ」になった Repository branch (format: 2a) Location: shared repository: . repository branch: hoge $ ls hoge/.bzr # hoge/.bzr/checkoutがなくなった branch branch-format branch-lock readme $ bzr status hoge # 作業ツリーがないのでstatusコマンドはエラーとなる bzr: ERROR: No WorkingTree exists for "hoge/.bzr/checkout/".
普段Subversionばかり使っている自分がBazaar 2.0.0のリポジトリやらブランチやらツリーやらチェックアウトやらの関係を理解するためのまとめ。
随時更新。
bzr init-repo repos
reposディレクトリに.bzr管理ディレクトリ(control directory)を作成し、reposディレクトリ以下を共用リポジトリ(shared repository)にする。
共用リポジトリの.bzrにはrepositoryディレクトリが作成され、共用リポジトリに作られたブランチのリビジョンはそこに格納される。
bzr init-repo --no-trees repos
作業ツリー(working tree)を持たない共用リポジトリを作成する。
作業ツリーとは、.bzr以外の、ユーザが直接編集するいわゆる作業コピーのことを指す。
この共用リポジトリに作られるブランチにはデフォルトで--no-tree
オプションが付く。
主に集中型リポジトリを作成する際に使う。
bzr init trunk
trunkディレクトリに.bzrディレクトリを作成し、trunkディレクトリをブランチ(branch)にする。
ブランチは作成される場所によって呼び名とリビジョンの格納先が変わる。
共用リポジトリに作られたブランチはリポジトリブランチ(repository branch)となる。
リポジトリブランチの.bzrにはrepositoryディレクトリは作成されず、リビジョンは共用リポジトリの.bzr/repositoryディレクトリに格納される。
共用リポジトリ以外の場所に作られたブランチはスタンドアロンブランチ(standalone branch)となる。
スタンドアロンブランチの.bzrにはrepositoryディレクトリが作成され、リビジョンはそこに格納される。
ブランチはまた作業ツリーの有無でも呼び名が変わる。
ブランチが作業ツリーを持つことを明確にしたい場合、「ブランチ」ではなく「ツリー」と呼ぶ。
すなわち「作業ツリーを持つスタンドアロンブランチ」はスタンドアロンツリー(standalone tree)であり、「作業ツリーを持つリポジトリブランチ」はリポジトリツリー(repository tree)である。
bzr branch parent_branch my_branch
parent_branchブランチのコピーとしてmy_branchブランチを作成する。
他の分散型SCMで言うところのclone。
bzrのclone
コマンドは、2.0.0現在branch
コマンドの単なるエイリアスとなっている。
このコマンドで作られるブランチもinitコマンドで作られるもの同様、共用リポジトリに作られればリポジトリブランチに、それ以外の場所に作られればスタンドアロンブランチになる。
my_branchがparent_branchと同じ共用リポジトリに作られた場合、両ブランチ間で共用可能なリビジョンは共用されるため、Subversionでブランチを切るのと同程度のコスト感覚でブランチを作成できる。
bzr branch --stacked parent_branch stacked_branch
parent_branchブランチの上に「積み重ねるリビジョンのみを格納」するスタックブランチ(stacked branch)を作成する。
その役割上、スタックブランチは必ず独自のリポジトリを持つ。
共用リポジトリに作ってもリポジトリブランチにはならず、スタックブランチ独自のリポジトリにparent_branchブランチのリビジョンがコピーされることもない。
そのため、parent_branchブランチにアクセスできない状況では、stacked_branchブランチではコミットはおろかdiffを取ることもできない。
これは「diffやrevert程度はリポジトリにアクセスしなくても行える」Subversionの作業コピーよりも厳しい制約である。
その上、Bazaar 2.0.0ではこのブランチにコミットしようとすると
bzr: ERROR: Cannot commit from a lightweight checkout to a stacked branch. See https://bugs.launchpad.net/bzr/+bug/375013 for details.
という実態に即さないエラーメッセージが出てコミットできない。
bzr branch --no-tree parent_branch no_tree_branch
parent_branchブランチのコピーとして、作業ツリーを持たないno_tree_branchブランチを作成する。
bzr checkout trunk working
workingにtrunkブランチのチェックアウト(checkout)を作成する。
チェックアウトは「コミットしたリビジョンが即座にブランチに伝搬される」という点でSubversionの作業コピーのようなものと言える。
ただしSubversionとは違い「ブランチの一部をチェックアウト」したり「チェックアウトした一部分のみを bzr update
」することはできない。
チェックアウトはスタンドアロンブランチと同じように「全てのリビジョンをコピーする」ため、過去のリビジョンを参照する際にもブランチへのアクセスを必要としない。
それどころか bzr unbind
でチェックアウトをブランチに、 bzr bind
でブランチをチェックアウトにすることもできる。
ゆえにチェックアウトは束縛されたブランチ(bound branch)とも呼ばれている(と、思う)。
bzr checkout --lightweight trunk working
workingにtrunkブランチの軽量チェックアウト(lightweight checkout)を作成する。
軽量チェックアウトは通常のチェックアウト(heavyweight checkout――lightweightとの対比から)にスタックブランチの特性(リビジョンをコピーしない)を合わせたようなもので、より一層Subversionの作業コピーに近い。
が、やはりこれもスタックブランチ同様、ブランチにアクセスできないとコミットすることもdiffを取ることもできない。
通常のチェックアウトは bzr unbind
や bzr commit --local
でブランチから一時的に切り離してチェックアウト自身にリビジョンを作成できるが、軽量チェックアウトではそれも不可能。
bzr checkout branch
checkoutコマンドは引数が1つ以下の場合、指定したブランチに作業ツリーを生成する。
つまり「ブランチをツリーにする」。
bzr update working_tree
作業ツリーの内容をブランチの最新に合わせて更新する。
参考: