When a merge queue lands a PR onto main, it has to decide how to record that event in git history. This choice affects how readable your repository is, how easy it is to debug regressions, and what your git log looks like six months from now.
The Three Strategies
1. Squash and Merge (Most Common)
All commits in the PR are squashed into a single commit on main. The commit message is typically the PR title plus a reference number.
main: A ── B ── C ── D (each letter = one PR, one commit)
- Pros: Perfectly linear history.
git bisectworks flawlessly. Each commit onmainrepresents exactly one unit of work. - Cons: You lose the granular commit history of the PR. If a PR had 8 commits showing the evolution of an idea, that story is gone.
- Best for: Most teams. The default for GitHub's merge queue.
2. Rebase and Merge
Each individual commit from the PR is replayed on top of main as if it were written there originally.
main: A1 ── A2 ── A3 ── B1 ── B2 (A1-A3 from PR-A, B1-B2 from PR-B)
- Pros: Preserves individual commit history. Still linear.
- Cons: Commit SHAs are rewritten (the commits are new objects). Can confuse developers who reference commit SHAs in issues or comments.
- Best for: Teams with disciplined, meaningful commit messages.
3. Merge Commit
A new "merge commit" with two parents is created, recording the exact moment the PR branch joined main.
main: ──●──────────────●──
\ /
A1 ── A2 ──
- Pros: Preserves full context. You can see exactly which commits belonged to which PR. The original branch SHAs are unchanged.
- Cons: History is non-linear.
git log --onelinebecomes hard to read.git bisectstill works but the graph is more complex. - Best for: Projects where auditability and traceability of feature branches matter more than log cleanliness.
The Practical Recommendation
For most teams using a merge queue, Squash and Merge is the right default. It enforces a clean, bisectable history on main while the full PR discussion and commit history remain accessible in the pull request itself (on GitHub, GitLab, etc.). The merge queue's job is to protect main — keeping main's history clean is part of that job.
A common interview question is: "Why does linear history matter for incident response?" The answer: during an outage, you need to identify the exact commit that introduced a regression. With linear history and git bisect, you can binary-search through commits in O(log n) steps. With a tangled merge-commit graph, git bisect still works but the cognitive overhead of interpreting the graph under pressure is significant. Linear history is an operational safety feature, not just an aesthetic preference.