[git] Gitの内部(はじめに)
こんにちは、@yoheiMuneです。
最近Pro Gitという本を読んでいます。 今日は、その本から学んだgitの内部について、はじめの部分をブログに書きたいと思います。
gitは、連想記憶ファイルシステム(content-addressable filesystem)上に構築されたバージョン管理システムである、という点を理解しておく必要があります。この点は他のバージョン管理システム(SVNなど)とは異なる点で、gitの大きな特徴です。
SVNなどのバージョン管理では、1つのファイルはコミットごとにコミット前後の差分を保持します。しかしGitでは、特定のファイルの特定のリビジョンに対してハッシュ値を生成し、そのハッシュ値を用いてその時のファイルにダイレクトにアクセスすることができます。
gitのバージョン1.5より前では、このファイルシステムという考えが押し出されていたため、少し複雑で使いづらいUIとなっていたようです。 しかし最近では、gitのUIは再定義され、使い勝手は少し改善されました。
この連想記憶ファイルシステムという仕組みについては、次回以降に詳しく取り上げたいと思います。 今回のブログでは、それを説明する前段となる部分を解説します。
gitの内部を知るためには、それらの内部コマンドを利用することになります。 gitの内部コマンドを使うことで、Gitの中で何がどのように動作しているのかを知る手助けとなります。 それぞれの内部コマンドは、必要な場面でそれぞれ説明できればと思います。
それではさっそく、先ほど作成したレポジトリの
これらの中で特に重要なものは、
なお、上記以外にも以下の要素が
Pro Git | git-scm.com/book
最後までご覧頂きましてありがとうございました。
最近Pro Gitという本を読んでいます。 今日は、その本から学んだgitの内部について、はじめの部分をブログに書きたいと思います。
Special Thanks to http://flic.kr/p/aWTB1r
Gitの内部を学ぶことの意義
Gitの内部構造や実装を学ぶことで、Gitがどのように動作しているかを理解することができ、その結果としてより便利に強力にGitを使えるようになります。 Gitの内部を学習する意義は、この点が一番大きいですね。gitは、連想記憶ファイルシステム(content-addressable filesystem)上に構築されたバージョン管理システムである、という点を理解しておく必要があります。この点は他のバージョン管理システム(SVNなど)とは異なる点で、gitの大きな特徴です。
SVNなどのバージョン管理では、1つのファイルはコミットごとにコミット前後の差分を保持します。しかしGitでは、特定のファイルの特定のリビジョンに対してハッシュ値を生成し、そのハッシュ値を用いてその時のファイルにダイレクトにアクセスすることができます。
gitのバージョン1.5より前では、このファイルシステムという考えが押し出されていたため、少し複雑で使いづらいUIとなっていたようです。 しかし最近では、gitのUIは再定義され、使い勝手は少し改善されました。
この連想記憶ファイルシステムという仕組みについては、次回以降に詳しく取り上げたいと思います。 今回のブログでは、それを説明する前段となる部分を解説します。
一般的なUIと内部的なUI
Gitには、一般的に利用される機能(pull, commit, add, push, branch,など)がたくさん存在します。git help
を使って、どのようなコマンドがあるかを調べることができます。$ git help The most commonly used git commands are: add Add file contents to the index bisect Find by binary search the change that introduced a bug branch List, create, or delete branches checkout Checkout a branch or paths to the working tree clone Clone a repository into a new directory commit Record changes to the repository diff Show changes between commits, commit and working tree, etc fetch Download objects and refs from another repository grep Print lines matching a pattern init Create an empty Git repository or reinitialize an existing one log Show commit logs merge Join two or more development histories together mv Move or rename a file, a directory, or a symlink pull Fetch from and merge with another repository or a local branch push Update remote refs along with associated objects rebase Forward-port local commits to the updated upstream head reset Reset current HEAD to the specified state rm Remove files from the working tree and from the index show Show various types of objects status Show the working tree status tag Create, list, delete or verify a tag object signed with GPGそして上記の一般的に良く利用する機能以外にも、様々な内部コマンド(=下位レベルのコマンド)が存在します。 例えば、
git hash-object
、git cat-file
、git write-tree
などです。gitの内部を知るためには、それらの内部コマンドを利用することになります。 gitの内部コマンドを使うことで、Gitの中で何がどのように動作しているのかを知る手助けとなります。 それぞれの内部コマンドは、必要な場面でそれぞれ説明できればと思います。
gitレポジトリの構造
ここでは、gitレポジトリの構造について説明します。 まずは、git init
コマンドでレポジトリを新規作成してみましょう。$ git init Initialized empty Git repository in /Users/munesadayohei/tmp/test/.git/
git init
を実行すると、.git
ディレクトリが作成されました。
この.git
ディレクトリは、Gitにおいてコアとなる存在なのです。
例えばgitレポジトリをバックアップしたりクローンしたい場合には、この1つのディレクトリをどこか違うディレクトリにコピーすれば、
必要なことのほとんど全てができてしまいます。
Gitの内部構造を知るために、以降ではこの.git
ディレクトリを中心に扱っていきたいと思います。それではさっそく、先ほど作成したレポジトリの
.git
の中を見てみましょう。$ ls .git HEAD branches/ config description hooks/ index # もしかしたらこれは最初は無いかも info/ objects/ refs/
.git
ディレクトリは、上記のファイルやディレクトリで構成されています。
既に利用中のレポジトリの場合には、他にもいくつかのファイルが存在するかもしれません。これらの中で特に重要なものは、
HEAD
ファイル、index
ファイル、objects
ディレクトリ、refs
ディレクトリです。それぞれの構成要素の役割は、以下の通りです。
objects
- このディレクトリは、gitレポジトリの実際のデータ(プログラムファイルや画像など)を全て保管しています。
refs
- このディレクトリは、データ(やブランチ)内のコミットオブジェクトを指すポインターを保持します。
HEAD
- このファイルは、チェックアウトしているブランチを指し示します。
index
- このファイルは、Gitがステージングエリアの情報を保持する場所です。
なお、上記以外にも以下の要素が
.git
には含まれます。config
- このファイルは、プロジェクト固有の設定内容(リモート先やサブモジュールなど)の情報を保持します。
description
- このファイルは、GitWebプログラムで利用されるファイルです。
info
- このディレクトリは、
.gitignore
には書きたくないような追跡除外パターンを書くための、グローバルレベルの除外設定ファイルを保持します。 hooks
- このディレクトリは、クライアントサイドやサーバーサイドで利用するフックスクリプトを保持します。
参考資料
Gitの内部挙動を理解するために、以下の資料を参照しました。ありがとうございます。Pro Git | git-scm.com/book
最後に
今回は、gitの内部についてのはじめの部分を扱いました。.git
ディレクトリがGitではキーとなる要素なんですね。
次は、バージョン管理で保管されている対象そのものであるobjectについて、見ていければと思います。最後までご覧頂きましてありがとうございました。