* 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をコピーして作られた
  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にする必要があるが)を指定すれば、ブランチの作成が可能です。
 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と同じ原理です。もし行単位でマージが出来ない場合は、手作業でのマージとなります。
 自動マージは行単位で行われます。いわゆる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へのマージです)参考にしてください。
 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