先日、Subversionの1.9.5がリリースされたというのをTwitterで見かけた。この機会を逃したら2度と書くこともないと思うのでSubversionがgitより良い点と思う部分を書いてみる。

まえがき


あらかじめ書いておかなければいけない点が何点かある。私はいまさら業務都合で使わざるを得ない場合を除いてSubversionを使う気は全くない。2点目に、かといって特にSubversionがgitに比べて劣るとも思っていない。3点目に、私のバージョン管理システムの使用経験はせいぜい3年程度である。

私のバージョン管理システムの使用歴はSubversionが1.5年程度でgitが2.5年くらいである。「足したら4年になるじゃないか!!」なのですが、これはSubversionからgitに移行する手順とかフローとかを検証するために併用していた期間が半年くらいあるためである。
たかだか3年程度の人間にごちゃごちゃ言われるのは片腹痛いと思われるかもしれないけど、gitに関してはそんじょそこらのエンジニアがやってもないような操作とかやってきて、運用のフローも含めてそこそこ詳しいという自負はある。まあ、この辺の話を書きだしたらキリがない。私のSubversionに関する知識は2年前に使っていた当時の最新バージョンの知識であるし、gitに関しても1.9.0の時の知識がベースなのでもしかしたら以降に記載することは間違っているかもしれない。また、gitの良い点は探したらいくらでも出てくるので今回はそういった点は基本的には書いていない。

今回はそういった背景を踏まえた上でSubversionの利点に関する記事。以下は淡々とgitと比較したSubversionの良い点を書いていく。(と書きながらそれ以外も書いてしまったが…)

コミットログの書き換えが容易


個人的にこれがもっともSubversionがgitより優れていた点。
gitはコミットログの書き換えが容易ではない。書き換えはできるけど、容易ではない。この話を書き出すと別で記事が書けてしまうので今回は書かないけれども、gitでコミットログを書き換えるのは非常に労力が必要になる。既に積みあがったコミットのコメントを書き換えるのはgitでは容易なことではない。fileter-branchというgit最強の破壊的オプションを使用して書き換える必要がある。これを使用したときの問題について書き出すとキリがないので今回は書かないけど、このオプションはマジでヤバい。

比べて、Subversionはコミットログを容易に書き換えることができる。
書き換えるにはhookにちょっとしたコードを書くだけ。どういったものを書けば良いかは忘れてしまったが、調べればいくらでも出てくると思う。

コミットログを後から書き換えることがあるのか?…と言われればちゃんとしたレビュー体制が整っていれば問題ないのかもしれない。マージの前に弾くことができるから。しかし、そういった体制が整っていなければ、コミットメッセージが多少間違っているくらいならまだしも、ITSを使用している場合などのチケット(Issue)番号の記述が間違っていれば目も当てられない。対象のチケットに対するコミットが誤って表示されてしまうのだから。しかも修正は容易ではない…

gitを導入していたとしてもそこまでキッチリしたレビュー体制が整っている組織があるかと言われると、そうでもないのではないかと思う。結果として、チケット番号が異なるコミットがマージされる可能性が高くなる。こうなると、gitで後でログを変更するのは非常にめんどう(というか現実問題的に不可能に近い)だ。なので、git + ITSを導入した場合はそのチェックが非常に重要になる。

と、偉そうに書いておきながら、弊社ではできてません…前職の時は私がマージの前に全部やってたんですけどね…

対して、Subversionはhookを少し弄れば後からログを変更できるので、この問題に対応することができる。

少し話が逸れてしまうが、私はコミットログは非常に重要な要素だと思っていて、キチンとした単位で、キチンとしたメッセージを残さなければいけないと思っている。「ソースコードを見れば変更箇所が解る」とかいう理屈はある意味もっともだが、だからといってコミットログのメッセージを適当に書いたり、適当な粒度でコミットするには個人的に論外だと思っている。コードを見るまでもなく、コミットログである程度の概要が解るべきだと思っている。キチンとしたコミットログは残すべき。そういう点でgitは中央のリポジトリにpushしない限りはコミットはいくらでも書き換えてよいという思想なので、コミットをキレイにするには最適だと思う。従ってコミットはpushする前に出来る限りキレイにするべきだと思っている。たぶんこの考えは大方間違ってないと思う。(ちなみにGitHubでgitのリポジトリを見てみるとコミットログは相当詳細なレベルで記述されている。)

もっとも、個人的にやる範囲ではある程度適当でもよいと思うし、私も適当にやっていることが多い。あくまで個人的な範囲に限ってだが…

コミット番号が解り易い


gitのコミット番号はsha-1のハッシュ値なので直感的に解り難い。これはブランチの概念がSubversionと違うので仕方ないと思うのだけど、Subversionだと連番なので解り易い。解り易いと書いときながら、正直個人的には割とどうでもいい要素でもある。

ファイルの削除がラク


gitであるファイルを履歴ごと削除したいとなった場合、そこそこの労力が必要になる。前述のfileter-branchを使用して、かつ場合によってはもう少し複雑な処理が必要になる。また、コミットのハッシュ値が変わってしまうので、全員が再度cloneしなおさないといけない。
対して、Subversionだとdumpでいらんファイルを除外すればいい。しかもgitのfileter-branchにくらべてはるかに高速である。

まあ、使う機会はそんなにないと思うんですけどね。

悲観的ロックができる


Subversion(というか中央管理型のバージョン管理システム)だとファイルごとの悲観的ロックをかけることができる。要するに「私がこのファイル編集してるので他の人は触らないでね。」ってのができる。
これも特に個人的に必要ないと思うんだけど、gitをはじめとした分散型のバージョン管理システムだとできない(git以外は正直知らない)

まあ、たぶんプロジェクトによっては必要になる部分も出てくることもないのではないかと思う…特にバイナリのファイル編集するときとか編集するときとか編集するときとか…

学習コストが低い


gitは学習コストが非常に高いと言われているし、実際にそうだと思う。まず、分散管理の次点で意味が解らんと思う。他の分散管理、例えばMercurialなどは使ったことないので知らないが、それらと比べても学習コストは高いといわれている。しかし、それに余りあるだけのメリットがあるし、gitが主流になってるのでいまからバージョン管理するならgitでやるべきだと個人的には思う。

ただ、バージョン管理の概念とか歴史とか中央管理とか学ぶにはSubversionを一度触ってみるのもアリだという気がしなくもない。まあ、くどいけど今からやるならgitからやった方がいいと思うけど。
あんまりSubversionのメリットに関係ない項目になっちゃったね…

まとめ


よ~するに、そのプロジェクトによってどっちを使うかは異なると思います。
…が、git使いましょう!git!とりあえず、使ってから考えたらいいと思います。