Joining Histories
When you merge two branches, Git combines their commit graphs. The strategy it uses depends on the relationship between the two branches' histories.
Fast-Forward Merge
This is the simplest scenario. It occurs when the target branch (main) has not received any new commits since the feature branch was created — the feature branch is simply ahead of main in a straight line.
Git doesn't create a new commit. It moves the main pointer forward to where the feature branch is pointing. The history remains linear. This behavior can be disabled to always create a merge commit instead, which preserves the fact that a feature branch existed, even when a fast-forward would have been possible.
Three-Way Merge
This occurs when both branches have diverged — main has received commits since the feature branch was created. Git cannot simply move a pointer.
Git identifies three commits:
1. The common ancestor (the commit where the branches diverged)
2. The tip of the current branch (main)
3. The tip of the branch being merged (feature)
It combines the changes from both tips relative to the ancestor and creates a merge commit — a special commit with two parent pointers, one to each branch tip. This is what creates the characteristic "diamond" shape in the commit graph.
Octopus Merge
An octopus merge combines more than two branches simultaneously into a single merge commit with multiple parents. It's used by maintainers who want to integrate several independent feature branches at once. The resulting commit has three (or more) parent pointers. The history graph resembles an octopus — one head, many legs. Octopus merges are only possible when there are no conflicts between the branches being merged; any conflict forces you to merge branches two at a time.
A common interview question is: "What's the difference between git merge and git rebase?" The key answer: both integrate changes from one branch into another, but they produce different histories. Merge preserves the full branching history with a merge commit (non-destructive, safe for shared branches). Rebase replays commits on top of the target branch, producing a linear history (rewrites hashes, unsafe for shared branches). Neither is universally better — the choice depends on your team's history philosophy.
Key Point: Fast-forward merges move a pointer (linear history, no merge commit). Three-way merges create a merge commit with two parents (preserves branching history). Octopus merges create a commit with many parents (for integrating multiple independent branches simultaneously, conflict-free).