Git
Chapters ▾ 2nd Edition

10.1 Gitの内側 - 配管(Plumbing)と磁器(Porcelain)

どこかの章からここに飛んできたのか、本書の他の部分を読み終えてからここにたどり着いたのか – いずれにせよ、この章ではGitの内部動作と実装を詳細に見ていきます。 我々は、Gitがいかに便利で強力かを理解するには、その内部動作と実装を学ぶことが根本的に重要であると考えました。一方で、そういった内容は、初心者にとっては不必要に複雑で、かえって混乱を招くおそれがあると主張する人もいました。 そこで我々は、この話題を本書の最後の章にして、読者の学習プロセスの最初の方で読んでも最後の方で読んでもいいようにしました。 いつ読むかって? それは読者の判断にお任せします。

もう既にあなたはこの章を読んでいますので、早速、開始しましょう。 まず最初に明確にしておきたいのですが、Gitの実態は内容アドレスファイルシステム(content-addressable filesystem)であり、その上にVCSのユーザーインターフェイスが実装されています。 これが何を意味するかについては、すぐ後で学びます。

初期(主に1.5より古いバージョン)のGitのユーザーインターフェイスは、今よりずっと複雑でした。これは、当時のGitが、洗練されたVCSであることよりも、このファイルシステムの方を重要視していたためです。 ここ数年で、Gitのユーザーインターフェイスは改良されて、世の中にある他のシステムと同じくらいシンプルで扱いやすいものになりました。しかし、複雑で学習するのが難しいという、初期のGitのUIに対するステレオタイプはいまだに残っています。

内容アドレスファイルシステムの層は驚くほど素晴らしいので、この章の最初で取り上げます。その次に転送メカニズムと、今後あなたが行う必要があるかもしれないリポジトリの保守作業について学習することにします。

配管(Plumbing)と磁器(Porcelain)

本書では、checkoutbranchremote などの約30のコマンドを用いて、Gitの使い方を説明しています。 一方、Gitには低レベルの処理を行うためのコマンドも沢山あります。これは、Gitが元々は、完全にユーザフレンドリーなVCSというよりも、VCSのためのツールキットだったことが理由です。これらのコマンドは、UNIX流につなぎ合わせたり、スクリプトから呼んだりすることを主眼において設計されています。 これらのコマンドは、通常 “配管(plumbing)” コマンドと呼ばれています。対して、よりユーザフレンドリーなコマンドは “磁器(porcelain)” コマンドと呼ばれています。

本書のはじめの9つの章では、ほぼ磁器コマンドだけを取り扱ってきました。 一方、本章ではそのほとんどで低レベルの配管コマンドを使用します。これは、Gitの内部動作にアクセスして、Gitが、ある処理を、なぜ、どうやって行うのか確かめるためです。 これら配管コマンドの多くは、コマンドラインから直接実行されるのではなく、新しくツールやカスタムスクリプトを作る際に構成要素となることを意図して作られています。

新規の、または既存のディレクトリで git init を実行すると、Git は .git というディレクトリを作ります。Git が保管したり操作したりする対象の、ほとんどすべてがここに格納されます。 リポジトリのバックアップやクローンをしたい場合、このディレクトリをどこかへコピーするだけで、ほぼ事足ります。 基本的にこの章では、全体を通して、 .git ディレクトリの内容を取り扱います。 .git ディレクトリの中は以下のようになっています。

$ ls -F1
HEAD
config*
description
hooks/
info/
objects/
refs/

これが git init を実行した直後のデフォルトのリポジトリであり、デフォルトで表示される内容です。なお、環境によってはここにないファイルが表示されることもあります。 description ファイルは、GitWebプログラムでのみ使用するものなので、特に気にしなくて大丈夫です。 config ファイルには、プロジェクト固有の設定が書かれています。また、info ディレクトリにはグローバルレベルの除外設定ファイル が格納されます。これは、.gitignoreファイルに記録したくない除外パターンを書く際に使用します。 hooks ディレクトリには、クライアントサイド、または、サーバーサイドのフックスクリプトが格納されます。フックスクリプトについては Git フック で詳しく説明します。

そして、重要なのは残りの4項目です。具体的には、 HEAD ファイル、 index ファイル(まだ作成されていない)、 objects ディレクトリ、 refs ディレクトリです。 これらがGitの中核部分になります。 objects ディレクトリにはデータベースのすべてのコンテンツが保管されます。refs ディレクトリには、それらコンテンツ内のコミットオブジェクトを指すポインタ(ブランチ)が保管されます。HEAD ファイルは、現在チェックアウトしているブランチを指します。index ファイルには、Git がステージングエリアの情報を保管します。 以降の各セクションでは、Git がどのような仕組みで動くのかを詳細に見ていきます。