Skip to content

fix(run): add post-commit and pre-rebase subcommands#858

Merged
jdx merged 2 commits intomainfrom
fix/pre-rebase-post-commit-subcommands
Apr 23, 2026
Merged

fix(run): add post-commit and pre-rebase subcommands#858
jdx merged 2 commits intomainfrom
fix/pre-rebase-post-commit-subcommands

Conversation

@jdx
Copy link
Copy Markdown
Owner

@jdx jdx commented Apr 23, 2026

Summary

hk install (and hk install --global) writes hookcmds for nine git events, but hk run only ships typed subcommand handlers for seven. post-commit and pre-rebase 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) rather than named arguments, so usage is opaque
  • produces confusing clap errors (`Usage: hk run --from-ref <FROM_REF> [FILES]...`) when positionals get reshuffled

This adds dedicated handlers so every event listed in `DEFAULT_GLOBAL_EVENTS` has a named handler, matching the pattern of the other seven hooks.

Changes

  • `src/cli/run/post_commit.rs` — new, no-args handler.
  • `src/cli/run/pre_rebase.rs` — new, typed ` [branch]` per git's pre-rebase spec.
  • `src/cli/run/mod.rs` — register both in the `Commands` enum and dispatch.

Test plan

  • `cargo build` clean
  • `hk run --help` now lists `post-commit` and `pre-rebase`
  • `hk run pre-rebase --help` shows ` [BRANCH]` signature
  • `hk run pre-rebase --from-hook origin/main` exits 0 silently in a dir without `hk.pkl` (expected no-op)
  • `hk run post-commit --from-hook` exits 0 silently in a dir without `hk.pkl`
  • `cargo test` — 7 pre-existing failures in settings/init tests present on clean `origin/main` too (pkl module resolution in the test env); this patch adds no new failures.

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 run subcommand handlers and only affects CLI parsing/dispatch for these hooks, without changing hook execution logic beyond how hook_args is populated.

Overview
hk run now has dedicated subcommands for post-commit and pre-rebase, so they appear in --help and don’t fall through to the generic other handler.

post-commit runs with empty hook_args, and pre-rebase adds typed <upstream> [branch] parsing and passes those values via hook_args before invoking the corresponding hook.

Reviewed by Cursor Bugbot for commit 55f5778. Bugbot is set up for automated code reviews on this repo. Configure here.

`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) <[email protected]>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR adds dedicated post-commit and pre-rebase subcommands to hk run, completing the full set of typed handlers for all nine git events listed in DEFAULT_GLOBAL_EVENTS. Both new handlers follow the exact same pattern as the existing seven (flatten HookOptions, populate hook_args in the tera context, delegate to HookOptions::run), and mod.rs is updated to register and dispatch them.

Confidence Score: 5/5

Safe 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

Filename Overview
src/cli/run/post_commit.rs New no-args handler for post-commit; correctly sets empty hook_args and delegates to HookOptions::run — matches the pattern of other simple hooks
src/cli/run/pre_rebase.rs New typed handler for pre-rebase with positional upstream/branch args; builds hook_args as space-separated string, consistent with post_merge.rs and prepare_commit_msg.rs patterns
src/cli/run/mod.rs Registers PostCommit and PreRebase in Commands enum and dispatches them correctly; other paths unchanged
docs/cli/commands.json Auto-generated JSON updated to include post-commit and pre-rebase subcommand specs; no manual edits needed here

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
Loading

Reviews (2): Last reviewed commit: "[autofix.ci] apply automated fixes" | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/cli/run/mod.rs
return match cmd {
Commands::CommitMsg(cmd) => cmd.run().await,
Commands::PostCheckout(cmd) => cmd.run().await,
Commands::PostCommit(cmd) => cmd.run().await,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Comment thread src/cli/run/pre_rebase.rs
Comment on lines +16 to +19
let args = match &self.branch {
Some(b) => format!("{} {}", self.upstream, b),
None => self.upstream.clone(),
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Suggested change
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,
};

@jdx jdx enabled auto-merge (squash) April 23, 2026 18:20
@jdx jdx disabled auto-merge April 23, 2026 18:20
@jdx jdx enabled auto-merge (squash) April 23, 2026 18:20
@jdx jdx changed the title feat(run): add post-commit and pre-rebase subcommands fix(run): add post-commit and pre-rebase subcommands Apr 23, 2026
@jdx jdx merged commit f9d70d0 into main Apr 23, 2026
19 checks passed
@jdx jdx deleted the fix/pre-rebase-post-commit-subcommands branch April 23, 2026 18:36
@jdx jdx mentioned this pull request Apr 23, 2026
jdx added a commit that referenced this pull request Apr 24, 2026
### 🐛 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 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant