ソフトウェア開発では一般的に、変更を特定のバグ ID や課題 ID に関連づけます。バグ追跡ツール(課題追跡システム)を使用している場合、課題追跡システムの特定の ID と Subversion で行った変更を関連付けできると便利です。そのため、多くの課題追跡システムでは、コミットに関連するバグ ID を探すために、ログメッセージを解釈する、pre-commit フックスクリプトを提供しています。しかし、ログメッセージを書くときに、pre-commit フックスクリプトから正しく解釈できるよう書けるかどうかはユーザー次第であるため、この方法はときどき失敗するという傾向があります。
TortoiseSVN は、以下の 2 種類の方法でユーザーの補助を行います。
ユーザーがログメッセージを入力すると、定義された書式に従ってコミットに関連付けられた課題番号を含む行が自動で追加されます。これによって、バグ追跡ツールが正しく解釈できない書式で、ユーザーが課題番号を入力してしまう危険を減らせます。
また、TortoiseSVN は入力したログメッセージの中で、課題追跡システムが認識した部分を強調表示できます。これにより、ログメッセージが正しく解釈されたか、ユーザーが知ることができます。
ユーザーがログメッセージを閲覧する際に、TortoiseSVN は、ログメッセージ内の各バグ ID に、課題に言及したページをブラウザーで開くリンクを張ります。
TortoiseSVN はいくつかのバグ追跡ツールと統合できます。このとき bugtraq: で始まるプロパティを使用します。以下のようにフォルダーに設定しなければなりません。 (「プロジェクト設定」)
課題追跡システムのプロパティを編集する場合、適切な値を簡単に設定するために、専用のプロパティエディターを使用することができます。
TortoiseSVN と課題追跡システムを統合するには、2 つ方法があります。ひとつは単純な文字列によるもの、もうひとつは 正規表現 によるものです。プロパティにはどちらの方法も使用できます。
バグ追跡ツールのURLを設定します。適切にURIエンコードし、中に %BUGID% を含んでいなければなりません。 %BUGID%は入力した課題番号に置き換えられます。これによって TortoiseSVN のログダイアログ上にリンクを表示し、リビジョンログを参照する際に、バグ追跡ツールに直接ジャンプできるようになります。このプロパティがないと、 TortoiseSVN は課題番号を表示するだけで、リンクを表示しません。例えば、 TortoiseSVN の開発プロジェクトでは、 http://issues.tortoisesvn.net/?do=details&id=%BUGID% と設定しています。
絶対 URL の代わりに相対 URL も使用できます。これは、課題追跡システムが、自分のソースリポジトリと同じドメイン・サーバーにある場合に便利です。ドメイン名を変更したとしても、bugtraq:url プロパティを調整する必要はありません。相対 URL を指定するには以下の 2 つの方法があります。
^/ で始まる場合は、リポジトリルートからの相対 URL であると見なします。例えば、リポジトリが http://tortoisesvn.net/svn/trunk/ にある場合、^/../?do=details&id=%BUGID% を、http://tortoisesvn.net/?do=details&id=%BUGID% と解釈します。
/ で始まる URL は、サーバーのホスト名からの相対 URL であると見なします。例えば、リポジトリが http://tortoisesvn.net のどこかにある場合、/?do=details&id=%BUGID% を、http://tortoisesvn.net/?do=details&id=%BUGID% と解釈します。
課題番号テキストフィールドが空の場合、TortoiseSVN が警告を発するようにしたければ、true に設定してください。有効な値は true/false です。 定義されていなければ、false として扱います。
シンプルアプローチでは、TortoiseSVN はユーザーに、バグ ID を入力できる独立した入力フィールドを表示します。すると、ユーザーが入力したログメッセージに独立した行が追加されます。
入力フィールドモードでバグ追跡システムを有効にします。このプロパティを設定すると、変更をコミットする際に、TortoiseSVN に課題番号を入力するよう促されます。これはログメッセージの最後に行を追加するのに使用します。中に %BUGID% を含んでいなければなりません。これはコミットの際に課題番号に置換されます。この機能を使用することで、確実にコミットログに課題番号への参照を一定の書式で含め、バグ管理ツールがこれを解釈して課題番号と特定のコミットを関連付けることができるようになります。例えば Issue : %BUGID% などと設定できますが、これは使用するツールに依存します。
このテキストは、TortoiseSVN がコミットダイアログの、課題番号を入力するエディットボックスのラベルに使用されます。設定されていないと、Bug-ID / Issue-Nr: が表示されます。このラベルにぴったり合うようにウィンドウのサイズ変更ができませんので、ラベルは 20-25 文字以下になるよう留意してください。
true に設定すると、課題番号テキストフィールドには数値しか入力できなくなります。カンマは例外ですので、カンマで区切って複数の数値を入力できます。有効な値は true/false です。 定義されていなければ、true として扱います。
バグ ID をログメッセージの最後に追加する (true) ときや、ログメッセージの先頭に挿入する (false) ときにこのプロパティを定義します。有効な値は true/false です。 既存のプロジェクトが壊れないよう、これが定義されていない場合、true として扱います。
正規表現でのアプローチでは、TortoiseSVN は独立した入力フィールドを表示しませんが、ユーザーが入力したログメッセージの中の、課題追跡システムに関係する部分をマーク付けします。ログメッセージを入力している間、有効です。これはバグ ID が、ログメッセージのどこにあってもかまわないと言うことです! この方法はとても柔軟で、TortoiseSVN プロジェクトではこれを使用しています。
このプロパティは、正規表現 モードでバグ追跡システムを有効にします。ここには改行で区切っていずれかひとつの正規表現を設定できます。
正規表現を2つ設定した場合、最初の正規表現は、含まれているバグ ID を探すための前処理フィルターとして使用します。2つ目の正規表現は、最初の正規表現の結果から、生のバグ ID を抽出します。これにより、必要に応じてバグIDの一覧や自然言語表現を使用することができます。例えば、いくつかのバグを修正し、 「This change resolves issues #23, #24 and #25」 といった文字列を入れたとします。
このログメッセージの中にある表現からバグ ID を抽出するには、[Ii]ssues?:?(\s*(,|and)?\s*#\d+)+ と (\d+)というような正規表現を使用することができます(TortoiseSVN プロジェクトでも使用しているものひとつです)。
最初の正規表現で、周囲ののログメッセージから 「issues #23, #24 and #25」 を抜き出します。ふたつ目の正規表現は、最初の正規表現の出力から、生の 10 進の数値を抽出します。つまり、バグ ID として使われている、「23」, 「24」, 「25」 が返ります。
はじめの正規表現を少しかみ砕くと、「issue」 という単語 (先頭が大文字でも可) で始まっていなければなりません。この後に 「s」 が続いてもよく (複数型)、コロンが続いてもよいです。この後には、0 以上の空白が続き、コンマか 「and」 が続いてもよく、その後また 0 以上の空白があるグループが 1 つ以上あります。最後に必ず 「#」 と 10進数の数値が来ます。
正規表現が 1 個のみの場合は、むき出しのバグ ID と正規表現文字列のグループとがマッチしなければなりません。例: [Ii]ssue(?:s)? #?(\d+)。この方法は、trac のような少数の課題追跡システムには必要ですが、その正規表現を構築するのは大変です。使用する課題追跡システムのドキュメントにある場合にのみ、この方法を使用するのをお勧めします。
正規表現になじみがなければ、http://ja.wikipedia.org/wiki/正規表現 にある導入や、http://www.regular-expressions.info/ にあるオンラインのドキュメントやチュートリアルをご覧ください。
正規表現を常に正しく書くことは困難なので、手助けのために、課題追跡システムのプロパティダイアログにテストダイアログを用意しています。エディットボックスの右側のボタンをクリックすると起動します。ここに文字列を入力し、正規表現を変更すると結果を表示させることができます。正規表現が無効であれば、エディットボックスの背景が赤くなります。
bugtraq:message と bugtraq:logregex の両方をセットしている場合、logregex を優先します。
pre-commit フックスクリプトで解釈していれば、課題追跡システムがない場合でも、ログメッセージ内の課題に言及している箇所を、リンクにするために使用できます!
またリンクが必要なくても、課題番号がログダイアログの独立した列に表示されるので、どの課題に対応する変更かがわかりやすくなります。
tsvn: プロパティのいくつかは true/false 値をとります。TortoiseSVN は yes を true と同義に、no を false と同義に解釈します。
これらのプロパティは、作業するシステムのフォルダーに設定しなければなりません。ファイルやフォルダーをコミットする際に、このフォルダーからプロパティが読み取られます。フォルダーにプロパティが設定されていない場合、プロパティはフォルダー階層を上位に向かって、バージョン管理外フォルダーか、ツリーのルート(例: C:\)に到達するまで検索されます。すべてのユーザーが、例えば trunk/ からチェックアウトし、サブフォルダーからチェックアウトしないことが確認できるのであれば、 trunk/ にそのプロパティを設定するだけで充分です。サブフォルダーからもチェックアウトする可能性があるのであれば、プロパティを各サブフォルダーに再帰的に設定するべきです。プロジェクトの深い階層で設定されたプロパティは、高いレベルの(trunk/ に近い)ものより優先します。
プロジェクトプロパティ(例:tsvn:、bugtraq:、webviewer:)に限っていえば、 プロパティを再帰的に適用する チェックボックスを使うと、そのフォルダ以下のすべてのサブフォルダーにプロパティを設定しますが、ファイルには設定しません。
TortoiseSVN で新しいサブフォルダーを作業コピーに追加する際、親フォルダーに設定されているプロジェクトプロパティは、新しいサブフォルダーにも自動的に追加されます。
バグ追跡システムとの統合は、Subversion のプロパティとして保持されているため、チェックアウトした作業コピーを使用するときのみ表示されます。リモートからプロパティを取得するのには時間がかかるため、作業コピーからリポジトリブラウザーを起動しなければ表示されません。リポジトリのURLを入力してリポジトリブラウザーを起動した場合は表示されません。
同じ理由で、プロジェクトのプロパティは、リポジトリブラウザーを使用して子フォルダーを追加しても、自動的には継承されません。
この課題追跡システムとの統合は、TortoiseSVN に限定されたものではなく、どの Subversion クライアントでも共通で使用できます。これについての詳細は、TortoiseSVN のソースリポジトリにある、Issue Tracker Integration Specificationの全文をお読みください(リポジトリへのアクセスのしかたは、 「ライセンス」で説明します)。
前節では、ログメッセージへ課題情報の追加について扱いました。しかし、課題追跡システムから情報を取得する必要がある場合、どのようにしたらよいのでしょう? コミットダイアログは、課題追跡システムと会話ができるような、外部プログラムを統合する COM インターフェイスを備えています。通常、今回のコミットで取り組む課題を取り上げられるように、自分に割り当てられた未解決の課題を取得するよう、課題追跡システムに問い合わせを行うのでしょう。
そのようなインターフェイスはいずれも、課題追跡システムに強く依存しているので、私たちはこの部分を提供することはできませんし、そのようなプログラムの作成方法について説明することは、このマニュアルの範疇を超えてしまいます。インターフェイスの定義や、C#やC++/ATLで書かれたサンプルプラグインは、TortoiseSVN リポジトリの contrib フォルダーから取得できます(リポジトリのアクセスの仕方は、 「ライセンス」で説明します)。API の概要も 6章IBugtraqProvider インターフェイス で得られます。それ以外の(動作する)サンプルプラグインとして、 C# では Gurtle があり、これは課題管理システム Google Code と連動するために必要な COM インターフェイスを実装しています。
説明のために、システム管理者が、インストールした課題管理システムプラグインを提供し、TortoiseSVN の設定ダイアログでそのプラグインを使用する作業コピーをセットアップしたとしましょう。プラグインに割り当てられた作業コピーからコミットダイアログを開くと、ダイアログの上部に新しいボタンが現れるはずです。
この例では、複数の未解決課題を選択できます。その後、プラグインがログメッセージに追加する、特定のフォーマットのテキストを生成できます。