* Subversionにおけるブランチ [#g6c33a4e]
#contents


** Subversionにおけるブランチの概念 [#z99c7e96]
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の変更を適用できます。

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


** 前提 [#hba18d51]
まず、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をコピーして作られた

という感じになります。


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

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

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


** ブランチの作り方 [#f2c7d4f1]
単純にコピーを行うだけです。基本はフォルダ単位で行います。

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

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

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

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

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


** ブランチの使い方 [#o196fd84]
ブランチの使い方は二通りあります。

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

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

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

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

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

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


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

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

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


*** マージの原理 [#y8836596]
まず、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のどっちかの行を組み合わせてマージできない場合は、手作業でマージする必要が出てきます。もちろん、それ以外の場所は極力自動でマージされます。


*** 操作方法 [#s2184d89]
コマンドラインの場合は、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に反映させる [#oe371026]
基本は前述のマージ手順と同じで、対象が逆転しただけです。つまり、今までの説明だと、trunkの変更 =>> branch-x、だったのが、branch-xの変更 =>> trunk、になっただけです。

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

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

ということです。


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

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

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


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS