fix(hook): do not stage fixes when fail_on_fix=true#892
Conversation
When `fail_on_fix=true` is set on a hook, the step's auto-staging would silently re-stage the fixer's output over the user's explicit `git add` choices. After the failed commit the user couldn't see the proposed fix as an unstaged change for review, and a re-commit would silently succeed with the fix baked in — defeating the entire point of `fail_on_fix`. Force `should_stage=false` during fix runs when `fail_on_fix=true`. The fixer's output stays in the worktree as an unstaged change, the user's staged changes are preserved, and a re-commit will fail again until the user explicitly accepts the fix. Closes #888 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR fixes a bug (#888) where Confidence Score: 5/5This PR is safe to merge — it is a minimal, well-targeted fix with a solid regression test covering the exact bug scenario. The change is two lines touching a single, narrow condition. The logic is correct: forcing No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant Git
participant HK as hk (pre-commit)
participant Fixer
User->>Git: git add a.json
User->>Git: git commit -m "update"
Git->>HK: run pre-commit hook
Note over HK: fail_on_fix=true, run_type=Fix<br/>→ should_stage forced to false
HK->>Fixer: run fix step on a.json
Fixer-->>HK: a.json modified (spaces stripped)
Note over HK: should_stage=false → skip git add
HK-->>Git: fail (files were modified by fixer)
Git-->>User: commit rejected
Note over User,Git: After fix (correct behavior)
User->>Git: git diff --cached a.json
Git-->>User: shows user's original staged change (a.json with spaces)
User->>Git: git diff a.json
Git-->>User: shows fixer's unstaged change (spaces stripped)
Reviews (1): Last reviewed commit: "fix(hook): do not stage fixes when fail_..." | Re-trigger Greptile |
There was a problem hiding this comment.
Code Review
This pull request modifies the hook execution logic in src/hook.rs to prevent automatic staging of fixes when fail_on_fix is enabled, ensuring that fixes are surfaced for manual review. Additionally, a new integration test in test/fail_on_fix.bats verifies that existing staged changes are preserved and fixes appear as unstaged changes. I have no feedback to provide.
### 🐛 Bug Fixes - **(hook)** do not stage fixes when fail_on_fix=true by [@jdx](https://github.com/jdx) in [#892](#892) - use site domain for plausible data-domain by [@jdx](https://github.com/jdx) in [#886](#886) - make text-mode progress output usable in CI by [@jdx](https://github.com/jdx) in [#890](#890) ### 📚 Documentation - prefix GitHub star count with ★ glyph by [@jdx](https://github.com/jdx) in [#883](#883) ### 🔍 Other Changes - **(release)** dedupe sponsor section in release notes by [@jdx](https://github.com/jdx) in [#881](#881) - switch analytics from gtm/goatcounter to plausible by [@jdx](https://github.com/jdx) in [#885](#885) - migrate to namespace.so runners by [@jdx](https://github.com/jdx) in [#891](#891) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk release bookkeeping: version bumps, regenerated docs, and lockfile dependency updates with no functional code changes in this PR. > > **Overview** > Bumps `hk` to **v1.44.3** and adds the corresponding `CHANGELOG.md` release entry. > > Regenerates versioned docs/CLI artifacts to reference `1.44.3` (package URLs and generated `commands.json`/`index.md`) and updates `Cargo.lock` with dependency resolution changes (notably `jni`, `rustls*`, `reqwest`, `wasm-bindgen`, and `thiserror` unification). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit ab7b72e. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: mise-en-dev <123107610+mise-en-dev@users.noreply.github.com>
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [hk](https://github.com/jdx/hk) | minor | `1.43.0` → `1.45.0` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>jdx/hk (hk)</summary> ### [`v1.45.0`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1450---2026-05-04) [Compare Source](jdx/hk@v1.44.3...v1.45.0) ##### 🚀 Features - **(builtins)** add `buildifier` format and lint built-ins by [@​plx](https://github.com/plx) in [#​896](jdx/hk#896) ##### 🐛 Bug Fixes - **(step)** only auto-batch when rendered command exceeds ARG\_MAX by [@​jdx](https://github.com/jdx) in [#​901](jdx/hk#901) ##### 📚 Documentation - thank Namespace for GitHub Actions runner support by [@​jdx](https://github.com/jdx) in [#​895](jdx/hk#895) ##### 🔍 Other Changes - **(ci)** use !cancelled() instead of always() for final job by [@​jdx](https://github.com/jdx) in [#​906](jdx/hk#906) - **(docs)** remove shrill.en.dev analytics script by [@​jdx](https://github.com/jdx) in [#​903](jdx/hk#903) - remove rust-cache from release jobs by [@​jdx](https://github.com/jdx) in [#​893](jdx/hk#893) - invert CLAUDE.md/AGENTS.md so AGENTS.md is canonical by [@​jdx](https://github.com/jdx) in [#​905](jdx/hk#905) - set dev profile debug to 1 by [@​jdx](https://github.com/jdx) in [#​907](jdx/hk#907) ##### 📦️ Dependency Updates - update anthropics/claude-code-action digest to [`fefa07e`](jdx/hk@fefa07e) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​897](jdx/hk#897) - update jdx/mise-action digest to [`1648a78`](jdx/hk@1648a78) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​898](jdx/hk#898) - update apple-actions/import-codesign-certs action to v7 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​900](jdx/hk#900) - update autofix-ci/action action to v1.3.4 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​899](jdx/hk#899) - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​908](jdx/hk#908) ##### New Contributors - [@​plx](https://github.com/plx) made their first contribution in [#​896](jdx/hk#896) ### [`v1.44.3`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1443---2026-04-30) [Compare Source](jdx/hk@v1.44.2...v1.44.3) ##### 🐛 Bug Fixes - **(hook)** do not stage fixes when fail\_on\_fix=true by [@​jdx](https://github.com/jdx) in [#​892](jdx/hk#892) - use site domain for plausible data-domain by [@​jdx](https://github.com/jdx) in [#​886](jdx/hk#886) - make text-mode progress output usable in CI by [@​jdx](https://github.com/jdx) in [#​890](jdx/hk#890) ##### 📚 Documentation - prefix GitHub star count with ★ glyph by [@​jdx](https://github.com/jdx) in [#​883](jdx/hk#883) ##### 🔍 Other Changes - **(release)** dedupe sponsor section in release notes by [@​jdx](https://github.com/jdx) in [#​881](jdx/hk#881) - switch analytics from gtm/goatcounter to plausible by [@​jdx](https://github.com/jdx) in [#​885](jdx/hk#885) - migrate to namespace.so runners by [@​jdx](https://github.com/jdx) in [#​891](jdx/hk#891) ### [`v1.44.2`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1442---2026-04-26) [Compare Source](jdx/hk@v1.44.1...v1.44.2) ##### 🐛 Bug Fixes - **(builtins)** silence pklr deprecation warnings on Builtins.pkl load by [@​jdx](https://github.com/jdx) in [#​880](jdx/hk#880) - **(ci)** serialize docs lint step by [@​jdx](https://github.com/jdx) in [#​874](jdx/hk#874) - **(config)** include main pkl path in cache fresh files by [@​jdx](https://github.com/jdx) in [#​879](jdx/hk#879) - **(docs)** stack banner message and link on mobile by [@​jdx](https://github.com/jdx) in [#​865](jdx/hk#865) - **(docs)** pin banner close button to top-right corner on mobile by [@​jdx](https://github.com/jdx) in [#​867](jdx/hk#867) ##### 📚 Documentation - **(site)** show release version and github stars by [@​jdx](https://github.com/jdx) in [#​872](jdx/hk#872) ##### 🔍 Other Changes - add pr-closer workflow by [@​jdx](https://github.com/jdx) in [#​876](jdx/hk#876) ##### 📦️ Dependency Updates - bump communique 1.0.3 → 1.0.4 by [@​jdx](https://github.com/jdx) in [#​868](jdx/hk#868) - update anthropics/claude-code-action digest to [`2da6cfa`](jdx/hk@2da6cfa) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​869](jdx/hk#869) - update anthropics/claude-code-action digest to [`567fe95`](jdx/hk@567fe95) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​870](jdx/hk#870) - bump communique to 1.1.2 by [@​jdx](https://github.com/jdx) in [#​875](jdx/hk#875) ### [`v1.44.1`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1441---2026-04-24) [Compare Source](jdx/hk@v1.44.0...v1.44.1) ##### 🐛 Bug Fixes - **(git)** skip untracked scan when HK\_STASH\_UNTRACKED=false by [@​jdx](https://github.com/jdx) in [#​861](jdx/hk#861) - **(run)** add post-commit and pre-rebase subcommands by [@​jdx](https://github.com/jdx) in [#​858](jdx/hk#858) ##### 📚 Documentation - **(install)** recommend global hooks as primary setup path by [@​jdx](https://github.com/jdx) in [#​855](jdx/hk#855) - add cross-site announcement banner by [@​jdx](https://github.com/jdx) in [#​857](jdx/hk#857) - respect banner expires field by [@​jdx](https://github.com/jdx) in [#​862](jdx/hk#862) ##### 🔍 Other Changes - vendor bats test helpers instead of git submodules by [@​jdx](https://github.com/jdx) in [#​859](jdx/hk#859) ##### 📦️ Dependency Updates - bump communique to 1.0.3 by [@​jdx](https://github.com/jdx) in [#​863](jdx/hk#863) - update anthropics/claude-code-action digest to [`e58dfa5`](jdx/hk@e58dfa5) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​864](jdx/hk#864) ### [`v1.44.0`](https://github.com/jdx/hk/blob/HEAD/CHANGELOG.md#1440---2026-04-23) [Compare Source](jdx/hk@v1.43.0...v1.44.0) ##### 🚀 Features - **(check)** implement --plan, --why, and --json by [@​jdx](https://github.com/jdx) in [#​848](jdx/hk#848) - **(cocogitto)** add cocogitto conventional commits config to hk builtin config by [@​hituzi-no-sippo](https://github.com/hituzi-no-sippo) in [#​838](jdx/hk#838) - **(git)** support GIT\_DIR/GIT\_WORK\_TREE for bare-repo dotfile managers by [@​jdx](https://github.com/jdx) in [#​847](jdx/hk#847) - **(install)** use Git 2.54 config-based hooks with --global support by [@​jdx](https://github.com/jdx) in [#​853](jdx/hk#853) ##### 🐛 Bug Fixes - use text progress in CI by [@​jdx](https://github.com/jdx) in [#​845](jdx/hk#845) ##### 📚 Documentation - generalize agent guidelines by [@​jdx](https://github.com/jdx) in [#​846](jdx/hk#846) - add releases nav and aube lock by [@​jdx](https://github.com/jdx) in [#​849](jdx/hk#849) ##### 🔍 Other Changes - **(release)** append en.dev sponsor blurb to release notes by [@​jdx](https://github.com/jdx) in [#​854](jdx/hk#854) - bump communique to 1.0.1 by [@​jdx](https://github.com/jdx) in [#​850](jdx/hk#850) ##### 📦️ Dependency Updates - update actions-rust-lang/setup-rust-toolchain digest to [`2b1f5e9`](jdx/hk@2b1f5e9) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​832](jdx/hk#832) - update anthropics/claude-code-action digest to [`c3d45e8`](jdx/hk@c3d45e8) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​833](jdx/hk#833) - update rust crate tokio to v1.52.1 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​834](jdx/hk#834) - update actions/upload-pages-artifact action to v5 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​835](jdx/hk#835) - update taiki-e/upload-rust-binary-action digest to [`f0d45ae`](jdx/hk@f0d45ae) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​839](jdx/hk#839) - update rust crate clx to v2 by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​836](jdx/hk#836) - update anthropics/claude-code-action digest to [`0d2971c`](jdx/hk@0d2971c) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​841](jdx/hk#841) - update anthropics/claude-code-action digest to [`38ec876`](jdx/hk@38ec876) by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​842](jdx/hk#842) - lock file maintenance by [@​renovate\[bot\]](https://github.com/renovate\[bot]) in [#​851](jdx/hk#851) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xNjguNSIsInVwZGF0ZWRJblZlciI6IjQzLjE2OC41IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
Summary
When a hook has
fail_on_fix=true, the step's auto-staging would silently re-stage the fixer's output over the user's explicitgit addchoices. After the failed commit:fail_on_fixThis is the bug reported in #888.
Fix
Force
should_stage = falseduring fix runs whenfail_on_fix = true(src/hook.rs:828). The fixer's output stays in the worktree as an unstaged change, the user's staged changes are preserved, and a re-commit will fail again until the user explicitly accepts the fix.After the fix, the user's reproduction scenario yields exactly what they expected:
Test plan
test/fail_on_fix.batsreproducing the discussion scenariofail_on_fix.batstests pass in bothlibgit2andnolibgit2modescargo test(145 tests) passesCloses #888
🤖 Generated with Claude Code
Note
Medium Risk
Changes
pre-commit/hook execution behavior around git staging during fix runs, which can affect users’ commit contents. Scope is small and covered by a new regression test, but it touches git index/worktree semantics.Overview
Ensures
fail_on_fix=trueruns do not auto-stage fixer modifications by forcingshould_stageoff forRunType::Fix, so a failed hook leaves fixer edits as unstaged changes for review and does not overwrite the user’s staged selection.Adds a Bats regression test reproducing #888 to verify a failed
pre-commitpreserves the original staged diff while exposing the fixer’s reformatting in the working tree.Reviewed by Cursor Bugbot for commit 7a2b202. Bugbot is set up for automated code reviews on this repo. Configure here.