なぜGitはそんなに複雑なのか?


Gitはそもそも、あなたに簡単だと感じさせるつもりはなかった。

Gitなんてadd、commit、pushの3つだけだと思ってる?それはあなたがずっと「シングルプレイヤーモード」で遊んでいただけだ。せいぜいLAN協力プレイ程度だ。それはGitを使っているとは言えない——手動同期の百度網盤(Baidu Netdisk)としてGitを使っているだけだ。

Gitの複雑さは、それが解決しようとする究極の問題に由来する:互いに信用せず、生活リズムも逆で、いつコードを書きっぱなしで消えるかわからないプログラマーたちが、どうやって同じプロジェクトで協業し、しかもカオスに陥らないようにするのか?

いいか、cloneやpushは誰でもできる。しかしチームで働き始めた瞬間——pullしたら衝突だらけで、画面中に <<<<< HEAD と >>>>>> なんらかのランダムハッシュ が散らばる——そこで悪夢が始まるんだ。

私自身も経験した。私たちのチームに来た新しいバックエンド開発者は、能力はあるのにGitが使いこなせなかった。ある時、緊急のhotfixをマージする必要があったが、何時間経ってもできずに助けを求めてきた。彼のブランチグラフを見て——なんということだ、クトゥルフ神話の触手に匹敵するような絡まりようだった:フォーク、マージ、さらにフォーク、さらにマージ、その合間には意味不明の merge branch 'master' into master コミットがいくつも混ざっていた。何をしたのか聞くと、彼は言った:「pullできなかったのでfetchして、それからrebaseして、rebaseがうまくいかなかったのでmergeして、mergeでも衝突が残っていたのでresetしました……」

私の血圧は急上昇した。彼はGitを願い事をかなえる泉のように扱っていた——聞こえのいいコマンドをとにかく投げ込んで、大力出奇跡(大力が奇跡を生む)を期待していたのだ。結果:奇跡は起こらず、むしろトラブルを起こしかけた。

これは氷山の一角に過ぎない。さらに深く進むと、アトミックな歴史操作の「禁術」に辿り着く:rebase -i、cherry-pick、filter-branch。これらは何のためにあるのか?簡単に言えば、コード世界の「タイムマシン」だ——過去に戻って歴史を改変できる。しかし映画で知っての通り、タイムトラベラーの10人中9人は宇宙を壊してしまう。git reflog は后悔薬(後悔の薬)だが、ほとんどの場合、自分がいつ「毒」に当たったのかさえ気づかない。

Gitの設計哲学は、中央機関を一切信用しないことだ。すべての開発者のコンピュータは完全な「パラレルワールド」(repository)であると考える。あなたが行うコミットの1つ1つが、その宇宙に新たな歴史のスナップショットを生み出す。ブランチを使えば、好きなだけ無数の平行宇宙を切り開ける。mergeとrebaseは、異なる2つの「タイムライン」を統合しようとする試みだ——その複雑さを考えてみてほしい。物理学者だって解明できていない!

だからステージングエリアがあるのは、コミット内容を精確に制御するためだ。ブランチは作業を分離して互いに干渉しないようにするためだ。mergeは協業の必然的な産物——分歧——を処理するためだ。これらすべては壮大な「分散型」目標のために機能している。Gitは無限の自由を与えると同時に、物事を台無しにする無限の可能性も与えている。

では問題は、Gitは絶望的なのか?普通の人には決して学べないのか?

そうではない。問題はGitではなく、私たちの学び方にある。世の中のチュートリアルのほとんどは、辞書のようなコマンド一覧か、断片的なシナリオ解説のどちらかだ。公式ドキュメントは数千ページの『新华字典(Xinhua Dictionary)』のようなものだ——単語を調べるにはいいが、辞書で小説の書き方を学べると思うか?ネット上のガイドはあちこちに散らばっていて、まるでバラバラのレゴブロックを拾い集めたようなものだ。しかし「ミレニアム・ファルコン号」を組み立てるための設計図は誰もくれない。

だからこそ、網羅的であることを追求せず、実践的な高頻度シナリオに焦点を当てたチュートリアルを強く勧める。バイトダンスのチームが以前出した『Gitゼロから実践ハンドブック』はかなり良いと思う。

例えば、git pull と git pull --rebase の違いと適用シーンを教えてくれる。丸暗記させるのではない。実際のコンフリクト事例を手取り足取り解説し、他人のコードを単に削除するのではなく、エレガントに解決する方法を示してくれる。機能ブランチがメインから大きく遅れた場合、同期にmergeとrebaseのどちらを使うべきか、それぞれの選択のトレードオフを説明してくれる。

結局のところ、Gitの設計哲学は「無限の自由を与え、同時に首を吊る縄も与える」ということだ。優れたガイドとは、その縄を漁網を編んだりロッククライミングに使う方法を教えるものであり、うっかり首に縄をかけてしまわないようにするものだ。私たちの目標は、すべてのコマンドを暗記できるGit考古学者になることではない。チーム内で余裕を持って立ち回り、仲間に迷惑をかけず、いざという時に世界を救えるGitの職人になることだ。