Latticework

Command Palette

Search for a command to run...

Git

Commits & Branches

18 min

Explanation

Every Git commit points to exactly one parent commit (except the very first commit, and merge commits, which have two) — the whole repository history is a graph built entirely from these parent pointers. A branch isn't a copy of anything; it's just a movable label pointing at one commit.

commits = {
    "c3": "c2",
    "c2": "c1",
    "c1": None,   # the root commit has no parent
}

def commit_history(commits, start):
    history = []
    current = start
    while current is not None:
        history.append(current)
        current = commits.get(current)
    return history

print(commit_history(commits, "c3"))   # ['c3', 'c2', 'c1']
Try it

Creating a commit is just 'add a new dict entry pointing at the old tip, then update the branch label to the new tip' -- there's no copying of history involved, which is exactly why branches in Git are so cheap to create.

Loading editor…
Explanation

Checking whether one commit is an ancestor of another (was it in that commit's history?) is exactly the same kind of graph-walk as the Debugging course's bisection module — follow parent pointers until you either find the target or run out of history:

def is_ancestor(commits, ancestor, descendant):
    current = descendant
    while current is not None:
        if current == ancestor:
            return True
        current = commits.get(current)
    return False

print(is_ancestor(commits, "c1", "c3"))   # True -- c1 is an ancestor of c3
print(is_ancestor(commits, "c3", "c1"))   # False -- c3 came AFTER c1, not before

This is exactly what git merge --ff-only checks before allowing a "fast-forward" merge — if the target branch is already an ancestor of what you're merging in, Git can just move the pointer forward with no actual merge commit needed at all.

Exercise

Model commits as a dict `{commit_id: parent_id}` (the root commit has parent `None`). Write `commit_history(commits, start)`: return the list of commit IDs from `start` back to the root, following parent pointers.

Exercise

Write `is_ancestor(commits, ancestor, descendant)`: return True if `ancestor` appears anywhere in `descendant`'s history (including itself).

Quiz

In Git, what does a branch actually point to?

Checkpoint

You can model a commit history as a parent-pointer graph, walk it to reconstruct history, and check ancestry relationships between commits.