Source lines changed versus a git ref — the basis for mix mutare --since,
the CI mode that mutation-tests only what a branch touched.
Scoping is per-line, not per-file: a one-line edit to a large module mutates
only that line, not the whole file. The changed lines are fed to :only_lines
(the same site filter --line uses), so a --since run and a --line run
share all the downstream machinery.
"Changed" means what the branch changed: lines differing between the working
tree and the point where HEAD forked from the ref (their merge base), plus
every line of an untracked .ex file. Commits the ref gained after the fork are
not the branch's changes and are not included.
Summary
Functions
Lines changed under root versus ref, as a set of {relative_path, line}
pairs on the new side of the diff (the lines that now exist to be mutated).
Functions
Lines changed under root versus ref, as a set of {relative_path, line}
pairs on the new side of the diff (the lines that now exist to be mutated).
The diff runs from the merge base of ref and HEAD to the working tree, so
it holds the branch's committed and uncommitted changes and nothing ref gained
after the branch forked — what a pull request's diff shows. Untracked files
that .gitignore does not exclude are new relative to any ref, so every line
of each untracked .ex file is included, as git diff reports a newly added
file. Only .ex files, because only those are discovered for mutation; reading
other untracked files would cost time and add nothing.
Uses git diff -U0 --relative, run with root as the working dir, so paths
are scoped to and relative to root. The diff command disables
presentation/user hooks and pins prefixes because the output is parsed, and
turns off core.quotePath so a non-ASCII pathname is returned verbatim rather
than octal-escaped. -U0 drops context lines so only genuinely-added lines
land in the set; pure deletions contribute nothing (their file drops out
entirely if it has no other changes). Returns {:error, detail} if git fails
(no repo, bad ref, git missing) or finds no merge base (unrelated histories,
or a shallow clone missing the fork point).