SVNを捨ててGitを使うべき5つの理由

# まえがき

私はGit好きの人間です。
もっと言えば、Gitを愛している（Git Lover）と言ってもいいくらいです。

そんな私がなぜこんなタイトルの記事をいまさら書こうと思ったかというと、
いまだにGitの便利さを知らず、Subversionを強い理由もなく使い続ける開発者が多いからです。


# そんなわけで

「会社にGit/GitHubを導入するための説得する」

という目的でこの記事を書こうと思います。


# Gitの良さってなんだろう？

実は私もこれまで強く意識して考えたことはありませんでした。
Gitを使い出したら、 **それがあるのが当たり前でGitなしの開発など考えられなくなっていた**からです。

そういう意味では、Gitって **中世における自動車** に近いものがあるのかもしれません。

その時代、移動手段といえば馬が普通であり、
自動車などが普及するとは誰も考えなかったわけです（たぶん）。

それが今では自動車って当たり前になっています。
**気づいた時にはそれを使うのが当たり前** になっているわけです。（イノベーションってやつですね）

それほど良い例えではないかもしれませんが、
私の経験則的には、これが分かりやすいメタファーかなと思っています。

（余談ですが、私は自動車はおろか免許証すら持っていません＞＜）

# SVNと比較したGitのメリット

## 1.ローカルコミットができる

SVNの場合、 **コミット＝共用リポジトリへのコード反映** です。
私もGitを使うまでは、これでも問題ないと思っていたことを正直に認めます。

しかし、この制約は一度のコミットが巨大になる傾向になります。
コミットという操作が共用リポジトリへ反映されるということは、
 **完全には機能しない、途中段階のコードは一切コミットできない** ことを意味するからです。

### 何が問題なのか？

例えば **「あるライブラリを1.xから2.xにVersionUpする」** という作業を考えてみます。

作業タスクは以下のようになるでしょうか。

1. 既存ライブラリの削除（2.xで削除されたファイルが残らないように）
2. 2.xのライブラリをプロジェクトに取り込み
3. 1.xから2.xで変更となったAPIの反映
4. Licence表記の変更（必要があれば）

これらの変更タスクはそれぞれ独立していると考えて良いでしょう。
（それぞれのタスクに明確なゴールがある）

しかし、SVNの場合は **すべての作業が間違いなく完了**しないとコミットできません。

これは以下のことを意味します。

1. コミット前の動作確認で正しく動作しない場合、 **自分がどこで間違えたか分からない**
2. コードレビューをする人は、 **すべての修正作業をまとめてレビューして正しいと判断**しなければならない

### ローカルコミットが出来ると

次にSVNにローカルコミットがあったらと考えてみます。

1. 既存ファイルの削除（2.xで削除されたファイルが残らないように）  
**＜コミット1＞**
2. 2.xのファイルをプロジェクトに取り込み  
**＜コミット2＞**
3. 1.xから2.xで変更となったAPIの反映  
**＜コミット3＞**
4. Licence表記の変更（必要があれば）  
**＜コミット4＞**

あなたはそれぞれの作業単位で、diffを確認してコミットをすることが出来ます。
この段階では、リポジトリへの反映はしていないため **他の開発者への影響は全くありません**。

これによりローカルコミットがない場合と比べて、どのような変化が起こるのでしょうか？

1. コミット前の動作確認で正しく動作しない場合、 **コミット単位で間違いを探せる**  
（diffあるいは過去コミットのチェックアウトすることで）
2. コードレビューをする人は、 **それぞれのコミット（独立した作業単位）でレビューして正しいと判断**できる  
（あなたは巨大な作業全体でレビューしたいか、それとも作業単位でレビューしたいか？）

詳しく語ることも可能ですが、ぜひ想像力を働かせて、
SVNに枠組みにとらわれず、どちらがあなたにとって本当に嬉しいか考えてみてください。


## 2.ブランチが簡単に切れる

一般的に広く知られているものではない（と私は思うのです）が、
SVNのブランチ（とマージ）にはかなりの「制約」や「コスト」を伴います。

- 子ブランチと親ブランチ間のマージは自動で出来るが、それ以外（孫 <--> 子）についてはできない
- Gitに比較してブランチを作るコストは大きい

ここでも私自身の経験を正直に告白します。
アジャイル系の開発に関わるまで、 **ブランチを切った方がいいと思ったことは一度もありませんでした**。

開発作業とは、1つのリポジトリに着々とコミットを重ねていく作業であり、
大きな理由（フェーズ1用保守verと最新開発verを分けるとか）がなければ、
ブランチを切る理由なんて見当たりませんでした。

そういった意味で、この項のタイトルである「ブランチが簡単に切れる」というのは、
ブランチを切らない開発をしてきた開発者には実は説明しづらいのです・・・実は。

（前述したとおり、私自身も **”ブランチが簡単に切れるの、で？”**という調子だろう）

### なぜブランチが必要なのか？

じゃあ、そもそもブランチってなんで切るんでしょう？
それは **他の開発者に影響をあたえず**、自分に与えられた開発作業をコミットしていくためです。

ふむ、考えてみると **実にアタリマエ**のことです。
そう考えると「ブランチを切る」ってのはむしろ自然な考えで、逆にブランチを切らないほうが不自然な考え方に思えてきます。

そういう **発想転換**が出来ると、今度はブランチを自由に切りたくなってきます。

### ブランチを使った開発

例えば「電子書籍Webサイト」の「検索機能」を作ることを考えてみます。
そして、あなたに与えられた開発作業は「お気に入り検索」です。

WBS（Work Breakdown Structure）で階層を考えると、以下のようになるでしょうか。

 - 電子書籍Webサイト ver1.0
   - 検索機能
     - フリーワード検索
     - カテゴリ検索
     - 詳細検索
     - お気に入り検索 **★あなたの開発担当**
   - 他機能A（ログインとか）
   - 他機能B（購入機能とか）

今回はそれぞれの機能が完全に独立していると仮定(*1)します。

あなたがプロジェクトを管理する立場、
あるいは聡明な開発者の一人であれば、以下のような開発スタイルでやりたいと考えるでしょう。

- 「フリーワード検索」とか「カテゴリ検索」とか、  
**それぞれの「中機能」ができたタイミングで、随時「検索機能」にマージ**していきたいな。
- 検索機能とか他機能A（ログインとか）とか、  
**それぞれの「大機能」ができたタイミングで、随時「電子書籍Webサイト ver1.0」にマージ**していきたいな。

前置きが長くなってしまいました。
このような自然な考え方、つまり「ブランチを切る」「それをマージする」という作業について、

- SVNだと制限が多く、コストも高い
- Gitだと自由に出来て(*2)、コストも驚くほど低い（それを前提としたアーキテクチャになっているのだ）

という違いが見られるわけです。

*1 この仮定が成り立たない場合（普通のことだ）でも、Gitのブランチはとても有効に機能することを補足しておく
*2 Gitの達人はこう言うらしい、”できるだけ早くブランチを切れ”と。


## 3.機能が充実し、操作体系も洗練されている

Gitが開発された経緯についても書いておきましょう。
もっとも、私自身が体験したことではなく本かWeb記事で読んだ知った内容ですけれど。

当時、最大のOSSである「Linux（カーネル）」は商用のVCS（バージョン管理理ステム）を採用していました。
それがライセンス上の理由だとかで、無料で使えなくなっちゃいました。

そこで、Linuxの開発者でもあるリーナス氏は、
新しいバージョン管理システムを1から再発明することにしたわけです。

プログラミング言語の歴史がそうであるように、
**過去から学び洗練されたバージョン管理システムを作り上げた**わけです。
（これは多分に憶測にもとづいていることを付記しておきます）

別にリーナス氏を崇拝するわけではないのですけれど、何を言わんとするかは分かると思います。

- GitはSVNが出来なかったことを、 **出来るようにしている**
- GitはSVNが出来たことを、 **より上手に出来るようにしている**

詳細について書き出したい気持ちはあるのですが、
Gitの解説記事になってしまうので止めておきます。


## 4.GitHubが利用できる

GitHubについて多くの説明は不要だと思います。
知らない人は「GitHubとは」とかでググってもらえれば大丈夫です。
（今さら聞けない・・・とかいう記事が出てくるんじゃないでしょうか）

GitHub（あるいはその派生アプリケーション）は、
現在の開発ではなくてはならないもの、というより使ってなんぼという状況になっています。
（メモ帳でもコードはかけるけど、高機能エディタ、あるいはIDE使ったほうが効率いいよね、ってイメージです）

一度、PullRequest（プルリクエスト）を使ってしまったら、
あなたは、今までどれだけコードレビューやブランチ管理に時間を費やしてきたのか痛感するでしょう。

PullRequestについて簡単に説明すると、
「こういう機能を作ったんだ、これをあなたの開発ブランチにマージしてくれないかな」ってお願いするものです。
（あぁ、これもググってもらったほうが早いかも・・・）

PullRequestを受けた人は、
コード差分（diff）が表示されるのでそれをレビューして、
問題があればコメント（あるいはディスカッション）して、問題がなければAccept（取り込み）することになります。

GitHubの機能はもちろんこれだけではないですけれど、
PullRequestがあるだけで、GitHubを使う理由としては十二分にあると思います。


## 5.世界の標準はGit

何年か前だったでしょうか。
私も「Gitを使うべき理由」みたいな記事の中で、以下のようなチャートを見たわけです。

![Screenshot 2015-01-12 21.09.49.png](https://qiita-image-store.s3.amazonaws.com/0/29653/45d75635-e747-584c-de69-15a00efc6355.png "Screenshot 2015-01-12 21.09.49.png")

これはGoogleのトレンド検索結果のチャートで、
gitがsvn(subversion)と比較して、どれだけ検索されているかひと目で分かるものです。

もちろん、これがそのまま利用ユーザ数というわけではありませんが。


# 他にも

Git/GitHubを評価すべき点はたくさんあります。

- 高速な動作
- 強力なコマンド体系
- 柔軟なブランチ機能を利用した開発フロー
- 制作（デザイナ）の人とも協力しやすい

聞いた話によれば、
いまや技術著者と出版社のやりとりにもGitHubが使われているようです。

Git/GitHubはソフトウェア開発だけにとどまらない、そういう時代なのです。


# デメリット（あるいは導入コストについて）

これまで見てきたとおり、 もし **導入コストが0であれば**SVNからGitへ移行しない理由はありません。
（少なくとも私はそう考えています）

ただし、実際にはその前提は成り立たず、実際には導入コスト（移行コストを含む）というものが確実に存在します。

1. Gitの学習コストが発生する
2. 既存でSVNリポジトリ管理している場合はGitと連携する
3. GitHub（あるいは他のOSSクローン）を利用する場合、費用あるいは導入コストが発生する

それぞれについて見ていきましょう。

## 1. Gitの学習コストが発生する

もうこれは技術者として生きていく以上、ある意味仕方ない話ではあります。

JavaやRubyはオブジェクト指向で学習コストがかかるから、
と理論武装してCOBOLをずっとやっていてもいいですが、仕事がなくなるのは時間の問題です。

まぁしかし実際のところ仕事で使う以上、悩ましい部分ではあります。

### トラブルと戦う

私が関わったプロジェクトでGitを導入した時も、
Gitrouble（ギットラブル）(*1)と呼ばれるトラブルは絶えませんでした。

「怖くないGit」というスライドがアップされるくらいです。
http://www.slideshare.net/kotas/git-15276118

控えめにみても、Gitは怖い、じゃなくて学習コストはSVNのそれよりも高いのです。

*1 語呂が良かったのでプロジェクト内で定着した造語です

### サプリメント

個人的に、開発プロジェクトへの以下のサプリメントを提案します。

- チームに1人でも良いので、Gitのプロフェッショナルを入れる（いなければIT組織計画として用意する）
- Gitの学習にかかる時間を「プロジェクトの作業時間」として取る
- Gitの本を開発チームで購入して、いつでも読める状態にしておく

とにかく、開発チーム、あるいはIT組織、あるいは会社でも良いですが、
そうしたスコープで対応するようにアプローチしましょう。

みんなで進まなければ、どこかしらでうまくいかず余計なコストを払うことが多いものです。

## 2. 既存のSVNリポジトリとの連携

例えば、今までSVNリポジトリで管理してきたソフトウェアがあったとします。
それをGitに移行するとしたら、今までのSVNコミット履歴はなくなってしまうのでしょうか？

そんなことはなく「git-svn」というツールがあります。

私自身も直接使ったことはないので必要になったら学習・導入コストは必要でしょう。
そういうコストは発生するわけです。

## 3. GitHub（あるいは他のOSSクローン）を利用する場合、費用あるいは導入コストが発生する

GitHubは公開リポジトリであれば無料で使えますが、
仕事で開発しているソフトウェアのコードを公開するわけにはいかず、
必然的に有料のプライベートリポジトリを必要とします。

GitHubは一番有名ですし、世界標準ですから、GitHubが使えるに越したことはありません。
しかし、いろいろな事情（予算とか）で使えないことも多いでしょう。

その場合は、他のリポジトリ管理サービスを利用するのも手です。

- GitLab
- BitBuckets
- GitBucket
- etc...

ここで詳細について語ることは避けます。（比較記事も世に多く出ているので）
重要なのは、どのサービスを利用するのが良いか考えぬくことです。

例えば「GitLab」、これは **完全無料**です。
~~まぁ、しかし昔からただより安いものはないと言うくらいで、実際GitHubよりはかなり劣ります。~~

~~私はプロジェクトの費用を管理するような立場に立ったことはないので、
あくまで私の個人的感覚にもとづいて、という前提付きの意見となりますが、
「GitLabを導入して使うくらいだったら、GitHubにお金を払ったほうが得」だと感じています。~~

**追記：
コメントでご指摘いただきましたが、最近のGitLabでは当初不足していた機能が拡充され、機能的にはGitHubとも遜色が無いレベルに達しているようです。**

繰り返します。

重要なのは、プロジェクトでどれを採用するのがベストか考えぬくことです。

安い＝悪い、ではありませんが、
安い＝コストが低い、というわけでもありません。

# 最後に

さて、ここまで新宿のCafeで一気に書き上げました。
個人的にSVNを捨てて、Git/GitHubを用いた開発を提案できるような材料を並べたつもりです。

しかし、これだけの材料で説得できるかどうかはやってみなければ分かりません。

もし技術に長けた開発者を説得するのであれば、これだけの材料で十分だと思います。

ただし技術を知らない上層部に説得するのであれば、
もっと詳細な（あるいは要約した）情報を必要とされるかもしれません。

どちらにせよ、結果あるいは経過が観測できた時点で、この記事に追記したいと思います。

# 関連記事（Tigは便利です）

- [[Git] 10分で使いはじめるTig（コミット操作を早くする）](http://qiita.com/YusukeHosonuma/items/d81397ab70a8c26a2902)
- [[GitHub] ディスカッションのコメントをすべて開く](http://qiita.com/YusukeHosonuma/items/9831f9a6654ce6a0df2d)