pre-commit stash restore corrupts partially-staged files: stash patch written without trailing newline → git-apply "corrupt patch" → manual fallback splits lines #965
-
|
Versions: hk 1.46.0 (latest), git 2.50.1 (Apple Git-155), macOS arm64, pkl 0.31.1
SummaryAny file with both staged and unstaged hunks gets its unstaged hunks re-applied at the wrong position after Minimal reproPrereqs: hk 1.46.0 + the pkl CLI on PATH (e.g. git init t && cd t
cat > hk.pkl <<'EOF'
amends "package://github.com/jdx/hk/releases/download/v1.46.0/hk@1.46.0#/Config.pkl"
hooks { ["pre-commit"] { fix = true; stash = "patch-file"; steps {
["noop"] { glob = Regex(#"\.txt$"#); check_first = false; fix = "true" }
} } }
EOF
printf 'l1\nl2\nl3: tail\n' > f.txt
git add -A && git commit -m base
printf 'l1 STAGED\nl2\nl3: tail\n' > f.txt
git add f.txt
printf 'l1 STAGED\nl2\nl3: tail UNSTAGED\n' > f.txt
hk run pre-commit
cat f.txtExpected (last line restored intact, ONE line): Actual (last-line edit split onto a new line, note the leading space): Root cause (source-pinned, v1.46.0)The restore path for both stash modes is // Try strict prefix first
let mut tail_opt = w.strip_prefix(i);
// If that fails, allow a single trailing newline discrepancy
if tail_opt.is_none() && i.ends_with('\n') {
tail_opt = w.strip_prefix(&i[..i.len().saturating_sub(1)]);
}The newline-tolerant fallback misclassifies an edit to the last line as a tail insertion whenever the index snapshot ends with
…which is exactly the observed corruption, leading space included. Edits to non-final lines of partially-staged files take the regular merge path and survive; it's specifically last-line edits that get split. Secondary bug: the recovery backup patch is unparseableThe stash backup written to Workaround we're using
Happy to test a fix — this repro is scripted in our migration test matrix. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
I've raised #966 to fix this. It addresses both bugs: the newline-tolerant fallback in the tail-insertion special case now only accepts the EOF-newline-removal case (last-line edits fall through to the regular three-way merge), and the backup patch gets its trailing newline restored so This comment was generated by Claude Code. |
Beta Was this translation helpful? Give feedback.
I've raised #966 to fix this.
It addresses both bugs: the newline-tolerant fallback in the tail-insertion special case now only accepts the EOF-newline-removal case (last-line edits fall through to the regular three-way merge), and the backup patch gets its trailing newline restored so
git applycan parse it. The repro from this discussion is included as a regression test covering both stash modes.This comment was generated by Claude Code.