Subversionにおけるブランチ

Subversionにおけるブランチの概念

Subversionにおけるブランチの概念は、単なるフォルダやファイルのコピーです。

例えば、trunkフォルダで作業中に、試験的にXという機能を実装する必要が出たとします。Xは、実際に使われるかどうかまだわかりません。

もしtrunkフォルダ上のファイルにXに関する変更を加えると、Xが正しく動くまでテストなどが出来ない状態になり、Xはいらないよ、ということになった時に、元に戻すのが大変です。

そこで、branch-xという名前でtrunkフォルダのコピーをつくり、そこで作業すれば、trunkフォルダの中身に影響を与えずに済みます。

trunkはtrunkで改良などが続き、branch-xではXの機能実装が行われる訳です。その間、trunkとbranch-xは、互いに影響を与えることはありません。

Xの機能はいらないとわかったら、branch-xフォルダを削除すれば良いですし、まぁ後々役に立つかもしれないと思うなら、残しておいても良いでしょう。trunkには影響を与えないので、残しておいても害はありません。

もしXの機能が必要なのでtrunkに組み込む、ということになれば、brach-xを、trunkに「マージ」することで、trunkにbranch-xの変更を適用できます。

これで、面倒な依存影響に煩わされることなく、開発を行うことが出来ます。

前提

まず、trunkのみで、リビジョン120まで開発したとします。

そこで、機能Xの実装を試みるために、trunkをbranch-xという名前でコピーします。ここで、リビジョンは121になります。branch-xは、リビジョン121で作成されます。

そして、trunkとbranch-xの両方の更新が行われ、レポジトリのリビジョンは150まで上がったとします。そこで、機能Xをtrunkに取り込むことにします。

ちなみに、レポジトリ構造としては、

http://server/svn/project1/ - レポジトリのルートフォルダ
http://server/svn/project1/trunk - 主開発フォルダ
http://server/svn/project1/tags - タグ用のフォルダ
http://server/svn/project1/branches - ブランチ用フォルダ
http://server/svn/project1/branches/branch-x - Xの機能をためしに実装してみるフォルダで、
                                               リビジョン120のhttp://server/svn/project1/trunkをコピーして作られた

という感じになります。

操作の流れ

最初に、操作の流れだけ書いておきます。まとめや結論を先に、です。

  1. ブランチを作る(trunkを、branch-xとしてコピーする)
  2. trunkとbranch-xでそれぞれ開発を行い、必要に応じてtrunkの修正をbranch-xに取り込む(マージする)
  3. trunkにXの機能追加を適用するために、branch-xの修正をtrunkに取り込む(マージする)

2.のマージ作業をこまめにやっておくと、3.のマージ作業が楽になります。

ブランチの作り方

単純にコピーを行うだけです。基本はフォルダ単位で行います。

コマンドラインなら、svn copyコマンドを使って、trunkフォルダをbranch-xというフォルダでコピーしてください。

TortoiseSVNであれば、http://tortoisesvn.bluegate.org/Help/dailyuseguide.html#Copy辺りを参考にしてください。このページで、to URLにbranch-xという名前(正確には、フルURLにする必要があるが)を指定すれば、ブランチの作成が可能です。

Subclipseなら、プロジェクトリストのフォルダを右クリックして、Teamの所からブランチを作成できます。

ブランチは、レポジトリ内のコピーなので、作った直後は(ローカル側では)何も起きません。

なお、レポジトリ内では、リンクによりコピーが行われるので、巨大なファイルだろうが何だろうが気にする必要はありません。

ブランチの使い方

ブランチの使い方は二通りあります。

一つは、レポジトリ切り替えを行って、trunkの編集をやめてbranch-xの編集を始める方法です。

もう一つは、branch-xを新しくチェックアウトする方法です。

ここでは、後者をお奨めするので、その方法についてです。

trunkをチェックアウトした時と同じように、branch-xを指定してチェックアウトしてください。

操作はそれだけです。ローカル作業領域には、trunkとbranch-xの二つができることになります。

これで、同時に、もともとのtrunkの開発も行えて、branch-xでXの機能追加も行えます。

trunkの修正をbranch-xに反映させる

trunkで重要なバグ修正等があると、branch-xも更新する必要が出てきます。そうしないと、バグのあるままXの機能実装をすることになりますから。

そこで、trunkの修正をbranch-xに反映させる必要が出てきます。

マージ作業の原理は、次のようになります。

マージの原理

まず、trunkのリビジョンを二つ指定します。その二つのリビジョンの期間にtrunkに行われた変更点を、branch-xのローカルコピーに適用します。

リビジョンを含めて説明すると、リビジョン120からリビジョン150までの間に、trunkに行われた変更を、branch-xに適用すれば、branch-xの元となったtrunkは見かけ上、リビジョン120のものからリビジョン150のものになります。これがマージです。

自動マージは行単位で行われます。いわゆるdiffと同じ原理です。もし行単位でマージが出来ない場合は、手作業でのマージとなります。

自動マージできる例としては、次のようなものがあります。

trunk@120
if(a > b) {
  x++;
}
trunk@150
if(a > b) {
  y--;
  x++;
}
branch-x@150
if(a > b) {
  x++;
  z = 0;
}
branch-x@マージ結果
if(a > b) { //この行は両方一致
  y--; //trunk@150からもってきて追加した
  x++; //この行は両方一致
  z = 0; //branch-xからもってきて追加した
} //この行は両方一致

自動マージできない例としては、次のようなものがあります。

trunk@120
if(a > b) {
  x++;
}
trunk@150
if((a > b) && (c < 0)) {
  y--;
  x++;
 }
branch-x@150
if((a > b) && (c < b)) {
  x++;
  z = 0;
}
branch-x@マージ結果
if((a > b) && (c < 0) && (c < b)) { //手作業でマージする必要がある
  y--; //trunk@150からもってきて追加した
  x++; //この行は両方一致
  z = 0; //branch-xからもってきて追加した
} //この行は両方一致

このように、trunkかbranch-xのどっちかの行を組み合わせてマージできない場合は、手作業でマージする必要が出てきます。もちろん、それ以外の場所は極力自動でマージされます。

操作方法

コマンドラインの場合は、svn mergeコマンドを使ってください。

svn merge -r [旧リビジョン]:[新リビジョン] [trunk(URL)] [branch-x(パス)]

です。変更元のtrunkの指定はレポジトリのURLであるのに対し、適用先のbranch-xの指定はローカル作業域へのパスであることに注意してください。

TortoisSVNなら、branch-xフォルダに対して、マージを実行してください。http://tortoisesvn.bluegate.org/Help/dailyuseguide.html#Mergeに、trunkへのマージの仕方がありますので、違いに気をつけながら(今は、branch-xへのマージです)参考にしてください。

Subclipseなら、プロジェクトリストのbranch-xフォルダを右クリックして、Teamからマージを選び、マージ元にtrunkのURLを指定して、リビジョン番号を指定しましょう。

この作業により、ローカルにあるbranch-xの作業領域が更新されます。branch-xをコミットすれば、レポジトリにも反映されます。

branch-xの機能をtrunkに反映させる

基本は前述のマージ手順と同じで、対象が逆転しただけです。つまり、今までの説明だと、trunkの変更 =>> branch-x、だったのが、branch-xの変更 =>> trunk、になっただけです。

注意すべき点だけを書いておきます。

  • マージの適用先は、ローカルにあるtrunk
  • マージの適用元は、レポジトリにあるbranch-x
  • マージの開始リビジョンは、branch-xをコピーした時(ブランチを作った時=リビジョン121)
  • マージの終了リビジョンは、branch-xを最後に更新したりビジョン(HEADリビジョンでも別に構わない)

ということです。

終わりに

trunkとbranch-xをそれぞれチェックアウトしたのは、両方の作業を簡単に進められるというだけではなく、trunkの変更を簡単に知ることが出来るように、という意味もあります。

trunkが変更されたことがわかったら、コミットコメントを見て、必要な部分をbranch-xに適用しましょう。バグのあるままbranch-xの開発をしても苦労するだけでしょう。多分。

こまめにマージしてtrunkの変更を取り込んでおけば、最後にtrunkにマージする時に一度にマージ作業をやる手間が省けます。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2006-11-02 (木) 15:27:30 (4786d)