【Git】【雑感】CVS や Subversion を捨ててまで Git を導入する意味があるのだろうか

業務で Git を使っているが、全く利点が無いので、Git 否定的立場で書いてみた。
あくまでも 業務環境での Git についてです。

八つ当たり被害者は、Qiita で一番最初に挙がった下記ページ様です。

qiita.com

まえがき

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

私は Git が好きでも嫌いでもない人間です。
ただ、特に製品開発をしている現場(特に大手メーカ)では、単に「新しい」「世間で流行っている」というだけで新しいソフトを導入しているような気がしています。

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

新しい VCS の利点のみしか見えなくなり、理想形ばかりを夢見ていないでしょうか?。
現在抱えている問題の改修およびシステム仕様を把握せずに、次々と新しい VCS に切り変えているのが現実では無いのでしょうか。
「その機能、Subversion でできませんか?」と問い掛けてみてはいかがでしょうか?。

そんなわけで

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

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

Git 導入の説明を受けると、 「つい2年前にレビュされた、CVS から Subversion 切り替えによる素晴しいバージョン管理の仕組みはどうなったのでしょうか?。」
「今回の Git 導入によるメリットですが、(CVSを捨てて) Subversion 導入時にも言っていませんでしたっけ?」
と言いたくなります。

あと、目新しい VCS が生れたら、「それ Git でも実現できるのでは?」ということでも、 Git からそちらに移るのではないでしょうか?。

Gitの良さってなんだろう?

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

自由に進められるオープンソースならまだしも、ルールで縛られた業務環境で頻繁なブランチ化やマージなど使えるのでしょうか?。   私の経験では * 内部では Subversion や Perforce で管理する
* 外部リリース時には Git リポジトリへ Push する
というプロジェクトが多いです。

「外部=お客側が Git を使いたい」と言い出して、このような不釣り合いな構成になっています。

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

その時代、移動手段といえば馬が普通であり、 自動車などが普及するとは誰も考えなかったわけです(たぶん)。
それが今では自動車って当たり前になっています。 気づいた時にはそれを使うのが当たり前 になっているわけです。(イノベーションってやつですね)
それほど良い例えではないかもしれませんが、 私の経験則的には、これが分かりやすいメタファーかなと思っています。

'パラダイムシフト' ということでしょうか?。
私には、PullRequest の目新しさから皆が飛び付いているものの、後発の VCS が生れたらすぐに捨てられてしまう、という程度にしか見えないです。
Git の操作性は良くない = 学習コスト大 だと思っているので、もっと操作性に優れたソフトが出たら乗り換えが発生するように思えてなりません。
とても「make」のように長寿になるとは思えないのです。

(余談ですが、私は自動車はおろか免許証すら持っていません><)

私も持っていません><

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


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


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

Subversion でも各自がテスト用のブランチを作って、そこにコミットし、最終的に共用リポジトリにコミットすれば同じことではないのでしょうか?

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

実際の製品開発の現場なら、「1機能は1度でコミットしろ」とうるさいです。
(コミットの度に CI による数時間掛るコード検証(ビルド、静的テスト)が行われるので、完全に Git の優位性を否定した運用ですね。)

何が問題なのか?


例えば 「あるライブラリを1.xから2.xにVersionUpする」 という作業を考えてみます。
作業タスクは以下のようになるでしょうか。
1. 既存ライブラリの削除(2.xで削除されたファイルが残らないように)
2. 2.xのライブラリをプロジェクトに取り込み
3. 1.xから2.xで変更となったAPIの反映
4. Licence表記の変更(必要があれば)

これらの変更タスクはそれぞれ独立していると考えて良いでしょう。 (それぞれのタスクに明確なゴールがある)
しかし、SVNの場合は すべての作業が間違いなく完了しないとコミットできません。

Subversion でもテストブランチを作れば実現可能です。
共用リポジトリに投入していないことは、Git、SVN で違いは無いはずです。

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

Subversion でもテストブランチを作れば実現可能です。

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


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

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

<コミット4>

あなたはそれぞれの作業単位で、diffを確認してコミットをすることが出来ます。

Subversion でも Tortoise svn を使ってグラフィカルに差分比較ができますね

この段階では、リポジトリへの反映はしていないため 他の開発者への影響は全くありません
これによりローカルコミットがない場合と比べて、どのような変化が起こるのでしょうか?
1. コミット前の動作確認で正しく動作しない場合、 コミット単位で間違いを探せる
(diffあるいは過去コミットのチェックアウトすることで)
2. コードレビューをする人は、 それぞれのコミット(独立した作業単位)でレビューして正しいと判断できる
(あなたは巨大な作業全体でレビューしたいか、それとも作業単位でレビューしたいか?)

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

Subversion でもテストブランチを作れば実現可能です。

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


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

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

「コスト」の意味が不明ですが、Subversion でのブランチ作成の操作が複雑ということでしょうか?。

であれば、Subversion のブランチ作成の操作は簡単です。
(というより、Git との大きな差は無いと思います)

  • trunk からブランチ「A」を作る場合
svn copy https://subversion/server/trunk  https://subversion/server/branch/A

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

集中管理型の VCS である Perforce を使ってアジャイル系開発をしているプロジェクトはありますよ。


開発作業とは、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の達人はこう言うらしい、”できるだけ早くブランチを切れ”と。

なぜ、SVN だと「ブランチを切る」「それをマージする」ことの制限が多いのか不明です。
XXX ブランチから trunk へマージをして、コミットするまでの操作は以下ですが、Git と大差ないかと思います。

1. 取り込みたい範囲(リビジョン)確認する

% svn co https://subversion/server/trunk
% svn log --stop-on-copy 'https://subversion/server/branch/XXXX'
r10530 | neko | 2017-11-20 22:30:06 +0900 (2017/11/20) | 7 lines
中略
r10438 | neko | 2017-11-17 09:35:56 +0900 (2017/11/20) | 24 lines
r10384 | neko | 2017-11-15 20:06:56 +0900 (2017/11/20) | 8 lines

2. 取り込み可能かテストする

% svn merge --dry-run -r 10384:10530 https://subversion/server/branch/XXXX

3. 本実行

% svn merge           -r 10384:10530 https://subversion/server/branch/XXXX
--- r10385 から r 10530 までを '.' にマージしています:

4. trunk へコミットする

% svn commit -m 'Merge: branch/XXXX to trunk' .

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


Gitが開発された経緯についても書いておきましょう。

もっとも、私自身が体験したことではなく本かWeb記事で読んだ知った内容ですけれど。

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

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

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

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

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

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

「GitはSVNが出来なかったことを、 **出来るようにしている」という一文には同意します。 (Git と SVN に限らず、全てのソフトウェアについて言えることかと思います。)

4.GitHubが利用できる


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

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

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

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

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

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

同じく、PullRequest は素晴しいと思います。
Subversion や Perforce では ReviewBoard を導入して、 Git の PullRequest と同じようなことを目指す職場が多かったです。
ちなみに、Git を使った職場では Gerrit を使っています。

5.世界の標準はGit


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

Screenshot 2015-01-12 21.09.49.png

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

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


他にも



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

- 高速な動作

何を持って「高速」なのでしょうか?。
CVS, SVN との速度差がわかりません。

あと、私の職場ではリモートリポジトリへの Push によってネットワークが混雑し、git clone するだけに 10分待機させらることがあるので、全く高速ではありません。。*1 が、もちろんこういう速度を指しての「高速」では無いと思っています

  • 強力なコマンド体系

何が「強力」なのか不明です。

  • 柔軟なブランチ機能を利用した開発フロー

実際の開発現場では制約だらけです。

  • 一度作成したブランチの削除すら許可されていません (テストブランチですら削除不可)
  • git rebase は許可されていません
  • git revert も許可されていません
  • git reset も許可されていません
  • 制作(デザイナ)の人とも協力しやすい

ブランチ開発であれば、CVS や Subversion で良いのでは無いでしょうか?。

実際の現場では、おまじない的に Git 操作する人が多いです。
また、デザイナではないのですが、SE的な立場の人が「ブランチの派生がわからないから、ブランチの派生図を HTML 形式で作ってくれ」と言います。
これって協力できていませんよね?

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

Privateリポジトリを持ち、かつ、ドラッグ and ドロップでできるのであれば良いかと思います。
ただ、GitHub にこだわる必要も無いかと思います。(倒産のリスクがゼロとは言えないので)

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

無理して 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のそれよりも高いのです。

同意です。
コミット時にコンフリクトが起きたら、再度、git clone からやり直してマージしている人が多いです。

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

サプリメント


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

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

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

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

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


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

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

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

Subversion の運用を外部に委託している企業が多くて、Git に完全移行できない職場が多いです。

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


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

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

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

- GitLab
- BitBuckets
- GitBucket
- etc...

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

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

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

外部にコードを出せないから、GitHub のシステムを購入している業務がありました。
多分、GitHub Enterprise だと思います。

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



繰り返します。


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

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

最後に


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

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

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

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

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

関連記事(Tigは便利です)


- [Git] 10分で使いはじめるTig(コミット操作を早くする) - [GitHub] ディスカッションのコメントをすべて開く

実際の開発現場では、システム構築グループが居て、その人たちが仕事が無くならないように目新しいソフトを提案し導入しているのが現実です。
新しいソフトを使うことで得られる効率性に目が眩む御偉い方が多いからですね。
ちなみに御偉い方は「自動化」もお好きなようです。

個人的には、Microsoft によってブラウザ上での GitHub の使い勝手を良くしてもらいたいです。

最後に。

下記のページが私の言いたいことを述べて下さっていました。

www.kaitoy.xyz

*1:1度のPushによるリリースの弊害であり、巨大な Push が原因です