Git
章 ▾ 第2版

1.3 はじめに - Git とは何ですか?

Git とは何ですか?

簡単に言うと、Git とは何でしょうか?このセクションはしっかりと理解することが重要です。なぜなら、Git とは何で、どのように動作するのかの基本を理解すれば、Git を効果的に使用することがはるかに容易になるからです。Git を学習する際には、CVS、Subversion、Perforce などの他の VCS について知っていることを一旦忘れましょう。そうすることで、ツールを使用する際の微妙な混乱を避けることができます。Git のユーザーインターフェースはこれらの他の VCS とかなり似ていますが、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について覚えておくべき最も重要なことは、ファイルが存在できる状態が3つあるということです。変更済みステージング済みコミット済みです。

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

  • ステージング済みとは、変更されたファイルを現在のバージョンでマークし、次のコミットスナップショットに含めることを意味します。

  • コミット済みとは、データがローカルデータベースに安全に保存されたことを意味します。

これにより、Gitプロジェクトの3つの主要なセクション、作業ツリー、ステージングエリア、Gitディレクトリについて説明します。

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

作業ツリーは、プロジェクトの1つのバージョンの単一チェックアウトです。これらのファイルは、Gitディレクトリの圧縮されたデータベースから取り出され、ディスクに配置されて使用または変更できます。

ステージングエリアは、一般的にGitディレクトリに含まれるファイルであり、次のコミットに含める情報が格納されます。Git用語での正式名称は「インデックス」ですが、「ステージングエリア」という表現でも問題ありません。

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

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

  1. 作業ツリー内のファイルを編集します。

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

  3. コミットを実行すると、ステージングエリアにあるファイルがGitディレクトリに永続的に保存されます。

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

scroll-to-top