なぜGitは難しいのか(あるいは「難しいツール」だと感じるのか)?

ユーザとして2~3のバージョン管理システムを扱った後、4つ目に出会い今も使い続けているGitだが、使い始めてから7年以上経った今でも「難しいツールだな」という感想を抱く瞬間がある。

私は元々、集中型のバージョン管理システムを長らく使用してきた。Gitは初めて経験した(そして現時点では唯一経験したことのある)分散型バージョン管理システムだ。そういった個人的経緯より、Gitを難しく感じることがあるのは「古い経験則に囚われた、老害の個人的感想」ではないかと自分自身を疑ってきた。

疑ってきたのだが……新入社員にGitについて教える機会に直面するようになってから、どうもGitというツールには、今まで触ってきたバージョン管理システムにはないような「本質的に難しい何か」があるのではないかと感じるようになってきた。

というのも、例えば過去に使用した経験があるCVSSubversionと比較すると、Gitは明らかに「新入社員への教育コスト」が高いのである。教育に割かれる時間は増えていて、それでいて業務アサイン後の操作トラブル件数は微増している。

振り返れば、CVSSubversionを使用していた頃は、バージョン管理システムの扱い方について「独立した研修」のような機会は皆無だった。大抵はOJTの場にて先輩からちょっと説明を受けただけだったし、それだけでもしばらく使っていくうちに「大雑把な使い方の全体像」を理解することができたように思う。

一方で、Gitを使い始めた当初の感想は「どう使えば良いのか分からない」だった。個々の操作(fetchやpullやmergeやpushなど)が分からないのではなく、全体像がよく分からなかった。そのため、1つ1つの操作を実行する際に「全体的にみて、この操作は今ここで実行してよいのか?」という疑問を解消できず、迷いを抱えたまま恐る恐る触っていた。

7年以上使っていることもあり、普段使いの範囲では、迷いを抱えたまま操作することは無くなった。しかしそれでも、普段使いの範囲を逸脱した操作や、他の利用者のヘルプ・コールに応じて問題解決を試みる時などには、今でも迷いを抱くことがある。

Gitは15年以上も開発が続けられているツールではあるが、それでもどちらかと言えば後発のバージョン管理システムだ。しかしオープンソースの超有名どころバージョン管理システムを歴史順に「CVSSubversion・Git」と並べた時、Gitは最後発なのにも関わらず、使いこなせないというユーザは最も多いように見える。

より便利になるように後発のツールが作られたはず(仮説)なのに、使いこなせないユーザの割合が増えているように見える――というのは少々不思議な構図である。

ポリシーとメカニズムの分離と、メカニズムの制約に基づく「暗黙のポリシー」

Gitを難しいと感じる理由について考えたとき、UNIX思想における「ポリシーとメカニズムの分離」に突き当たるように思う。

これはエリック・S・レイモンドが『The Art of UNIX Programming』で述べた「ポリシーをメカニズムから分離せよ」という思想である。ポリシー(物事を行うときの原則)は時代と場所で変化する不安定なものであるから、ツールを作る際にはメカニズム(機能)だけ提供するようにしておいて、ユーザには自身のポリシーに沿った形でメカニズムを利用してもらう――という考え方だ。

実のところ、CVSSubversion・Gitのいずれも、基本的にはメカニズムのみを提供する。問題は、CVSSubversionはメカニズムの制約より「大まかな利用スタイル」が定まっているのにたいして、Gitは自由度が高い(メカニズムによる制約が緩い)、という点にある。

CVSSubversionには「集中型バージョン管理システム」という制約がある。この制約により、使い方のスタイルは概ね定まっている。メンバー全員がアクセスできるサーバ上にリポジトリを置き、各メンバーの端末にファイルをチェックアウトし、編集し、リポジトリにチェックインする。大抵はこのようなスタイルに固定される。

UNIX思想に基づいてメカニズムのみを提供しているにも関わらず、ツールの性質より、大まかな利用スタイルが決ってしまう。私はこれを「暗黙のポリシー」と呼んでいる。

つまりCVSSubversionを使う際には、誰しもが暗黙のポリシーに従っているし、ひとまず暗黙のポリシーに従っておけば概ね上手くいくのだ。

一方でGitは、使い方のスタイルが定まっているとは言い難い。リモートリポジトリを1つ利用する従来のSubversionっぽいスタイル、リモートリポジトリを持たないスタイル、複数のリモートリポジトリを参照するスタイルなど、様々な使い方ができるように設計・実装されている。だからGitでバージョン管理したいなら、まずは自分の環境に合ったスタイルを模索しなくてはならず、模索するためには「Gitで何ができるか?」ということを知る必要があり、Gitの可能性と限界を判断するためにもGitの全体像(表面的な使い方ではなく、操作の背景や内部メカニズム)に目を向けなくてはならない。

つまりGitには、CVSSubversionのような暗黙のポリシーが無いに等しい。

ポリシーがない状態でメカニズムを渡された時、メカニズムの制約の緩さ(≒ツールの自由度の高さ)は、時として凶器となる。明示的でも暗黙的でも、ポリシーさえあるなら、ひとまずそれに従ってツールを使えばよい。使っていくうちに、段々と分かってくるようになるものだ。しかしポリシーが無いと、自由過ぎて「そもそも、どう使えばよいのか?」と困惑してしまうものだ。

仮にポリシーを定めたとしても、今度は「ポリシーに沿うようにメカニズムを利用するには、どうすれば良いか?」という問題が生じる。うまい具合にポリシーに合わせるために、メカニズムそのものへの理解を深める必要がある。この点は「ツールの学習コストの高さ」として表面化する。

そして重要なことだが、「自身のポリシーに沿った形で『制約の緩いメカニズム』を利用する」ということは、「運用でカバー」と同義だ。「ユーザの使い込み度」という、ある種の技術力を前提としている訳だ。だから、ツール利用者の熟練度が低い間は、運用トラブルは必至だと言える。誰しも慣れないうちは、commit前にpullしたり、commit後のpushを忘れたりしてしまう――ということが起きる遠因だ。

熟練者の罠

ポリシーがない状態でメカニズムを渡すことには暴力性が伴うものだが、しかし一方で「使いこなすことさえできれば、利用者に大きな力を与える」という利点もある。

その分かりやすい例はUnix環境のCLIだ。自由度の高い、メカニズムのみを提供するツールであり、初心者がトラブルを引き起こす例は枚挙にいとまがない。それなのに、Unix環境は依然として一部のソフトウェア・エンジニアを惹きつけて止まない。なぜだろうか?

要は、自由度の高さは諸刃の剣なのだ。扱い方をしくじれば大怪我するが、うまくコントロールできれば強力な武器となる。ツールの自由度の高さは、現実の開発においてソフトウェア・エンジニアの武器となりうる(偶にしくじって怪我をするが)。だから今でもメカニズムのみを提供するツールが作られ続けているし、熱心なユーザはツール利用の熟練度を上げようと訓練し続けている。

Unix環境のCLI信者の大半は、「熟練度が高くなるにつれて、メカニズムを自在にコントロールできるようになり、飛躍的に生産性が向上する」という体験の虜になっているように思う。

Gitも同じで、使い慣れてくるとその便利さが分かるようになるし、熟練するにつれてGUIのツールだけでは物足りなくなってgit(1)コマンドを併用するようになってくる。

問題は、Gitのパワーを感じ取れるようになる前に、学習曲線が低い状態がしばらく続く、という点にある。Gitはバージョン管理システムという重要なツールではあるが、プログラミングそのものでない。あくまでも副次的なツールだ。本筋からやや外れたツールであるために、「習熟する」というレベルまで使いこもうとする人は少ない。そのため、大抵のGitユーザは学習曲線が低い期間が長いか、もしくは低い状態から抜け出すことがないだろう。