github jdx/hk v1.53.0
v1.53.0: Faster config loading and safer stashing

7 hours ago

This release adds a cargo-deny builtin, meaningfully speeds up config resolution and hook runs in large repos, and fixes two correctness bugs around dependency graphs and stashing. It also hardens hk's Git invocations against argument injection.

Added

  • cargo_deny builtin (@risu729) #1081. Runs cargo-deny for Rust dependency policy checks (advisories, bans, licenses, sources). It triggers on Cargo.toml, Cargo.lock, and deny.toml/.deny.toml (including .cargo/ and exceptions variants), groups executions by Cargo workspace and runs from the workspace directory, and uses --locked so checks never create or update Cargo.lock.

    ["cargo_deny"] = Builtins.cargo_deny

Fixed

  • Dependents no longer hang after a failed dependency (@jdx) #1099. With fail_fast = false, a failed step returned without marking its dependency watch channel as done, so any step with depends on it waited forever and the run hung. The failed step now signals its dependents so they can proceed. fail_fast = true behavior is unchanged. Fixes discussion #1098.

  • No stashing when a hook has no steps to run (@jdx) #1106. When a hook resolved to zero steps but the worktree had unstaged or untracked changes, hk stashed them and returned early — before the restore ran — leaving a dangling stash and a stripped working tree (each retry piling on another stash). The "no steps to run" guard now runs before any side effects, so there is nothing to stash. Stash-restore failures also now report the ~/.local/state/hk/patches/*.patch backup path for manual recovery. Fixes #1105.

Changed

  • Hardened Git invocations against argument injection (@sshine) #1101. hk now passes --end-of-options before untrusted revisions in merge-base, rev-parse, ls-tree, and diff ranges, and replaces ls-remote shell interpolation with an argv invocation. This prevents repo-config-controlled refs (hk.pkl default_branch, --from-ref/--to-ref) and hyphen-prefixed branch names from being misread as options. Note: rev-parse --end-of-options requires Git 2.30+.

Performance

  • Resolved config cached in-process (@mharris-figma) #1104. Each Config::get() previously re-applied subprojects and user config, re-validated, and cloned on every call. Since hk runs one command against one project, the resolved config is now built once per process (callers still get clones). A warm-cache hk validate benchmark against a large config improved 46% (102.60 ms to 55.21 ms).

  • Final status snapshot skipped outside debug logging (@mharris-figma) #1102. The final Git status scan is only used for debug diagnostics, but hk was running a full repository scan at every log level and discarding it. It's now gated behind debug logging. A no-op benchmark over a 6,156-file repo with 4,000 modified files improved ~40% on both backends (libgit2: 221 ms to 131 ms; shell Git: 223 ms to 136 ms). Status reads used for file selection, stashing, and hook behavior are unchanged.

New Contributors

Full Changelog: v1.52.0...v1.53.0

💚 Sponsor hk

hk is maintained by @jdx, an open source developer for entire.io, the title sponsor of the jdx.dev open source tools including mise, aube, and more. Work on hk is funded by sponsorships.

If hk has sped up your pre-commit loop or made linting feel less painful, please consider sponsoring at jdx.dev. Sponsorships are what keep hk moving and the project independent.

Don't miss a new hk release

NewReleases is sending notifications on new releases.