Changes touching this path

  • loot apply-patch no longer deletes a file its deletion stanza does not describe: the deletion arm now checks its preimage, so the lines the stanza removes, with its no-newline marker, must equal the file on disk in the patch line space or the whole run is refused naming the path and why, a stanza with no hunks deletes only an empty file, and --check gives the same refusal. the binary test is now the exporters own delta::is_binary, so a NUL-bearing file is refused as binary too. spawned-binary tests went red before the change (1 passed, 4 failed), with the preimage check removed (2 passed, 3 failed), with the old utf8-only binary test (4 passed, 1 failed), with a hunkless deletion always applied (4 passed, 1 failed) and with the trailing newline ignored (4 passed, 1 failed), and the format-patch round trips of a text file, a file with no trailing newline and an empty file stay green. the comparison is in the line space, so the #1807 CRLF deletion still applies; its fixture now holds the lines its stanza deletes, which it did not, and comparing with the carriage returns kept turned that pin red (11 passed, 1 failed). ADR 0082 section 2, the #1809 and #1993 comments and CONTEXT.md state the preimage rule, and the workspace suite is green (#1992) 98894a0a · dbf3dbe6…
  • loot apply-patch closes the preimage gaps #1992 and #1995 left: an add is refused over a path holding bytes other than the ones it adds, which it used to write in front of them, a modify stanza with no hunks is refused, which wrote an empty file at an absent path, a deletion of an absent path is refused rather than reported as done, and a patch that writes or deletes one path in more than one stanza or renames one old path twice is refused. the similarity index, dissimilarity index and index rows are read past, so a git format-patch -M rename applies as a rename where it used to write an empty file at the new path, and another unread row above hunks is refused by name. apply_strict now reads a deleted last line without the no-newline marker as a claim that the file ends with a newline, the deletion arm compares through apply_strict, and the writer no longer discards a removal error. ten new spawned-binary tests went red before the change (deletion 5 passed, 2 failed; preimage 0 passed, 4 failed; rename 8 passed, 4 failed), a new pin for a deleted file that grew a line holds the unified deletion check, and over the apply-patch and format-patch test files the pins went red with the add check removed (46 passed, 2 failed), the hunkless modify refusal removed (47 passed, 1 failed), the git rows unread (47 passed, 1 failed), the unread-row refusal removed (46 passed, 2 failed), an absent deletion planned as a delete (47 passed, 1 failed), the shared path check removed (47 passed, 1 failed), the shared rename source check removed (47 passed, 1 failed), the newline claim removed (46 passed, 2 failed) and leftover lines ignored by the deletion check (47 passed, 1 failed). the format-patch round trips stay green, ADR 0082 gains section 4, one table of what each stanza class checks, its rename paragraph no longer claims more than the hunks compare, CONTEXT.md states the rules, and the workspace suite is green (#1997) 15e2d13e · dbf3dbe6…diff
  • loot apply-patch refuses a patch that deletes a path and also renames it away: refuse_shared_paths now counts every path a stanza removes, as a deletion or as a rename old path, and refuses both rows, where the run used to move the file, remove the old path once and discard the second NotFound, and a row it refuses that was already refused keeps its first reason with the shared one appended. a rename old path that another stanza writes stays allowed, as #1995 pins, and ADR 0082 says why and where git apply differs; the rename writer now reports every removal error. the offer_cost double counts account_of, and the two constant-cost cases pin it at the one read Reader::new makes since #1955. the apply_strict comment and ADR 0082 no longer say an unmarked kept last line claims nothing: format-patch writes one when only the new side ends with a newline, so it stays unchecked, and a hunk that adds no line loses that newline. plan_one shares one helper for the rename and add verdicts, the ClassReads, ingest_cost and offer_cost doubles and Reader::new have docs true to the code, no shared base double is added since the conformance double delegates every method, and the CONTEXT.md, ADR 0077 and ADR 0082 rewrap leftovers are fixed. before the change the new rename test went red (12 passed, 1 failed), as it did with deletions uncounted, with the deletion refusal removed and with the rename refusal removed (12 passed, 1 failed each); the kept-reason test went red with the first reason overwritten (8 passed, 1 failed); the account pins went red with a per-object account_of read in readable_rows (11 passed, 2 failed), which the old double let pass (13 passed), and with the owner arm reading nothing (11 passed, 2 failed). the workspace suite is green, and the loot-forge suite is green against a throwaway cluster with the CI env block and LOOT_FORGE_TEST_REQUIRE_DATABASE (#2006) f16115c2 · dbf3dbe6…diff

Renames are not followed. loot's tree maps a path to an address, so a rename is a delete and an add. This list is the history of the name, not of the bytes.