fix(kvb-git-commit-next): renumber kept hunks in stage_hunks.py
git apply --unidiff-zero places an add-only hunk, which has no context to match, at its new-side start line. That line counts every earlier hunk of the diff, so each hunk select() dropped shifted the later add-only hunks down by its size: on the real README a staged node landed in the wrong Mermaid subgraph. renumber() rewrites each kept header from the old start plus the net lines of the hunks kept before it (+1 for a pure insertion, -1 for a pure deletion), with counts that match the kept lines. A new test drops an early hunk and a line of a mixed one and compares the whole staged file; against the previous script it fails with the line one place too low. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
43b0949f6b
commit
4ffbc85411
2 files changed
+27
-1
No files matched your search
@@ -21,6 +21,22 @@ import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
HEADER = re.compile(r"^@@ -(\d+)(?:,(\d+))? \+\d+(?:,\d+)? @@(.*)$")
|
||||
|
||||
|
||||
def renumber(hunks: list[list[str]]) -> list[list[str]]:
|
||||
offset = 0
|
||||
out = []
|
||||
for hunk in hunks:
|
||||
match = HEADER.match(hunk[0])
|
||||
start, count = int(match.group(1)), int(match.group(2) or 1)
|
||||
added = sum(line.startswith("+") for line in hunk[1:])
|
||||
removed = sum(line.startswith("-") for line in hunk[1:])
|
||||
new_start = start + offset + (1 if count == 0 else 0) - (1 if added == 0 else 0)
|
||||
out.append([f"@@ -{start},{count} +{new_start},{added} @@{match.group(3)}", *hunk[1:]])
|
||||
offset += added - removed
|
||||
return out
|
||||
|
||||
|
||||
def fail(message: str) -> None:
|
||||
print(f"stage_hunks: {message}", file=sys.stderr)
|
||||
@@ -78,7 +94,7 @@ def main() -> int:
|
||||
except re.error as error:
|
||||
fail(f"--match: {error}")
|
||||
header, hunks = split(git(repo, "diff", "--no-color", "-U0", "--", args.file))
|
||||
kept = select(hunks, pattern)
|
||||
kept = renumber(select(hunks, pattern))
|
||||
if not kept:
|
||||
print(f"stage_hunks: no change in {args.file} matches {args.match!r}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
Reference in new issue
Block a user