C.W.K.
Stream
Lesson 04 of 05 · published

Commits, Parents, and the DAG

~20 min · dag, commit-graph

Level 0Untracked Rookie
0 XP0/47 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

Commits are nodes; branches are pointers

Once you accept that commits are snapshots, the next move is to see how snapshots connect. Every commit (except the first) records the hash of its parent. Merge commits record two parents. The result is a Directed Acyclic Graph: directed (each link points only to the past), acyclic (you cannot follow links and end up where you started), graph (parallel branches and merges create real graph topology, not just a line).

Picture it. A ← B ← C ← D is a linear chain on main. Now you branch feature at B and add E ← F. The graph forks. When you merge feature back into main, you create a new commit G with two parents — D and F. Future history walks from G can reach all earlier work through either parent. Nothing is deleted; nothing is overwritten. The graph just grows.

Branches and tags are 41-byte files holding a single hash. Creating feature is writing one file. Switching to it changes HEAD to point at it. Deleting it removes the pointer but leaves the commits, which Git's garbage collector will eventually sweep if no other ref points at them. This is the answer to "how is branching so cheap?" — there is almost nothing to copy.

Most powerful Git commands — log, blame, bisect, rebase, cherry-pick — are graph operations. Once you read commands as graph instructions, the names stop feeling random. git log feature..main means "commits reachable from main but not from feature." That is set difference on the DAG.

Code

Visualize the actual DAG of any repo·bash
# ASCII-art graph of all branches
git log --oneline --graph --decorate --all

# Just the last 20 nodes, with author and dates
git log --oneline --graph --decorate --all --pretty='%h %ad %an %d %s' --date=short -n 20

# See the parents of one commit
git cat-file -p HEAD | head -3
Branches and tags are pointers, not folders·bash
# What does main really point to?
cat .git/refs/heads/main

# What about HEAD?
cat .git/HEAD

# All refs at once
git for-each-ref --sort=committerdate \
  --format='%(refname:short) -> %(objectname:short)'

External links

Exercise

In a scratch repo, make four commits on main, then branch feature, add two commits, switch back to main, add one more commit, then merge feature in. Run git log --oneline --graph --decorate --all. Identify which commit has two parents. Then run git log main..feature and explain in one sentence what that range expresses about the graph.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.