An Architect’s guide to understanding what actually happens inside Git when you branch, merge, and rebase — without magic or myths.
The Git Internals
- Git Internals Explained Simply – How Git Stores Data
- Advanced Git Internals – How Git Scales to Massive Repositories
Now, we focus on
- How Git branching works internally
- What really happens during a merge
- How rebase rewrites history
- When to use merge vs rebase at scale
The Biggest Git Myth- Branches Are Copies
One of the most common misunderstandings: “A Git branch is a copy of the code.”
Reality: A branch is just a movable pointer to a commit.
Internally, a branch is a simple file
.git/refs/heads/main
Containing
<commit-hash>
That’s it. No duplication. No magic.
Branch Creation – What Actually Happens
When you run
git branch feature-x
Git
- Creates a new reference
refs/heads/feature-x - Points it to the same commit as the current branch
No objects are created. No files are copied.
This is why Git branching is fast — even in massive repositories.
HEAD Revisited: The Key to Understanding History
HEAD is Git’s way of saying “This is where you are right now.”
Usually : HEAD → refs/heads/main
Detached HEAD : HEAD → <commit-hash>
Every branch switch updates HEAD. Every commit moves the branch pointer.
Commit Graph – Git Is a DAG
Git history forms a Directed Acyclic Graph (DAG):
- Nodes → commits
- Edges → parent relationships
Branches are just labels on nodes in this graph.
Visualize it as:
A---B---C (main) \ D---E (feature-x)
Merge Internals – Combining Histories
When you merge a branch
git merge feature-x
Git:
- Finds the lowest common ancestor (merge base)
- Computes changes from base → branch A
- Computes changes from base → branch B
- Combines the results
This is a three-way merge.
Fast-Forward Merges
If the target branch has not diverged
A---B---C (main) \ D---E (feature-x)
Git simply moves the pointer
main → E
No merge commit is created.
True Merge Commits
When histories diverge
A---B---C---F (main) \ D---E (feature-x)
Git creates a merge commit
M
/ \
A---B---C---F
\
D---E
This commit has two parents.
Merge Conflicts: Why They Happen
Conflicts occur when
- The same lines change differently
- Git cannot auto-resolve intent
Important : Git never guesses. Humans decide.
Understanding merge bases helps you resolve conflicts calmly.
Rebase Internals – Rewriting History
Rebase answers a different question “What if my commits were based on the latest main branch?”
Command
git rebase main
Internally, Git
- Finds the common ancestor
- Temporarily removes your commits
- Replays them one by one on top of
main - Creates new commit objects
Old commits are abandoned.
Why Rebase Changes Commit Hashes
Commits include
- Parent commit hash
- Timestamp
When rebased
- Parent changes
- Hash changes
Same code, different history. This is why rebasing shared branches is dangerous.
Merge vs Rebase – Architectural Trade-offs
| Aspect | Merge | Rebase |
|---|---|---|
| History | Preserves | Rewrites |
| Safety | Very safe | Risky on shared branches |
| Graph | Explicit | Linear |
| CI/Audit | Excellent | Requires discipline |
Enterprise Best Practices
From large-scale teams:
- Use merge commits on shared branches
- Allow rebase on local feature branches
- Never rebase
mainorrelease - Prefer fast-forward merges for clean histories
Reflog – Your Safety Net
Even after rebases
git reflog
Shows where HEAD used to point. Most “lost commits” are recoverable.
Git Branching as Distributed Systems Design
Git branching reflects
- Immutable data
- Append-only history
- Cheap metadata operations
- Explicit conflict resolution
These are the same principles used in
- Event sourcing
- Distributed logs
- Versioned data stores
Git branching, merging, and rebasing are not commands — they are graph transformations.
Once you see the graph, Git stops being scary and starts being precise.
Recap
Git Internals: A Complete Guide for Engineers
- Part 1: How Git Stores Data
- Part 2: How Git Scales with Packfiles & Compression
- Part 3: Git Branching, Merging & Rebase Internals
- Part 4: Git Internals for CI/CD, Mono-Repos
- Part 5: Git Security Internals
In the next, we’ll explore Git internals for CI/CD, mono-repos, and large organizations
Frequently Asked Questions (FAQ)
Internally, a Git branch is just a pointer to a commit. It does not copy files or history. When new commits are added, the branch pointer moves forward.
Git merge combines two commit histories by creating a new commit with multiple parent commits, preserving both branches in the commit graph.
Git rebase replays commits from one branch onto another by creating new commits with new hashes, effectively rewriting history.
Rebase is safe for local or private branches. It becomes risky when used on shared branches because it rewrites commit history.
Merge preserves full history with a merge commit, while rebase creates a linear history by rewriting commits. Both have valid use cases.
The commit graph allows Git to track history efficiently, support branching and merging, and detect relationships between commits quickly.