Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,8 @@ impl Hook {
return Ok(());
}
let run_type = self.run_type(&opts);
// fail_on_fix exists to surface fixes for review; staging would defeat that.
let should_stage = should_stage && !(self.fail_on_fix && matches!(run_type, RunType::Fix));
let repo = Arc::new(Mutex::new(Git::new()?));
let groups = self.get_step_groups(&opts);
let stash_method = if let Some(stash_str) = &opts.stash {
Expand Down
50 changes: 50 additions & 0 deletions test/fail_on_fix.bats
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,53 @@ EOF

hk run fix
}

@test "fail_on_fix=true preserves staged changes and surfaces fix as unstaged (#888)" {
cat <<EOF > hk.pkl
amends "$PKL_PATH/Config.pkl"
hooks {
["pre-commit"] {
fix = true
fail_on_fix = true
steps {
["normalize"] {
glob = "*.json"
fix = #"for f in {{ files }}; do tr -d ' ' < "\$f" > "\$f.tmp" && mv "\$f.tmp" "\$f"; done"#
}
}
}
}
EOF
# Initial committed state has spaces that the fixer will strip.
echo '{"a": 1}' > a.json
echo "original" > b.md
git add hk.pkl a.json b.md
git commit -m "initial commit"
hk install

# User makes intentional changes to both files, but only stages a.json.
echo '{"a": 2}' > a.json
echo "modified" > b.md
git add a.json

# Pre-commit must fail with fail_on_fix.
run git commit -m "update"
assert_failure

# The user's staged change to a.json must survive: index still differs from HEAD
# in the test value, NOT in the formatting (which is the fixer's contribution).
run git diff --cached --name-only
assert_output "a.json"
run git diff --cached a.json
assert_output --partial '"a": 2'
refute_output --partial '{"a":2}'

# The fix should now be visible as an unstaged change on a.json (whitespace removed).
run git diff --name-only
assert_line "a.json"
assert_line "b.md"

# b.md unstaged change must be preserved.
run cat b.md
assert_output "modified"
}
Loading