はじめに
前回のgit
の挙動について、今回はその内容を図で確認していく。
最初のgitコマンドを用意する
最初のgit
コマンドをビルドし、`$HOME/bin-git にコピーして、コピーした場所へのPATHを通してあると仮定する。
$ ls $HOME/bin-git
$ cat-file commit-tree init-db read-tree show-diff update-cache write-tree
$ export PATH=$PATH:$HOME/bin-git
$ which cat-file
/$HOME/bin-git/cat-file
確認する内容
下記のコマンド実行によるリポジト内部の変更を逐次確認することでgit
の動作を理解する。
$ init-db # リポジトリの初期化
$ echo "Hello" > README.md # gitで管理するファイルを作成
$ cat README.md # 作成したファイルの内容を確認
Hello
$ update-cache README.md # コミットするファイルをgitに登録
$ write-tree # コミットするためにtreeオブジェクトを作成
5b884d166f3d56691ba080195ca0ceaed25f14b9
$ echo "1st commit" | commit-tree 5b884d166f3d56691ba080195ca0ceaed25f14b9 # コミット
Committing initial tree 5b884d166f3d56691ba080195ca0ceaed25f14b9
79df7b69d49cf4decaee4353d375af5390434041
$ echo "Hello, World" > README.md # ファイル内容を変更
$ show-diff # 変更内容を確認
README.md: 3c510aa6ed4c90af836505a9da8d9d2a0f36c5c9
--- /tmp/show_diff.fKo3Xz 2024-01-03 16:25:16.771067627 +0900
+++ README.md 2024-01-03 16:24:55.966972373 +0900
@@ -1 +1 @@
-Hello
+Hello, World
$ update-cache README.md # コミットするファイルをgitに登録
$ write-tree # コミットするためにtreeオブジェクトを作成
056a16ec6554427cee5f2c087c4a3be4a6022e4b
$ echo "2nd commit" | commit-tree 056a16ec6554427cee5f2c087c4a3be4a6022e4b # コミット
Committing initial tree 056a16ec6554427cee5f2c087c4a3be4a6022e4b
ec74c2dcdcfbf5a576fc63ceece2179dc0a21d3f
リポジトリの初期化
git init
に相当する処理
$ init-db
defaulting to private storage area
.dircache
ディレクトリがリポジトリ用のフォルダとして作成される
git
が管理するオブジェクトは.dircache
フォルダの下のobjects
フォルダの下に配置される。多数のオブジェクトを効率よく管理するため、00
から``ff`の256個のフォルダがさらに用意される。
.dircache/
└── objects
├── 00
├── 01
...
└── ff
ファイルを登録する
git add
に相当する処理を行う。
ワーキングディレクトリにREADME.md
ファイルを作成し、そのファイルをgit
に登録する
$ echo "Hello" > README.md
$ cat README.md
Hello
$ update-cache README.md
指定したファイルをblob
オブジェクトとしてファイルに保存して、そのファイルへの参照をindex
フィルに書き込む
ファイルを登録した後のリポジトリの構成
- [add] objects/3c/510aa6ed4c90af836505a9da8d9d2a0f36c5c9
- [add] index
.dircache/
├── index
└── objects
├── 00
...
├── 3c
│ └── 510aa6ed4c90af836505a9da8d9d2a0f36c5c9
...
└── ff
登録されたREADME.md
ファイルの管理
objects/3c/510aa6ed4c90af836505a9da8d9d2a0f36c5c9
ファイルで管理される。
- ファイルはzlibで圧縮され
blobオブジェクト
として管理される - SHA1ハッシュでの管理方法
-
3c
:ディレクトリ名 -
510aa6ed4c90af836505a9da8d9d2a0f36c5c9
:ファイル名
-
blobオブジェクト
はindex
ファイルで管理される
-
blobオブジェクト
として保存されたREADME.md
ファイルへの参照(SHA1ハッシュ)をindex
に保存する - 登録された
README.md
ファイルにアクセスしたい場合には3c
フォルダの51...c9
ファイルを確認すれば良い
コミットする
git commit
に相当する処理を行う
コミットはtreeオブジェクト
を対象として行う。tree
オブジェクトは1つ以上のblob
オブジェクトへの参照を持つオブジェクトである。
$ write-tree
5b884d166f3d56691ba080195ca0ceaed25f14b9
$ echo "1st commit" | commit-tree 5b884d166f3d56691ba080195ca0ceaed25f14b9
Committing initial tree 5b884d166f3d56691ba080195ca0ceaed25f14b9
79df7b69d49cf4decaee4353d375af5390434041
treeオブジェクト
を作成し、そのtree
オブジェクトを参照するcommitオブジェクト
を作成する。「コミットする」とは、commitオブジェクト
を作成することであり、コミットの内容はcommitオブジェクト
が参照するtreeオブジェクト
が参照するblobオブジェクト
一覧である。
ファイルをコミットした後のリポジトリの構成
- [add] objects/5b/884d166f3d56691ba080195ca0ceaed25f14b9
- [add] objects/79/df7b69d49cf4decaee4353d375af5390434041
.dircache/
├── index
└── objects
├── 00
...
├── 3c
│ └── 510aa6ed4c90af836505a9da8d9d2a0f36c5c9
...
├── 5b
│ └── 884d166f3d56691ba080195ca0ceaed25f14b9
...
├── 79
│ └── df7b69d49cf4decaee4353d375af5390434041
...
└── ff
ファイル変更
ワーキングディレクトリのREADME.md
ファイルを変更する。
$ echo "Hello, World" > README.md
変更点の確認
git diff
に相当する処理を行う
登録されたファイルとワーキングディレクトリのファイルとの差分を表示する。
$ show-diff
README.md: 3c510aa6ed4c90af836505a9da8d9d2a0f36c5c9
--- /tmp/show_diff.fKo3Xz 2024-01-03 16:25:16.771067627 +0900
+++ README.md 2024-01-03 16:24:55.966972373 +0900
@@ -1 +1 @@
-Hello
+Hello, World
index
ファイルに登録されたファイルとワーキングディレクトリのファイルの差分をdiff
コマンドを呼び出して作成して出力する。
変更をコミット
README.md
ファイルの修正をコミットする。
- コミットするファイルを
update-cache
コマンドで登録 - コミットに必要な
treeオブジェクト
をwrite-tree
で作成 - コミット対象の
tree
オブジェクトをSHA1ハッシュで指定してcommitオブジェクト
を作成する
$ update-cache README.md
$ write-tree
056a16ec6554427cee5f2c087c4a3be4a6022e4b
$ echo "2nd commit" | commit-tree 056a16ec6554427cee5f2c087c4a3be4a6022e4b
Committing initial tree 056a16ec6554427cee5f2c087c4a3be4a6022e4b
ec74c2dcdcfbf5a576fc63ceece2179dc0a21d3f
.dircache/
├── index
└── objects
├── 00
..
├── 05
│ └── 6a16ec6554427cee5f2c087c4a3be4a6022e4b : 2nd tree オブジェクト
..
├── 3c
│ └── 510aa6ed4c90af836505a9da8d9d2a0f36c5c9 : 最初の README.md
..
├── 5b
│ └── 884d166f3d56691ba080195ca0ceaed25f14b9 : 1st tree オブジェクト
├── 5c
├── 5d
├── 5e
├── 5f
│ └── 60b55715af0273fd592428a179c59299a0987f : 修正した README.md
├── 60
..
├── 79
│ └── df7b69d49cf4decaee4353d375af5390434041 : 1st commit オブジェクト
..
├── ec
│ └── 74c2dcdcfbf5a576fc63ceece2179dc0a21d3f : 2nd commit オブジェクト
├── ed
└── ff
修正したREADME.mdファイルのblobオブジェクト
を新規に作成し、そのファイルへの参照をindex
ファイルに保存する。index
ファイルはupdate-cache
を呼び出す毎に更新されるため、前回登録したファイルへの参照は消える。
次回
次回は複数のファイルやディレクトリを対象にコミットした場合や、コミットからのリストアについて動作を確認していく。