Chapter 20Lesson 04~145 minutes

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.

DiagnosticsSilent mismergeDriver failuresVersion boundaries

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

  1. Preserve: branch tips, merge bases, Git version, strategy/options, attributes/config, status, stage entries, rerere state, and tests.
  2. Inspect: topology, MERGE_HEAD, ls-files -u, stage content, driver config, and normalization rules.
  3. Classify: topology, content/path, index, semantic, rerere, driver/runtime, or normalization issue.
  4. Correct the narrowest layer.
  5. 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

Do not use hard reset, broad clean, force-updated shared refs, reflog expiry, object pruning, or history rewrite as first-line merge diagnosis. Preserve the tips/stages and use a disposable integration branch or 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.

Next

Run the integrated checkpoint

Lesson 5 combines text stages, rename/delete ownership, semantic tests, rerere reuse, and a harmless generated-file driver design.

Authoritative references

 merge-strategies
 git-merge-tree
 git-rerere
 gitattributes

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.