チャプター ▾ 第2版

1.3 始める前に - Git とは?

Gitとは?

では、Gitとは一言で言えば何なのでしょうか?このセクションは非常に重要です。なぜなら、Gitが何であるか、そしてその動作原理を理解すれば、Gitを効果的に使うことがずっと容易になるからです。Gitを学ぶ際には、CVS、Subversion、Perforceのような他のVCSについて知っていることを一旦頭の中から消し去るように努めてください。そうすることで、ツールを使う際に微妙な混乱を避けることができます。Gitのユーザーインターフェースは他のVCSとかなり似ていますが、Gitは情報を非常に異なる方法で保存し、考えています。これらの違いを理解することが、混乱することなくGitを使う上で役立ちます。

スナップショットであって差分ではない

Gitと他のVCS(Subversionなど)との最大の違いは、Gitがデータを考える方法にあります。概念的に、他のほとんどのシステムは、ファイルをベースとした変更のリストとして情報を保存します。これらの他のシステム(CVS、Subversion、Perforceなど)は、保存する情報を、一連のファイルと、各ファイルに加えられた時間の経過に伴う変更として考えます(これは一般的に「デルタベースのバージョン管理」と表現されます)。

Storing data as changes to a base version of each file
図4. 各ファイルのベースバージョンへの変更としてデータを保存する

Gitは、このようにデータを考えたり保存したりしません。代わりに、Gitはデータをミニチュアファイルシステムの一連のスナップショットのように考えます。Gitでは、コミットするたびに、つまりプロジェクトの状態を保存するたびに、Gitは基本的にその時点のすべてのファイルの状態を写真に撮り、そのスナップショットへの参照を保存します。効率化のために、ファイルが変更されていない場合、Gitはファイルを再度保存せず、すでに保存されている以前の同一ファイルへのリンクのみを保存します。Gitはデータを「スナップショットのストリーム」のように考えています。

Git stores data as snapshots of the project over time
図5. 時系列でプロジェクトのスナップショットとしてデータを保存する

これはGitと他のほとんどすべてのVCSとの重要な区別です。これによりGitは、ほとんどの他のシステムが前の世代からコピーしてきたバージョン管理のほぼすべての側面を再考しています。これによりGitは、単なるVCSというよりも、その上に信じられないほど強力なツールが構築されたミニファイルシステムのようなものになっています。この方法でデータを考えることによって得られる利点のいくつかについては、Gitのブランチ機能でGitのブランチについて説明する際に探ります。

ほとんどの操作はローカル

Gitのほとんどの操作は、ローカルファイルとリソースのみで動作します。通常、ネットワーク上の他のコンピューターからの情報は必要ありません。ほとんどの操作にネットワーク遅延オーバーヘッドがあるCVCSに慣れている場合、このGitの側面は、スピードの神々がGitに超常的な力を与えたと思わせるでしょう。プロジェクトの完全な履歴がすべてローカルディスク上にあるため、ほとんどの操作はほぼ瞬時に行われるように感じられます。

たとえば、プロジェクトの履歴を参照するために、Gitはサーバーにアクセスして履歴を取得して表示する必要はありません。ローカルデータベースから直接読み取るだけです。これは、プロジェクト履歴がほぼ瞬時に表示されることを意味します。ファイルの現在のバージョンと1ヶ月前のファイルの間に導入された変更を見たい場合、Gitは1ヶ月前のファイルを検索し、ローカルで差分計算を行うことができます。リモートサーバーに計算を依頼したり、古いバージョンのファイルをリモートサーバーからプルしてローカルで計算したりする必要はありません。

これはまた、オフラインやVPNが使えない状況でも、ほとんどの作業ができることを意味します。飛行機や電車に乗って少し作業をしたい場合でも、ネットワークに接続してアップロードできるようになるまで、安心してコミットできます(ローカルコピーに、ですよ?)。家に帰ってVPNクライアントがうまく動作しない場合でも、作業を続けることができます。他の多くのシステムでは、このようなことは不可能か、非常に苦痛です。たとえばPerforceでは、サーバーに接続していないとほとんど何もできません。SubversionやCVSではファイルを編集できますが、データベースにコミットすることはできません(データベースがオフラインのため)。これは大したことではないように思えるかもしれませんが、それがどれほど大きな違いを生むかを知れば驚くかもしれません。

Gitには整合性がある

Git内のすべてのデータは、保存される前にチェックサムが計算され、そのチェックサムによって参照されます。これは、Gitに知られずにファイルやディレクトリの内容を変更することは不可能であることを意味します。この機能はGitの最も低いレベルに組み込まれており、その哲学の不可欠な部分です。転送中に情報が失われたり、ファイルの破損が発生しても、Gitはそれを検出することができます。

Gitがこのチェックサムのために使用するメカニズムは、SHA-1ハッシュと呼ばれます。これは16進文字(0-9およびa-f)で構成される40文字の文字列で、Git内のファイルまたはディレクトリ構造の内容に基づいて計算されます。SHA-1ハッシュは次のような形をしています。

24b9da6552252987aa493b52f8696cd6d3b00373

Gitではこれらのハッシュ値が非常に頻繁に使用されるため、あちこちで目にすることになるでしょう。実際、Gitはデータベース内のすべてをファイル名ではなく、その内容のハッシュ値で保存しています。

Gitは一般的にデータ追加のみ

Gitでアクションを実行する際、そのほとんどはGitデータベースにデータを「追加」するだけです。システムに元に戻せないようなことや、データを消去するようなことをさせるのは困難です。他のVCSと同様に、まだコミットしていない変更を失ったり台無しにしたりすることはありますが、Gitにスナップショットをコミットしてしまえば、それを失うことは非常に困難です。特に、定期的にデータベースを別のリポジトリにプッシュしている場合はなおさらです。

これにより、Gitを使うのは楽しいものになります。なぜなら、私たちは物事をひどく台無しにする危険なしに実験できると知っているからです。Gitがどのようにデータを保存し、失われたように見えるデータをどのように回復できるかについて、より詳しく知りたい場合は、元に戻すを参照してください。

3つの状態

さあ、ここがスムーズに学習を進める上でGitについて覚えておくべき主要な点です。Gitには、ファイルが存在できる3つの主要な状態があります。「変更済み (modified)」、「ステージ済み (staged)」、そして「コミット済み (committed)」です。

  • 変更済み (Modified) とは、ファイルを変更したが、まだデータベースにコミットしていない状態を意味します。

  • ステージ済み (Staged) とは、現在のバージョンの変更済みファイルに、次のコミットスナップショットに含めるようマークした状態を意味します。

  • コミット済み (Committed) とは、データがローカルデータベースに安全に保存されている状態を意味します。

これにより、Gitプロジェクトの3つの主要なセクションにたどり着きます:ワーキングツリー、ステージングエリア、そしてGitディレクトリです。

Working tree, staging area, and Git directory
図6. ワーキングツリー、ステージングエリア、Gitディレクトリ

ワーキングツリーとは、プロジェクトのあるバージョンの単一のチェックアウトです。これらのファイルは、Gitディレクトリ内の圧縮されたデータベースから取り出され、使用または変更するためにディスクに配置されます。

ステージングエリアは、通常Gitディレクトリ内に含まれるファイルで、次のコミットに何が含まれるかについての情報を格納します。Git用語では「インデックス」という技術的な名前ですが、「ステージングエリア」というフレーズでも同様に通用します。

Gitディレクトリは、Gitがプロジェクトのメタデータとオブジェクトデータベースを保存する場所です。これはGitの最も重要な部分であり、別のコンピュータからリポジトリを「クローン」する際にコピーされるものです。

基本的なGitのワークフローは次のようになります。

  1. ワーキングツリーでファイルを変更します。

  2. 次のコミットの一部としたい変更だけを選択的にステージングします。これにより、それらの変更「のみ」がステージングエリアに追加されます。

  3. コミットを実行します。これは、ステージングエリアにあるファイルをそのまま取得し、そのスナップショットをGitディレクトリに永続的に保存します。

ファイルの特定のバージョンがGitディレクトリにある場合、それは「コミット済み」と見なされます。変更されてステージングエリアに追加された場合、それは「ステージ済み」です。チェックアウトされてから変更されたがまだステージングされていない場合、それは「変更済み」です。Gitの基本では、これらの状態について、そしてそれらを活用したり、ステージング部分を完全にスキップしたりする方法についてさらに詳しく学びます。

scroll-to-top