fix(run): add post-commit and pre-rebase subcommands#858
Conversation
`hk install` (and `hk install --global`) writes hookcmds for nine git
events including `post-commit` and `pre-rebase`, but `hk run` only
shipped typed subcommand handlers for seven of them. The two events
without handlers fell through to the `other` catch-all, which works
but:
- hides them from `hk run --help`
- mixes their args into `HookOptions::files` (the positional
collector) instead of named arguments, so usage is opaque
- produces confusing clap errors when arg parsing goes sideways
Add dedicated `PostCommit` (no args) and `PreRebase` (upstream +
optional branch, matching git's hook spec) handlers so every event
listed in `DEFAULT_GLOBAL_EVENTS` has a named handler.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR adds dedicated Confidence Score: 5/5Safe to merge — additive only, follows established patterns exactly, no logic changes to existing paths Both new handlers are small, pattern-matched implementations with no edge-case risk. The only change to existing code is adding two enum variants and two match arms in mod.rs. No existing behaviour is altered. No files require special attention Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["hk run <subcommand>"] --> B{Commands enum}
B --> C[CommitMsg]
B --> D[PostCheckout]
B --> E["PostCommit 🆕"]
B --> F[PostMerge]
B --> G[PostRewrite]
B --> H[PreCommit]
B --> I[PrePush]
B --> J["PreRebase 🆕"]
B --> K[PrepareCommitMsg]
B --> L[other catch-all]
E --> E1["hook_args = ''"]
J --> J1["hook_args = upstream [branch]"]
E1 --> Z[HookOptions::run]
J1 --> Z
C --> Z
D --> Z
F --> Z
G --> Z
H --> Z
I --> Z
K --> Z
L --> M["hook_args = ''"]
M --> Z
Reviews (2): Last reviewed commit: "[autofix.ci] apply automated fixes" | Re-trigger Greptile |
There was a problem hiding this comment.
Code Review
This pull request introduces support for the post-commit and pre-rebase Git hooks by adding the corresponding modules and CLI subcommands. The post-commit hook is implemented with empty arguments, while the pre-rebase hook handles upstream and optional branch parameters. Review feedback highlights a potential issue where flags passed before subcommands are ignored due to the current command dispatch pattern. Additionally, a suggestion was made to optimize the pre-rebase argument construction by moving the upstream string instead of cloning it.
| return match cmd { | ||
| Commands::CommitMsg(cmd) => cmd.run().await, | ||
| Commands::PostCheckout(cmd) => cmd.run().await, | ||
| Commands::PostCommit(cmd) => cmd.run().await, |
There was a problem hiding this comment.
Flags passed before the subcommand (e.g., hk run --all post-commit) are captured by the Run struct's hook field but are ignored when dispatching to a subcommand, as the subcommand's run method only uses its own hook options. This is an existing pattern in this file, but it affects the newly added subcommands as well. Consider merging the parent options into the subcommand's options or refactoring how flags are handled.
| let args = match &self.branch { | ||
| Some(b) => format!("{} {}", self.upstream, b), | ||
| None => self.upstream.clone(), | ||
| }; |
There was a problem hiding this comment.
Joining upstream and branch with a space in hook_args can be ambiguous if either value contains spaces (e.g., a branch name with a space). While branch names with spaces are rare, Git's pre-rebase hook provides them as separate arguments to preserve boundaries. If the downstream consumer of hook_args splits by space, this implementation might fail for complex ref names. Additionally, since run takes ownership of self, you can avoid the clone by moving self.upstream in the None case.
| let args = match &self.branch { | |
| Some(b) => format!("{} {}", self.upstream, b), | |
| None => self.upstream.clone(), | |
| }; | |
| let args = match self.branch { | |
| Some(b) => format!("{} {}", self.upstream, b), | |
| None => self.upstream, | |
| }; |
### 🐛 Bug Fixes - **(git)** skip untracked scan when HK_STASH_UNTRACKED=false by [@jdx](https://github.com/jdx) in [#861](#861) - **(run)** add post-commit and pre-rebase subcommands by [@jdx](https://github.com/jdx) in [#858](#858) ### 📚 Documentation - **(install)** recommend global hooks as primary setup path by [@jdx](https://github.com/jdx) in [#855](#855) - add cross-site announcement banner by [@jdx](https://github.com/jdx) in [#857](#857) - respect banner expires field by [@jdx](https://github.com/jdx) in [#862](#862) ### 🔍 Other Changes - vendor bats test helpers instead of git submodules by [@jdx](https://github.com/jdx) in [#859](#859) ### 📦️ Dependency Updates - bump communique to 1.0.3 by [@jdx](https://github.com/jdx) in [#863](#863) - update anthropics/claude-code-action digest to e58dfa5 by [@renovate[bot]](https://github.com/renovate[bot]) in [#864](#864) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk release bookkeeping only: version numbers, generated CLI/docs, and lockfile dependency bumps with no runtime logic changes. > > **Overview** > **Release prep for `v1.44.1`.** Updates `Cargo.toml`/`Cargo.lock` (including `libc`) and all version references in generated CLI docs (`docs/cli/*`, `hk.usage.kdl`). > > Refreshes documentation examples to reference the new `v1.44.1` Pkl package URLs and adds the `1.44.1` entry to `CHANGELOG.md`. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d7637d4. 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
hk install(andhk install --global) writes hookcmds for nine git events, buthk runonly ships typed subcommand handlers for seven.post-commitandpre-rebasefell through to theothercatch-all, which works but:hk run --helpHookOptions::files(the positional collector) rather than named arguments, so usage is opaqueThis adds dedicated handlers so every event listed in `DEFAULT_GLOBAL_EVENTS` has a named handler, matching the pattern of the other seven hooks.
Changes
Test plan
Repro
Before this patch, a stale `--from-hook` hookcmd from a previous `hk install` + downgraded hk binary produced:
```
$ git rebase origin/main
Usage: hk run --from-ref <FROM_REF> [FILES]...
error: The pre-rebase hook refused to rebase.
```
With named handlers, the hookcmd parses cleanly regardless of hk version skew.
🤖 Generated with Claude Code
Note
Low Risk
Low risk: adds two new
hk runsubcommand handlers and only affects CLI parsing/dispatch for these hooks, without changing hook execution logic beyond howhook_argsis populated.Overview
hk runnow has dedicated subcommands forpost-commitandpre-rebase, so they appear in--helpand don’t fall through to the genericotherhandler.post-commitruns with emptyhook_args, andpre-rebaseadds typed<upstream> [branch]parsing and passes those values viahook_argsbefore invoking the corresponding hook.Reviewed by Cursor Bugbot for commit 55f5778. Bugbot is set up for automated code reviews on this repo. Configure here.