Gitはデータをスナップショットとして保存する
- 変更されたファイルの内容全体を保存する
- 前のデータとの差分を保存しているわけではない
スナップショットを保存することのメリット
- 頻繁に行われる基本的な操作が劇的に高速化する
- 変更同士で差分を取る操作
- 変更をマージする操作
- ブランチに関する操作
- 新規にブランチを切る操作
- ブランチを切り替える操作
- 堅牢なデータ管理が実現できる
- コミット同士が疎結合になる
- 「前のコミットの内容がないと、あるコミットの内容を復元できない」という事態が発生しない
スナップショットを保存することのデメリット
- 巨大なファイルを扱う場合、リポジトリが肥大化しやすい
- 特に圧縮済みバイナリファイルの管理には全く向かない
Gitリポジトリを構成する要素
blob
- 管理対象ファイルの内容そのものを指す実体
git add
コマンドの実行により、リポジトリ上に生成される- 生の内容そのものではなく、圧縮された上で保管される
- 既に圧縮済みのバイナリファイルを管理対象とした場合、みるみるうちにリポジトリが肥大化していく
- blobにはファイル名の情報は含まれない
tree
- ディレクトリ構造全体のうち、変更が加えられた部分のスナップショットを表す実体
- 一つのtreeの構成要素
- ファイル名と対応するblobの組
- サブディレクトリ名と対応するtreeの組
- 変更が加えられていない部分を取得するためには、前のスナップショットを順次参照していく
- 一つのtreeの構成要素
git commit
コマンドの実行により、リポジトリ上に生成される- その内容は、
git add
コマンドによりステージングエリアに生成されたindexの内容に基づいて定義される
- その内容は、
- 有効なtreeの条件
- 有効なtreeは、blobまたは別のtreeを1つ以上参照していなければならない
- treeチェーンがループすることはありえない
- treeチェーンの末端にはblobが必要となる
- 「空ディレクトリ」はGitでは管理できない
- 上記の条件から導かれる
commit
- コミットそのものの情報を表す実体
- 誰がコミットしたか
- いつコミットしたか
- 1つ前のコミット
- イニシャルコミットに1つ前のコミットは存在しない
- 通常のコミットの場合、1つ前のコミットは1つのみ存在する
- マージコミットの場合、1つ前のコミットは2つ以上存在する
- コミットメッセージ
git commit
コマンドの実行により、treeと同時にリポジトリ上に生成される- branchやtagは、それぞれ1つのcommitに紐づけされる
- branchであっても、枝全体を指すわけではない
- branchが指すcommitはあとから変更することができる
- tagが指すcommitをあとから変更することはできない
ローカルマシンにおける、Gitに関する実体
ローカルリポジトリ
- 管理対象文書群のスナップショットそのものを記録していく領域
- 上記blob、tree、commitを主な内容とする
- branchやHEADもローカルリポジトリを構成する主体である
ステージングエリア
- ひとまとめとしてコミット処理を行いたい一連の変更をひとまとめにするための領域
index
- ステージングエリアに存在する実体
- 「ファイルパスと対応するblobの組」をひとまとめにしたもの
git commit
を行うと、indexの内容から新たなtree群がローカルリポジトリに記録される