Chapter 06Lesson 01~70 minutes

Branches, Fast-Forward and Three-Way Merges, and Branching Strategies: Concepts, Architecture, and Mental Model

Build a graph-first mental model of branch refs, HEAD movement, divergence, merge bases, fast-forward updates, true merge commits, conflicts, safe branch deletion, and practical branching strategies.

BranchesMerge basesFast-forwardThree-way merge

Learning objectives

  • Explain local branches as movable refs and HEAD as the current branch attachment.
  • Use reachability and merge bases to predict whether a merge can fast-forward.
  • Distinguish fast-forward ref movement from a true two-parent merge commit.
  • Explain the three conceptual inputs of a merge and why conflicts require human intent.
  • Compare trunk-based, short-lived feature, release, and Git Flow-style policies as operational tradeoffs.

1. The practical problem — parallel work creates a graph, whether your policy admits it or not

Chapter 03 established that branches are refs pointing at commit objects. Chapter 05 taught you to interrogate commit reachability and parent relationships. The next operational question is what happens when two lines of work move independently and then need to become one deployable history.

Teams often learn branch commands as folder-like operations—“copy main, work there, merge it back.” That metaphor breaks as soon as histories diverge. A branch is a movable name. Switching branches changes which commit HEAD is attached to and updates the index and working tree accordingly. Merging is a graph operation that either moves a ref forward or creates a new commit with multiple parents.

2. Branch refs and HEAD movement

A local branch such as trunk is normally stored under refs/heads/trunk. In ordinary branch work, HEAD symbolically names that branch. A new commit advances the current branch ref to the new commit; the commit does not contain a branch name.

git branch --show-current
git symbolic-ref HEAD
git show-ref --heads
git rev-parse HEAD

These read-only commands separate the naming layer from the commit graph. If trunk and feature/api both point at the same commit, creating the second branch has not duplicated any files or commits.

3. Divergence and reachability

Two branches diverge when each tip reaches commits the other tip cannot reach. Their most useful shared reference point is a merge base: a best common ancestor used as the base input for a three-way merge.

git merge-base trunk feature/api
git merge-base --is-ancestor trunk feature/api
git log --graph --decorate --oneline --all

The --is-ancestor form gives an especially direct answer to “can this ref be fast-forwarded to that one?”: if the current tip is an ancestor of the incoming tip, no divergent current-branch commits need preserving in a merge commit.

4. Fast-forward versus true merge

Two different integration shapes
flowchart LR
A[commit A] --> B[commit B]
B --> F[feature commit F]
T1[trunk ref before] -. points to .-> B
T2[trunk ref after fast-forward] -. moves to .-> F

M[merge base M] --> L[trunk-only L]
M --> R[feature-only R]
L --> C[merge commit C]
R --> C

In the upper graph, trunk can move directly from B to F: the branch ref advances, but no extra merge commit is created. In the lower graph, both sides contain unique commits. A true merge records a new snapshot in C and gives C two parents, preserving both lines of ancestry.

5. Three-way merge inputs

For the common two-branch case, Git conceptually compares three snapshots: the merge base, the current branch tip (“ours” in this merge context), and the incoming tip (“theirs”). If one side changed a region and the other did not, Git can usually combine the result automatically. If both sides made incompatible changes to the same logical region, Git cannot choose intent and records a conflict for human resolution.

Input Role
merge base shared ancestor: what both sides started from
current HEAD current branch's result since the base
incoming tip branch/commit being merged

6. A conflict is missing intent, not repository corruption

A merge conflict means Git found changes it cannot safely reconcile mechanically. During a conflicted merge, the index can hold multiple stages for an unmerged path and Git writes conflict markers into suitable working-tree files. The repository is in an in-progress merge state until you resolve and continue, or abort.

git status
git ls-files -u
git diff --name-only --diff-filter=U

Do not “fix” a conflict by deleting .git, force-resetting indiscriminately, or accepting one side without understanding the application behavior.

7. Deleting a branch deletes a name, not every commit it ever reached

git branch -d topic removes a branch ref when Git considers it safely merged into the relevant upstream or HEAD. If the commits are also reachable through trunk, tags, other refs, or retention mechanisms, the commit objects remain reachable. Even unreferenced objects are not necessarily physically removed immediately.

git branch --merged
git merge-base --is-ancestor topic trunk
git branch -d topic

Force deletion with -D bypasses the merged-safety check and can remove the easiest name for unmerged work. It is not needed in the normal labs in this chapter.

8. Branching strategies are policies over the same graph mechanics

Model Useful when Main cost
Trunk-based development Frequent integration/deployment, strong automated tests, feature flags Requires disciplined small changes and reliable CI
Short-lived feature branches Review before integration without long isolation Integration delay grows if branches live too long
Release branches Multiple supported releases need selective stabilization/fixes Backports and divergence management
Git Flow-style multi-branch model Release trains/support constraints genuinely require multiple long-lived lanes Higher merge/integration overhead and policy complexity

None of these changes what a branch or merge is. They change how long refs live, who may update them, which histories are integrated, and how release support is organized.

9. DevOps connection — integration latency becomes delivery risk

A branch that diverges for hours usually produces fewer integration surprises than one that diverges for weeks. Branch policy therefore affects queue time, review size, conflict probability, release coordination, rollback reasoning, and how quickly CI feedback reaches the person who introduced a change. Choose the model from deployment frequency and support obligations, not popularity.

10. Knowledge check

Question 1. If trunk is an ancestor of feature/api, what can a normal merge often do?

Question 2. What three snapshots conceptually feed an ordinary two-head three-way merge?

Question 3. Does deleting a merged feature branch delete its commits from trunk?

Question 4. Why is a long-lived branch usually more expensive to integrate?

11. Summary

Branches are movable refs over one commit graph. A fast-forward moves a ref when no divergent current history needs preservation. A true merge records a new multi-parent commit, using a merge base plus both tips to compute the result. Branching strategies are operational policies layered on these mechanics.

Next

Build and inspect fast-forward, true merge, abort, conflict resolution, and branch deletion

Lesson 2 turns the graph model into a disposable workflow using modern git switch, explicit merge-base checks, and state inspection before and after every integration.

Authoritative references

 git-branch
 git-switch
 git-merge
 git-merge-base

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.