Merge Algorithms, Conflict Engineering, rerere, and Custom Merge Drivers: Diagnostics, Failure Modes, Security, and Performance
Diagnose silent integration failures caused by ours shortcuts, semantic breakage, obsolete rerere reuse, missing drivers, rename/normalization changes, and Git-version assumptions.
Learning objectives
- Preserve topology/index/rerere/config evidence before modifying a failed integration.
- Explain how ours strategy and -Xours can discard valid intent without prompts.
- Detect marker-free semantic breakage using domain tests.
- Fail closed when rerere or a custom driver cannot be trusted or reproduced.
- Record Git version/rename/normalization inputs when conflict sets differ.
1. Diagnostic sequence
- Preserve: branch tips, merge bases, Git version, strategy/options, attributes/config, status, stage entries, rerere state, and tests.
-
Inspect: topology,
MERGE_HEAD,ls-files -u, stage content, driver config, and normalization rules. - Classify: topology, content/path, index, semantic, rerere, driver/runtime, or normalization issue.
- Correct the narrowest layer.
- Verify: no unresolved index stages plus domain tests and final merge diff.
2. Intentionally broken example — -s ours discards
required topic content
A topic branch changes a conflicting config line and adds a required
schema.sql. An operator runs:
git merge -s ours topic -m "merge topic quickly"
The merge can succeed while schema.sql is absent
because the result tree is exactly the current branch tree. Diagnose
it:
git show -s --format='%H %P %s' HEAD
git diff HEAD^1 HEAD
git diff HEAD^1 HEAD^2
git show HEAD:schema.sql
The missing content is the strategy's documented behavior, not corruption. Recreate the integration on a disposable branch using a normal strategy and real validation rather than hiding the conflict.
3. -Xours can still silently choose the wrong conflict
side
Unlike -s ours, non-conflicting topic files remain, but
conflicting hunks prefer our side. This can remove the prompt while
also preventing a required topic behavior from entering the result.
Review the merge diff and feature tests.
4. Markers removed does not mean semantics repaired
min_workers=10
...
max_workers=6
sh check_pool.sh
echo "validation exit=$?"
The correct response is a domain repair, not another strategy option. Integration correctness must be tested independently from conflict-marker resolution.
5. Obsolete rerere resolution
A remembered resolution can become stale as surrounding code/policy evolves. Inspect before staging:
git rerere status
git rerere diff
git diff
run-your-real-tests-here
If the remembered resolution no longer applies, use
git rerere forget -- path where appropriate and
resolve/record a new result.
6. Custom driver missing on CI
git check-attr merge -- generated/components.lock
git config --show-origin --get merge.generatedComponents.driver
command -v trusted-generated-merge || true
A tracked driver name is not an installed driver. The safe fallback is fail/regenerate/manual resolution through the authoritative tool—not silently switching to ours.
7. Rename detection changes conflict shape
Large rewrites can fall below similarity thresholds and appear as delete/add. Diagnose both sides from the merge base:
BASE=$(git merge-base HEAD MERGE_HEAD)
git diff --find-renames "$BASE"..HEAD
git diff --find-renames "$BASE"..MERGE_HEAD
If you tune -Xfind-renames=<n>, record the value
because it changes path identity analysis.
8. Normalization migration can produce surprising conflict sets
Different historical text/eol or filter rules can make
mechanically converted content look changed. Inspect attributes at
relevant commits. Use merge.renormalize only for a
known canonicalization transition; do not guess.
9. Strategy-name assumptions age
Current Git says ort is default. Git 2.50+ redirects
recursive to ort; the local Git 2.47.3
validator still predates that redirection. Always capture
git --version when a runbook names a strategy
explicitly.
10. merge-tree output must be interpreted with exit status
OUT=$(git merge-tree --write-tree left right)
RC=$?
printf 'exit=%s\n' "$RC"
On exit 1, stdout includes conflict information rather than only one clean tree OID. Scripts that ignore status and parse the whole output as an object ID are incorrect.
11. Security relevance — merge drivers execute code
Provision drivers from a trusted channel, quote paths/arguments,
avoid shell eval, reject malformed input, and run with
least privilege. A buggy or malicious driver can alter integration
output before review.
12. Performance relevance — do not trade correctness for faster conflict handling
Rename detection and per-file external drivers can cost time in large repositories. Measure before tuning. Disabling rename analysis or validation can reduce merge time while increasing mismerge/incident cost.
13. Red-zone operations
git merge --abort where appropriate.
14. Symptom → likely layer → evidence
| Symptom | Layer | Evidence |
|---|---|---|
| topic file missing after “successful” merge | strategy | parents + first-parent diff; inspect ours strategy use |
| no markers, tests fail | semantic integration | domain tests and merged config/API |
| rerere result suspicious | recorded reuse | rerere diff + tests |
| CI differs from local | driver/config/version | Git version + attributes + driver/runtime |
| unexpected rename conflict | rename/history | merge bases + rename-aware side diffs |
15. Knowledge check
Question 1. Why can the ours strategy make valid topic files disappear?
Question 2. What should happen when rerere's remembered result is obsolete?
Question 3. Why can CI lack a driver referenced by .gitattributes?
Question 4. Why is Git version relevant to recursive?
Question 5. Why must merge-tree scripts inspect exit status?
16. Summary
Merge automation fails silently when it substitutes convenience for evidence. Diagnose strategy, semantic validation, rerere reuse, driver provisioning, rename analysis, normalization, and version assumptions separately.
Authoritative references
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.