← 解説「コミットハッシュとtreeの対応 — スナップショットと親への参照」に戻る
サンプルコードで身につける: コミットハッシュとtreeの対応 — スナップショットと親への参照
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
1実際のコミットの中身を見る
commitオブジェクトはただの数行のテキストです。1つ目のコミットには parent 行がなく、2つ目には前のコミットを指す parent 行が付いていることを、実際の出力で確認してください。
# 最初のコミット
$ git cat-file -p 3a72bb1
tree b4b9a853c3ffc746b9f0ce42ad8216540e74206e
author Tanaka <tanaka@example.com> 1700000000 +0900
committer Tanaka <tanaka@example.com> 1700000000 +0900
初期コミット
↑ parent 行がない = 履歴の起点
# 2つ目のコミット
$ git cat-file -p dd2818b
tree 68bd1e3558ff34e67e1301c8eefbbaac3f8aa842
parent 3a72bb1be654931c3afba45c654a7ee444e09206 ← 1つ前を指している
author Tanaka <tanaka@example.com> 1700000100 +0900
committer Tanaka <tanaka@example.com> 1700000100 +0900
READMEに使い方を追加
2コミットのIDを自分で計算して一致させる
commitも「テキストにヘッダを付けてSHA-1」です。実機のコミットと同じ内容を組み立てると、同じハッシュ 3a72bb1… が出ます。ここまで来ると、Gitに魔法が無いことが分かります。
Python
3履歴を親でたどる = git log がしていること
git log は魔法ではなく、HEADから parent を1つずつ辿っているだけです。実際のリポジトリのコミットを使って、その動きを再現します。矢印が必ず「新しい→古い」の一方向であることを確認してください。
Python
4最新のハッシュ1つで履歴全体が確定する
コミットのハッシュは親のハッシュを含んで計算され、その親もさらに親を含んでいます。だから過去を1つ書き換えると、それ以降すべてのハッシュが変わります。実際に途中を改ざんして連鎖を観察します。
Python
5同じ内容でも作者や時刻が違えば別のコミット
「同じファイル内容ならコミットも同じ」ではありません。treeが同じでも、時刻・作者・メッセージ・親が違えばIDは変わります。cherry-pickで同じ変更を持ってきてもハッシュが変わる理由がこれです。
Python