Support all-parent merge diffs

ober

37572290becfc2e63e699512607e3d72ddeee142

diff --git a/README.md b/README.md
index 5dd57c1..c98e8af 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ jerboa main-binary.ss scan /path/to/repo --format json
 
 Supported options are `--config FILE`, `--count N`, `--all`, `--from REV`,
 `--to REV`, `--commit REV`, `--file PATH`, `--include PATH`,
-`--exclude PREFIX`, `--min-lines N`, `--max-files N`,
+`--exclude PREFIX`, `--first-parent`, `--all-parents`, `--min-lines N`, `--max-files N`,
 `--max-added-lines N`, `--max-note-bytes N`,
 `--threshold HUMAN,AI`, `--threshold HUMAN,UNCERTAIN,AI`,
 `--no-llm`, `--llm`, `--provider NAME`,
@@ -59,6 +59,10 @@ JSON output. `--llm` is accepted as an explicit request, but this release has no
 active provider adapter; it emits a warning and still reports `llm_used:false`
 and `network_used:false`.
 
+Merge commits default to first-parent diffs. Use `--all-parents` to inspect
+per-parent merge diffs via Git's `-m` mode; merge warnings state which mode was
+used.
+
 By default, scans skip `vendor/`, `generated/`, `dist/`, `node_modules/`, and
 `.git/` paths. Use `--include PATH` or `--file PATH` to inspect one of those
 paths explicitly. `--include` and `--file` accept repository-relative pathspecs;
diff --git a/main-binary.ss b/main-binary.ss
index cec2864..45aa76d 100644
--- a/main-binary.ss
+++ b/main-binary.ss
@@ -2,6 +2,22 @@
 (import (std misc process))
 
 (def detector-version "0.1.0")
+(def current-parent-diff-mode "first-parent")
+
+(def (use-first-parent-diffs!)
+  (set! current-parent-diff-mode "first-parent"))
+
+(def (use-all-parent-diffs!)
+  (set! current-parent-diff-mode "all-parents"))
+
+(def (all-parent-diffs?)
+  (same-public-string? current-parent-diff-mode "all-parents"))
+
+(def (git-show-diff-args rev extras)
+  (append (list "show" "--format=")
+          (if (all-parent-diffs?) (list "-m") (list "--first-parent"))
+          extras
+          (list rev)))
 (def us (integer->char 31))
 (def tab (integer->char 9))
 
@@ -23,7 +39,7 @@
         xs)))
 
 (def (usage)
-  (displayln "usage: jerboa main-binary.ss scan [PATH] [--config FILE] [--count N|--all] [--from REV] [--to REV] [--file PATH|--include PATH] [--exclude PREFIX] [--min-lines N] [--threshold HUMAN,AI] [--no-llm|--llm] [--provider NAME] [--max-files N] [--max-added-lines N] [--max-note-bytes N] [--format table|json|jsonl|markdown]")
+  (displayln "usage: jerboa main-binary.ss scan [PATH] [--config FILE] [--count N|--all] [--from REV] [--to REV] [--file PATH|--include PATH] [--exclude PREFIX] [--first-parent|--all-parents] [--min-lines N] [--threshold HUMAN,AI] [--no-llm|--llm] [--provider NAME] [--max-files N] [--max-added-lines N] [--max-note-bytes N] [--format table|json|jsonl|markdown]")
   (displayln "       jerboa main-binary.ss explain REV [PATH] [--format json|markdown|table]")
   (displayln "       jerboa main-binary.ss stats [PATH] [--count N]")
   (displayln "       jerboa main-binary.ss verify-authorship [PATH] [--count N]"))
@@ -252,7 +268,7 @@
          [path (safe-ref parts 2 "")])
     (list path adds dels)))
 (def (numstat-lines repo rev file)
-  (let ([args (append (list "show" "--format=" "--numstat" "--first-parent" rev)
+  (let ([args (append (git-show-diff-args rev '("--numstat"))
                       (pathspec-args file))])
     (filter (lambda (line) (not (blank? line)))
             (split-lines (git repo args)))))
@@ -290,7 +306,7 @@
 (def (numstat-paths files) (map car files))
 
 (def (added-lines repo rev file)
-  (let ([args (append (list "show" "--format=" "--first-parent" "--unified=0" "--no-ext-diff" rev)
+  (let ([args (append (git-show-diff-args rev '("--unified=0" "--no-ext-diff"))
                       (pathspec-args file))])
     (map (lambda (line) (substring line 1 (string-length line)))
          (filter (lambda (line)
@@ -573,7 +589,11 @@
 
 (def (commit-shape-warnings parents)
   (append (if (root-commit? parents) '("root commit; no parent diff baseline") '())
-          (if (merge-commit? parents) '("merge commit; scanner uses first-parent diff") '())))
+          (if (merge-commit? parents)
+              (if (all-parent-diffs?)
+                  '("merge commit; scanner uses all-parent diffs")
+                  '("merge commit; scanner uses first-parent diff"))
+              '())))
 (def (parent-history-warnings shallow? missing-parent?)
   (append (if shallow? '("repository is shallow; parent history may be unavailable") '())
           (if missing-parent? '("parent object unavailable; history may be shallow") '())))
@@ -878,6 +898,14 @@
                                (options-commit opts) (options-from opts) (options-to opts) (cadr xs)
                                (options-min-lines opts) (options-metadata-only? opts) (options-heuristics-only? opts))
                  path-set?)]
+          [(string=? (car xs) "--first-parent")
+           (begin
+             (use-first-parent-diffs!)
+             (loop (cdr xs) opts path-set?))]
+          [(string=? (car xs) "--all-parents")
+           (begin
+             (use-all-parent-diffs!)
+             (loop (cdr xs) opts path-set?))]
           [(and (string=? (car xs) "--exclude") (pair? (cdr xs)))
            (begin
              (set! current-excludes (cons (cadr xs) current-excludes))
diff --git a/tests/fixture-smoke.sh b/tests/fixture-smoke.sh
index 8804b55..38db1a4 100755
--- a/tests/fixture-smoke.sh
+++ b/tests/fixture-smoke.sh
@@ -207,6 +207,11 @@ merge_rev=$(git -C "$fixture" rev-parse HEAD)
 merge_json=$("$root/bin/jerboa-aigit" scan "$fixture" --format json --commit "$merge_rev")
 printf '%s\n' "$merge_json" | grep -q 'merge commit; scanner uses first-parent diff'
 
+all_parent_json=$("$root/bin/jerboa-aigit" scan "$fixture" --format json --commit "$merge_rev" --all-parents)
+printf '%s\n' "$all_parent_json" | grep -q 'merge commit; scanner uses all-parent diffs'
+printf '%s\n' "$all_parent_json" | grep -q 'branch/feature.txt'
+printf '%s\n' "$all_parent_json" | grep -q 'src/human.txt'
+
 printf '*.bin binary\n' > "$fixture/.gitattributes"
 git -C "$fixture" add .gitattributes
 GIT_AUTHOR_DATE='2026-07-29T09:06:00-06:00' \