以前、ブランチ戦略について自分が纏めた記事を書きました(当記事の最後にリンクあります)。 ただ、Gitについて書いたはずなのに「SVNブランチ戦略」で検索される方が一定数いらっしゃいます。ここ2年くらいSVNについてはもう触っていませんが、自分の知識を深めるためにSVNを改めて勉強しようと思い、この記事を書きました。
なお、社内でSVN使っているところもあるらしいです。私もまだまだ使う可能性はありますから、学ぶメリットはあるはずです。
この記事のターゲット
非ターゲット
SVNとは
「Subversion」でSVN。集中管理方式のバージョン管理システムです。バージョン管理システムは、ファイルに対して更新履歴を記録することで、過去のある時点の状態を復元したり変更内容の差分を表示できるようにするシステムです。チームでの開発で最も力を発揮しますが、個人で使用しても数カ月前のことは覚えていなかったりするので、論文や原稿等でも使えます。
なお、正確な捉え方ではないでしょうが、操作履歴を保持する巨大な共有フォルダのイメージで良さそうです。
- ディレクトリの移動や削除をサポートしている。このため、ファイル名やソースツリーの構造がはっきりと決まらないうちからバージョン管理をできる。
- バージョン番号(リビジョン番号)はソースツリー全体に対して振られるため、原則としては誰かがソースツリーのどこかのファイルを更新する度に番号が増えてゆく(CVSではファイル毎にリビジョン番号がつけられている)。
- 作業ディレクトリ内に、最後にソースリポジトリと同期をとったときのファイルのコピーを持っているため、改編中のファイルの変更部の確認などがソースリポジトリにアクセスする事無く高速に実行できる。また、ファイルの差分送信が効率よく行なわれるため、プアなネットワーク環境で利用したときに快適である。
- SSHによるソースリポジトリとの通信を標準でサポートしている。インターネット経由で利用してもセキュリティを容易に保つ事ができる。
- WebDAVをバックエンドとして使うことができる。つまり、Apache HTTP ServerなどのWebDAVをサポートするHTTPサーバを経由して、WebDAVプロトコルを用いてSubversionサーバとSubversionクライアントが通信するという形態が使える。
集中管理型と分散管理型
集中管理型は、非常にわかりやすいことがメリットです。開発中のブランチはtrunkディレクトリであることが一般的な慣習です。なので、開発中のブランチ戦略を考えることはありません。常に開発ブランチが明白なので、リファクタリングしてもチームへの影響を最小限にできます。また、一部のソースをロック(チェックアウト)して、他の人に修正させないようにできます。開発中も誰が修正しているかが一目瞭然です。
しかし、デメリットもあります。
集中管理型は分散管理型と違い、リポジトリの存在を1つしか許容しません。それは、リモートとローカルでの差分を許容しないということです。Gitは分散型なのでcloneした段階で、origin/masterとmasterの2つのリポジトリを作成します。SVNはあくまで、リモートリポジトリを参照しているので、1つのリポジトリのままです。
集中管理型では、ローカルで小さくコミットして最後にまとめてプッシュはできません。コミット=プッシュとなります。うっかりコミットすると全員の環境が壊れてしまいます。
また、Gitであれば動かなくなった段階で別ブランチにしてプッシュし、他の人に相談を持ち掛けることもできます。SVNでは環境壊すのを覚悟でプッシュするか、コミット前のローカルの環境を元に相談しに行くしかありません。
あと、別のリポジトリの存在を許容しないという観点から、PullRequestのような別リポジトリ(第三者)からの意見を反映する、ということは思想上難しそうです。OSSが集中管理方式をとることは無いでしょうね。
なお、私はGitでもmasterのみ開発(トランクベース開発)が最高だと信じています。ブランチを切ることは、マージコストを高めてしまいます。リポジトリの存在を1つしか許容しないので、強制的にトランクベース開発を取ることになります。
SVNで使われるクライアントツール
Eclipse等のIDEに含まれていますが、IDE上でうまく操作できず、私は下記リンクのTortoiseSVNを使用してました。読み方は「トータス・エスブイエヌ」です。社会人1年目で読み方が分からなかったので、「カメさんツール」でごり押して表現していました。
俺のブランチ戦略
SIer時代にSVNで開発をしていた時の経験則と、Git開発に慣れた経験則を合わせて考えました。SVNのベストプラクティスはわかりません。
SVNの一般的なリポジトリ構成としては、下記の構成になります。
SVNを構築した段階では下記の構成はなく、まっさらな状態なので自分でディレクトリを作成する必要があります。
- project/trunk/subdir/...
- project/branches/branch/subdir/...
- project/tags/tag/subdir/...
※ 上記のsubdirがGitのbranchの作業ディレクトリと同等と考えていいでしょう。 SVNは全部の作業ディレクトリが同時に存在するので、巨大な共有フォルダという捉え方をしました。
trunk
開発に使用するリポジトリ。開発の中でもメジャーアップデートのために使用していました。一部だけ先行機能追加したい場合は、branchesを使っていました。
- trunk(開発環境/検証環境)
trunkをGitで表現するなら
master, mainブランチと表現されることもあるけれど、個人的にはdevelopブランチが一番しっくり来ます。もちろん、Gitのブランチ戦略によるのでブランチの捉え方は異なりますが、ブランチが切りづらい=masterブランチと捉えるのは違和感がありました。
branches
trunkからコピーした後、修正OKなリポジトリ。本番環境で適応しているソースコード、マイナーアップデート等で使用していました。
なお、SVNはマージのコストが非常に重いです。なので、障害修正も直接branchesにコミットして、その後trunkにマージしていました。同様にマージのコストの関係で、検証環境等はtrunkからデプロイしていました。
- branches/prd(本番環境)
- branches/feature(先行リリース機能開発)
等々。
branchesをGitで表現するなら
Gitでいうとリリースブランチ、featureブランチです。hotfixブランチはマージコストが重いのでわざわざ作りません。
tags
trunkからコピーした後、修正NGなリポジトリ。リリースタイミングでどんなソースコードだったかを残すときに使用する(スナップショットを残す)
- tags/1.0(本番バージョン1.0)
- tags/2.0(本番バージョン2.0)
tagsをGitで表現するなら
Gitと同じ感覚で問題ありません。ただし、Gitのtagはコミットハッシュなので非常に軽いですが、ディレクトリごとコピーなのでやればやるほど重くなります。
SVNのブランチ戦略を図で表現する
線が飛び交っていてわかりづらいですが、このような運用を想定しています。
ちなみに、Git-flowだともっとごちゃごちゃします。
時系列の運用とSVN操作
※時系列とは合わない箇所があります。
- 本番リリース前の開発を行う
- 本番へリリースを行う。trunkからbranches/prdにブランチを切る。
- branches/prdからリリース対象に対してタグ(1.0.0)をつける。先行リリース機能として、trunkからbranches/featureブランチを切る。
- 本番で障害が発生したので、直接コミットする。branches/prdからリリース対象に対してタグ(1.0.1)をつける
- 障害修正を、別ブランチに反映する。branches/prdからtrunk、branches/prdからbranches/featureにマージする。
- 先行リリース機能を本番環境に反映する。branches/featureからbranches/prdにマージする。また、先行リリース機能ブランチを使わなくなるので、削除する。
- branches/prdからリリース対象に対してタグ(1.1.0)をつける
- 先行リリース機能を開発環境に反映する。branches/prdからtrunkにマージする。
- 開発環境から本番環境にメジャーアップデートする。trunkからbranches/prdにマージする。
- branches/prdからリリース対象に対してタグ(2.0.0)をつける
最終的に残っているブランチ:trunk、branches/prd
タグは基本的には許される限りは残しておくものだと思いますが、タグの生存期間や頻度等は実際の現場での相談になります。
終わりに
Gitの知識を得てからSVNの知識を学ぶと、それなりに整理できました。「SVN ブランチ戦略」で検索してきて、この記事が目的通りのものかはわかりません…。また、Gitの詳細もSVNの詳細もわかっていないので認識があっているかどうかは分かりませんが、SVNのディレクトリをコピーしつつ、履歴を残すブランチやタグを切る処理は重いだろうなぁという感想を持ちました。
動的型付言語と静的型付言語が定期的に人気が変わるように、バージョン管理システムの集中管理方式と分散管理方式の人気が変わるのでしょうか…。一度Gitで分散管理方式に慣れた身としては集中管理方式に強いメリットは感じませんが、技術として出てきたら非常に強いメリットがあるんでしょうね。
もし出てきたら、興味を持って調べてみようと思います。
もしこの記事が役に立ったのであれば、はてぶ、Twitterでの記事の拡散、Twitterのフォローもよろしくお願いします。
私の励みになります。
参考資料
https://ja.wikipedia.org/wiki/Apache_Subversion
https://ja.wikipedia.org/wiki/TortoiseSVN
類似記事
ブランチ戦略について考える
nainaistar.hatenablog.com