Part III: Chapter 3.5

git log

Time Travel

When you want to see the history of your project, you type git log. But Git doesn't store a global "list of commits" in a database table. So how does it generate this history? It relies entirely on the Linked List architecture of Commit Objects.

Graph Traversal

Click $ git log below to watch Git start at HEAD and walk backwards through time.

Commit Graph

Commit
9f8a357
Commit
1b2c3d4
Commit
5e6f7g8
Commit
c4d5e89
HEAD

Terminal Output

$ git log

The Starting Point

Git always starts the log traversal at exactly one place: the HEAD pointer. It opens the `.git/HEAD` file, finds out what branch you are on, and then opens that branch's reference file to get the exact Commit Hash.

It prints that commit to your terminal. Then it asks one simple question: "What is the parent hash of this commit?"

Following the Pointers

Because every Commit Object stores the hash of the commit that came right before it, Git just opens the parent commit, prints it, and repeats the process.

It walks backwards, hand-over-hand, until it finds a commit that has no parent (the initial commit). This is why if a commit gets disconnected from the graph (like a Detached HEAD), it completely disappears from git log!

Proving the Architecture

We can see this in action by inspecting raw commit objects. Note the `parent` line.

Terminal
$git cat-file -p HEAD
tree t9x2a5...
parent a1b2c3...
author Badu <badu@git.com> 1777265969 -0700
committer Badu <badu@git.com> 1777265969 -0700
Fix layout bug
$# Now Git automatically repeats the command on the parent hash:
$git cat-file -p a1b2c3
tree r3b4c5...
parent 1b2c3d...
...