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
139 changes: 135 additions & 4 deletions docs/cli/commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -565,6 +575,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -744,10 +764,30 @@
},
"install": {
"full_cmd": ["install"],
"usage": "install [--mise]",
"usage": "install [FLAGS]",
"subcommands": {},
"args": [],
"flags": [
{
"name": "global",
"usage": "--global",
"help": "Install at user level (~/.gitconfig) so every repo on this machine\ngets hk hooks. Requires Git 2.54 or newer. In repos without an\n`hk.pkl`, the installed hook is a silent no-op.",
"help_first_line": "Install at user level (~/.gitconfig) so every repo on this machine",
"short": [],
"long": ["global"],
"hide": false,
"global": false
},
{
"name": "legacy",
"usage": "--legacy",
"help": "Force using the legacy `.git/hooks/` script shims instead of Git\n2.54+ config-based hooks. Not compatible with `--global`.",
"help_first_line": "Force using the legacy `.git/hooks/` script shims instead of Git",
"short": [],
"long": ["legacy"],
"hide": false,
"global": false
},
{
"name": "mise",
"usage": "--mise",
Expand All @@ -763,7 +803,7 @@
"mounts": [],
"hide": false,
"help": "Sets up git hooks to run hk",
"help_long": "Sets up git hooks to run hk\n\nIn a git worktree with a per-worktree core.hooksPath configured, hooks are installed to that worktree-local directory. Otherwise hooks go to the shared hooks directory.",
"help_long": "Sets up git hooks to run hk.\n\nOn Git 2.54+ this uses config-based hooks (`hook.<name>.command`), which keeps `.git/hooks/` untouched and composes cleanly with other hook managers. On older Git it falls back to writing script shims.\n\nWith `--global`, hooks are installed into the user's `~/.gitconfig` so every repository picks them up without a per-repo install. In a project without an `hk.pkl`, the installed hook exits silently — no-op.",
"name": "install",
"aliases": ["i"],
"hidden_aliases": [],
Expand Down Expand Up @@ -997,6 +1037,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -1275,6 +1325,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -1535,6 +1595,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -1795,6 +1865,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -2046,6 +2126,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -2316,6 +2406,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -2594,6 +2694,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -2849,6 +2959,16 @@
"hide": false,
"global": false
},
{
"name": "from-hook",
"usage": "--from-hook",
"help": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"help_first_line": "Invoked by an installed git hook — gracefully exit 0 when no hk.pkl is present or the event isn't defined. Set automatically by `hk install`",
"short": [],
"long": ["from-hook"],
"hide": true,
"global": false
},
{
"name": "from-ref",
"usage": "--from-ref <FROM_REF>",
Expand Down Expand Up @@ -3043,10 +3163,21 @@
},
"uninstall": {
"full_cmd": ["uninstall"],
"usage": "uninstall",
"usage": "uninstall [--global]",
"subcommands": {},
"args": [],
"flags": [],
"flags": [
{
"name": "global",
"usage": "--global",
"help": "Remove hk hooks from the user's global git config (`~/.gitconfig`).",
"help_first_line": "Remove hk hooks from the user's global git config (`~/.gitconfig`).",
"short": [],
"long": ["global"],
"hide": false,
"global": false
}
],
"mounts": [],
"hide": false,
"help": "Removes hk hooks from the current git repository",
Expand Down
4 changes: 2 additions & 2 deletions docs/cli/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Output in JSON format
- [`hk config sources`](/cli/config/sources.md)
- [`hk fix [FLAGS] [FILES]…`](/cli/fix.md)
- [`hk init [FLAGS]`](/cli/init.md)
- [`hk install [--mise]`](/cli/install.md)
- [`hk install [FLAGS]`](/cli/install.md)
- [`hk migrate <SUBCOMMAND>`](/cli/migrate.md)
- [`hk migrate pre-commit [FLAGS]`](/cli/migrate/pre-commit.md)
- [`hk run [FLAGS] [FILES]… <SUBCOMMAND>`](/cli/run.md)
Expand All @@ -71,7 +71,7 @@ Output in JSON format
- [`hk run pre-push [FLAGS] [ARGS]…`](/cli/run/pre-push.md)
- [`hk run prepare-commit-msg [FLAGS] <ARGS>…`](/cli/run/prepare-commit-msg.md)
- [`hk test [FLAGS]`](/cli/test.md)
- [`hk uninstall`](/cli/uninstall.md)
- [`hk uninstall [--global]`](/cli/uninstall.md)
- [`hk util <SUBCOMMAND>`](/cli/util.md)
- [`hk util check-added-large-files [--maxkb <MAXKB>] <FILES>…`](/cli/util/check-added-large-files.md)
- [`hk util check-byte-order-marker [-d --diff] <FILES>…`](/cli/util/check-byte-order-marker.md)
Expand Down
19 changes: 16 additions & 3 deletions docs/cli/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,28 @@

# `hk install`

- **Usage**: `hk install [--mise]`
- **Usage**: `hk install [FLAGS]`
- **Aliases**: `i`

Sets up git hooks to run hk
Sets up git hooks to run hk.

In a git worktree with a per-worktree core.hooksPath configured, hooks are installed to that worktree-local directory. Otherwise hooks go to the shared hooks directory.
On Git 2.54+ this uses config-based hooks (`hook.<name>.command`), which keeps `.git/hooks/` untouched and composes cleanly with other hook managers. On older Git it falls back to writing script shims.

With `--global`, hooks are installed into the user's `~/.gitconfig` so every repository picks them up without a per-repo install. In a project without an `hk.pkl`, the installed hook exits silently — no-op.

## Flags

### `--global`

Install at user level (~/.gitconfig) so every repo on this machine
gets hk hooks. Requires Git 2.54 or newer. In repos without an
`hk.pkl`, the installed hook is a silent no-op.

### `--legacy`

Force using the legacy `.git/hooks/` script shims instead of Git
2.54+ config-based hooks. Not compatible with `--global`.

### `--mise`

Use `mise x` to execute hooks. With this, it won't
Expand Down
8 changes: 7 additions & 1 deletion docs/cli/uninstall.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

# `hk uninstall`

- **Usage**: `hk uninstall`
- **Usage**: `hk uninstall [--global]`

Removes hk hooks from the current git repository

## Flags

### `--global`

Remove hk hooks from the user's global git config (`~/.gitconfig`).
40 changes: 40 additions & 0 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,46 @@ hk install

This will install the hooks for the repository like `pre-commit` and `pre-push` if they are defined in `hk.pkl`. Running `git commit` would now run the linters defined above in our example through the pre-commit hook.

On **Git 2.54 or newer**, `hk install` writes [config-based hooks](https://github.blog/open-source/git/highlights-from-git-2-54/) (`git config hook.hk-<event>.command`) instead of script files in `.git/hooks/`. This keeps the hooks directory untouched and composes cleanly with other hook managers. On older Git it falls back to writing script shims — no configuration needed, hk detects the installed git version automatically. Pass `--legacy` to force the shim mode.

## Install Hooks Globally (Git 2.54+)

With Git 2.54+, you can install hk hooks once in your **user-wide** `~/.gitconfig` and they apply to every repository on your machine:

```sh
hk install --global
```

This writes `hook.hk-<event>.command` entries to your global git config for the common client-side hooks (`pre-commit`, `pre-push`, `commit-msg`, `prepare-commit-msg`, `post-checkout`, `post-merge`, `post-rewrite`, `pre-rebase`, `post-commit`). Each invocation is a **silent no-op in repos that don't have an `hk.pkl`**, so you can safely enable it everywhere without breaking unrelated projects.

To remove the global install:

```sh
hk uninstall --global
```

Per-repository `hk install` works alongside `--global`, but note that **Git aggregates `hook.<name>.command` entries across every scope and runs them all** — so a local install on top of a global one will fire hk twice per event. To run only the local install in a repo that also has the global install active, disable the global entries in that repo with `hook.hk-<event>.enabled = false` (see the note at the end of this section).

### Configuring manually in `~/.gitconfig`

If you'd rather set this up by hand, add a block like the following to your `~/.gitconfig`:

```ini
[hook "hk-pre-commit"]
command = test "${HK:-1}" = "0" || hk run pre-commit --from-hook "$@"
event = pre-commit
[hook "hk-pre-push"]
command = test "${HK:-1}" = "0" || hk run pre-push --from-hook "$@"
event = pre-push
[hook "hk-commit-msg"]
command = test "${HK:-1}" = "0" || hk run commit-msg --from-hook "$@"
event = commit-msg
```
Comment thread
greptile-apps[bot] marked this conversation as resolved.

The `--from-hook` flag tells hk to exit silently when the project has no `hk.pkl` or doesn't define that event. The `test "${HK:-1}" = "0" ||` prefix is an escape hatch: run `HK=0 git commit` to bypass hooks for a single command. Use `mise x -- hk` instead of `hk` in the `command` if you manage hk via mise and don't auto-activate it.

To disable hk for a single repo without uninstalling globally, set `hook.hk-<event>.enabled = false` in that repo's `.git/config`.

## Checking and Fixing Code

You can check or fix code with [`hk check`](/cli/check) or [`hk fix`](/cli/fix)—by convention, "check" means files should not be modified and "fix"
Expand Down
Loading
Loading