pub fn scan_merge(
merge: &str,
paths: &[(String, Blobs)],
report: &mut ScanReport,
)Expand description
Applies the safety check to every path of one merge, counting into
report.
Pure: the caller supplies the blobs. merges_scanned is incremented
here, so a caller that skips a merge before reaching this function
must count that skip itself.
§Relocation
crate::safety::check compares one path against itself, so a merge
that moves content from one file to another looks like a reversion
in the source and an injection in the destination. That is not a
silent revert: nothing was lost. The first corpus this was pointed at
produced exactly that, a documentation section moved between two
files during the merge, and it was 40% of the raw findings.
So after every path of a merge is checked, a line that appears as
reverted in one path and injected in another path of the same merge
is cancelled from both and counted in
ScanReport::lines_relocated. The cancellation is per merge and
never across merges: content leaving one commit and appearing in
another, later, is not a move, and treating it as one would hide the
exact class this scan exists to count.
§Survival, which is a second number rather than a second filter
That cancellation requires the line to be unattributable at both
ends. A refactor that moves a function into a file the author was
already editing does not qualify: the destination addition is
attributable to base -> proposed, so it never enters the injected
set, so it cannot cancel anything, and the source removal is reported
as a reversion of work that is sitting in the result untouched. On
git/git that is most of what the raw findings are – the object
database refactor moving blocks out of object-file.c reads as
fourteen reverted lines.
ScanReport::lines_surviving_elsewhere counts reverted lines that
are present somewhere in this merge’s result, and
ScanReport::findings_all_surviving counts findings made entirely
of them.
They are counted and still reported. Cancelling them would be the stronger detector and the weaker measurement: line presence anywhere in a result is a cheap test that a short or idiomatic line passes by accident, so silently dropping on it would remove true findings with no way to see how many. The kill criterion for this measurement was fixed before any number was known, and a filter added after seeing the data is exactly the move that discipline forbids. Two numbers let a reader bound the answer from both sides; one number chosen after the fact lets them do neither.