Terminus Expanse
CurriculumBlogPricingSign in
Back to dispatches
guidesgitAug 16, 2026

Git explained: what a commit, branch, and merge actually are under the hood

Terminus Expanse

The one-sentence version

Git doesn't store a list of changes to your files — it stores complete snapshots of your entire project at each commit, and the "magic" is that it's smart enough to store nearly identical snapshots incredibly cheaply, by only actually saving what's different.

What a commit actually is

A commit is a snapshot plus metadata: who made it, when, a message, and — critically — a pointer to the commit that came right before it. That last part is the whole trick. Because every commit points to its parent, the entire history of your project is really just a chain of snapshots linked backward in time. Git doesn't need a separate "history" file; the history is just following the pointers.

What a branch actually is (it's not what people picture)

Most people picture a branch as a separate copy of the whole project. It isn't. A branch is a single, tiny, movable label — a few bytes — that just points at one commit in that chain. Creating a branch doesn't copy anything; it just adds a new label pointing at wherever you currently are. When you make a new commit while on that branch, the label automatically moves forward to point at the new commit. That's why creating a branch in Git is instant even on an enormous repository — you're not duplicating gigabytes of files, you're writing a few bytes.

What a merge actually does

Say branch A and branch B both started from commit X and diverged from there. A merge finds that shared ancestor (X), looks at what changed on A since X and what changed on B since X, and combines both sets of changes into one new commit with two parents instead of one. If the two branches changed different lines, Git combines them automatically. If they changed the same line differently, Git can't guess which one you want — that's a merge conflict, and it isn't Git being broken, it's Git correctly refusing to silently pick a winner on your behalf.

What people get wrong

"git pull and git fetch are basically the same thing" — they aren't. Fetch downloads the latest history from the remote and stops there, leaving your own branch completely untouched so you can look before deciding anything. Pull does that same fetch and then immediately tries to merge it into your current branch. Fetch is the safe, look-first version; pull is fetch-plus-merge in a single step, which is exactly why it can surprise you with an unexpected merge you didn't ask for.

One caveat worth knowing

Nothing in Git is really deleted the moment you think it is. Even after you "delete" a branch, the commits it pointed to usually still exist in the repository for a while — Git only cleans up truly unreferenced commits after some time has passed. That's exactly why recovering an "accidentally deleted" branch is very often still possible with git reflog, which is worth knowing exists before you panic over a bad git branch -D.

This post is about