Commit Anatomy
Commit Anatomy
After this page you can read a commit object and say what each field is for.
A commit is a snapshot plus metadata
cd ~/desk/desk-api
git cat-file -p HEADYou will see something like:
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
parent 9fceb02d0ae598e95dc970b74767f19372d61af8
author Ada Desk <ada@example.com> 1774000000 +0530
committer Ada Desk <ada@example.com> 1774000000 +0530
Document the ping endpoint in README
| Field | Meaning |
|---|---|
tree |
Hash of the directory snapshot this commit names |
parent |
Previous commit (omitted on the first commit; two lines on a merge) |
author |
Who wrote the patch, plus timestamp |
committer |
Who created this commit object, plus timestamp |
| blank line, then body | The message |
The name of the commit is the hash of this object. Change the message, the tree, or a parent → new hash. That is why amend and rebase rewrite history: they write new objects.
Short names
git rev-parse HEAD
git rev-parse HEAD~1 # first parent, one step back
git rev-parse HEAD^ # same as HEAD~1 on a non-merge
git rev-parse --short HEAD # abbreviated, unique in this repoOn a merge commit, HEAD^1 is the first parent (the branch you were on) and HEAD^2 is the branch you merged in. HEAD~n walks first-parent only. Chapter 10 uses that when reverting a merge.
The tree under it
git ls-tree -r HEADEach line is a mode, type, hash, and path. Blobs have no filename inside them; the tree supplies the name. Two commits that share an unchanged src/ping.py share the same blob hash.
What git show adds
git show HEAD
git show --stat HEAD
git show --name-only HEADgit show pretty-prints the commit and, by default, the diff against its first parent. That diff is computed; Git stored the tree, not the patch.
Next page: how to write the message so later git log and automation can parse it.