編集履歴
- 2024/12/22
-
git cat-file -t
コマンドの実行を追記(後続記事の説明のため)
-
Gitでバージョン管理されたプロジェクトを扱うと、必ず .git
というディレクトリがあります。
このディレクトリを使ってGitがバージョン管理をしているらしい、ということはなんとなく知っています。でも、具体的になにが入っていて、どう管理されているんだろう?
このアドベントカレンダーは、そんな疑問からGitを深堀りしていきます。
.gitの中身を見てみる3(git commit)
では次に、コミットするとどうなるのか確認してみます。
(ディレクトリバックアップのログは割愛)
$ git status # コミット前のステータス確認
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: a.txt
$ git commit -m 'commit test' # コミット実行
[main (root-commit) e452a0a] commit test
Committer: user <user@machine>
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly:
git config --global user.name "Your Name"
git config --global user.email you@example.com
After doing this, you may fix the identity used for this commit with:
git commit --amend --reset-author
1 file changed, 1 insertion(+)
create mode 100644 a.txt
$ git status # コミット後のステータス確認
On branch main
nothing to commit, working tree clean
$
コミット前後で差分を取ってみます。
$ diff -r .git ../git-study-before-commit/.git
.git のみに存在: COMMIT_EDITMSG
バイナリーファイル .git/index と../git-study-before-commit/.git/index は異なります
.git のみに存在: logs
.git/objects のみに存在: 58
.git/objects のみに存在: e4
.git/refs/heads のみに存在: main
$
差分が6つでてきました。
それぞれ確認します。
差分1(.git/COMMIT_EDITMSG)
$ ls -l .git/COMMIT_EDITMSG
-rw-r--r-- 1 user group 12 12月 4 23:14 .git/COMMIT_EDITMSG
$ cat .git/COMMIT_EDITMSG
commit test
$
コミットメッセージがそのまま入っていました。
差分2(.git/index)
index
ファイルの中身はバイナリなので、以前と同様に git ls-files
コマンドを使っていきます。
コミット前
$ git ls-files --stage
100644 9daeafb9864cf43055ae93beb0afd6c7d144bfa4 0 a.txt
$
コミット後
$ git ls-files --stage
100644 9daeafb9864cf43055ae93beb0afd6c7d144bfa4 0 a.txt
$
差分がない…。
これは別途調べたいと思います。
差分3(.git/logs)
.git/logs
はディレクトリだったので、 ls -lR
で確認します。
$ ls -lR .git/logs
.git/logs:
合計 4
-rw-r--r-- 1 user group 157 12月 4 23:14 HEAD
drwxr-xr-x 1 user group 10 12月 4 23:14 refs
.git/logs/refs:
合計 0
drwxr-xr-x 1 user group 8 12月 4 23:14 heads
.git/logs/refs/heads:
合計 4
-rw-r--r-- 1 user group 157 12月 4 23:14 main
$
下記2つのファイルがあるようです。
- .git/logs/HEAD
- .git/logs/refs/heads/main
$ cat .git/logs/HEAD
0000000000000000000000000000000000000000 e452a0a52250236a24d1f63dd7e7fbb84d6e55c5 user <user@machine> 1733321663 +0900 commit (initial): commit test
$ cat .git/logs/refs/heads/main
0000000000000000000000000000000000000000 e452a0a52250236a24d1f63dd7e7fbb84d6e55c5 user <user@machine> 1733321663 +0900 commit (initial): commit test
$ diff .git/logs/HEAD .git/logs/refs/heads/main
$
中身を見ると、同じ文言が入っていました。
コミットが1つしかないからってことでしょうか?
複数回コミットしたらどうなるのかが気になります。
差分4,5(.git/objects/58, .git/objects/e4)
オブジェクトファイルを2つ同時に確認します。
オブジェクトファイルもバイナリなので、 git cat-file
コマンドを利用します。
まず、ハッシュ値全体を確認します。
$ ls -lR .git/objects/58
.git/objects/58:
合計 4
-r--r--r-- 1 user group 52 12月 4 23:14 c608a3fa830548019591fc45f307554ca9a57f
$ ls -lR .git/objects/e4
.git/objects/e4:
合計 4
-r--r--r-- 1 user group 117 12月 4 23:14 52a0a52250236a24d1f63dd7e7fbb84d6e55c5
$
58c608a3fa830548019591fc45f307554ca9a57f
のほうは、git ls-files --stage
の結果と似た結果が表示されました。
$ git cat-file -t 58c608a3fa830548019591fc45f307554ca9a57f
tree
$ git cat-file -p 58c608a3fa830548019591fc45f307554ca9a57f
100644 blob 9daeafb9864cf43055ae93beb0afd6c7d144bfa4 a.txt
$
(再掲)
$ git ls-files --stage
100644 9daeafb9864cf43055ae93beb0afd6c7d144bfa4 0 a.txt
$
e452a0a52250236a24d1f63dd7e7fbb84d6e55c5
のほうは、ログっぽいです。
$ git cat-file -t e452a0a52250236a24d1f63dd7e7fbb84d6e55c5
commit
$ git cat-file -p e452a0a52250236a24d1f63dd7e7fbb84d6e55c5
tree 58c608a3fa830548019591fc45f307554ca9a57f
author user <user@machine> 1733321663 +0900
committer user <user@machine> 1733321663 +0900
commit test
$
差分6(.git/refs/heads/main)
$ ls -l .git/refs/heads/main
-rw-r--r-- 1 user group 41 12月 4 23:14 .git/refs/heads/main
$ cat .git/refs/heads/main
e452a0a52250236a24d1f63dd7e7fbb84d6e55c5
$
またハッシュ値が出てきました。
これは、今回新しく作成されたオブジェクトファイルと同じハッシュ値ですね。
関連があるようです。
本日はここまで。
参考書籍・参考資料
- エンジニアのためのGitの教科書[上級編] Git内部の仕組みを理解する
- git 公式ドキュメント