| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -8,6 +8,6 @@ | |
| "check", | ||
| "lint", | ||
| "fmt", | ||
| "setup", | ||
| "hooks", | ||
| "staged" | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,247 @@ | ||
| --- | ||
| description: 'Install, configure, troubleshoot, and safely remove repository-level Git hooks with Rstack CLI.' | ||
| --- | ||
|
|
||
| # hooks | ||
|
|
||
| import { PackageManagerTabs } from '@rspress/core/theme'; | ||
|
|
||
| The `rs hooks` command installs, updates, and removes repository-level [Git hooks](https://git-scm.com/docs/githooks). Hook scripts run in the project that installed them. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```bash | ||
| rs hooks [options] | ||
| rs hooks uninstall | ||
| ``` | ||
|
|
||
| Run `rs hooks` without a subcommand to install or update hooks. | ||
|
|
||
| :::tip Alias | ||
| `rs setup` is an alias for `rs hooks`. | ||
|
Comment thread
chenjiahan marked this conversation as resolved.
|
||
| ::: | ||
|
|
||
| ## Install hooks | ||
|
|
||
| By default, hook scripts are stored in `.rstack/hooks` at the Git repository root. If the current directory is outside a Git repository, the command skips installation. | ||
|
|
||
| Add `rs hooks` to the `prepare` script of the project that owns the repository hooks: | ||
|
|
||
| ```json title="package.json" | ||
| { | ||
| "scripts": { | ||
| "prepare": "rs hooks" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Run the script once to install the hooks: | ||
|
|
||
| <PackageManagerTabs | ||
| command={{ | ||
| npm: 'npm run prepare', | ||
| yarn: 'yarn run prepare', | ||
| pnpm: 'pnpm run prepare', | ||
| bun: 'bun run prepare', | ||
| }} | ||
| /> | ||
|
|
||
| For example, create a `pre-commit` hook that runs [`rs staged`](./staged): | ||
|
|
||
| ```sh title=".rstack/hooks/pre-commit" | ||
| rs staged | ||
| ``` | ||
|
|
||
| You can safely run the installation more than once, and it does not load `rstack.config.*`. Run `rs hooks` again after cloning the repository or if the generated hook files are missing. | ||
|
|
||
| :::warning Existing Git hook managers | ||
|
|
||
| `rs hooks` updates the repository's [`core.hooksPath`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-corehooksPath). If it detects another hooks path or existing Git hooks, it skips installation. Run `rs hooks --force` to let Rstack manage hooks instead. | ||
|
|
||
| ::: | ||
|
|
||
| ## Install options | ||
|
|
||
| ### `--force` | ||
|
|
||
| `--force` (or `-f`) installs Rstack hooks even when another Git hook setup already exists: | ||
|
|
||
| ```bash | ||
| rs hooks --force | ||
| ``` | ||
|
|
||
| Rstack keeps the existing hook files and points `core.hooksPath` to its generated hooks directory. While this setting is active, Git does not run hooks from the previous location. | ||
|
|
||
| `--force` cannot replace hooks owned by another Rstack project. | ||
|
|
||
| :::tip | ||
| Run `rs hooks --force` only once. Use `rs hooks` without `--force` in the `prepare` script. | ||
| ::: | ||
|
|
||
| ### `--hooks-dir` | ||
|
|
||
| Specifies a custom directory for hook scripts, relative to the Git repository root. | ||
|
|
||
| ```bash | ||
| rs hooks --hooks-dir config/git-hooks | ||
|
|
||
| # Quote paths that contain spaces | ||
| rs hooks --hooks-dir "config/git hooks" | ||
| ``` | ||
|
|
||
| When using a custom directory, add the full command to the `prepare` script of the project that manages hooks: | ||
|
|
||
| ```json title="package.json" | ||
| { | ||
| "scripts": { | ||
| "prepare": "rs hooks --hooks-dir config/git-hooks" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| > The path must not contain `..`. This prevents hook files from being created or overwritten outside the repository through a parent directory path. | ||
|
|
||
| ### `--help` | ||
|
|
||
| `--help` (or `-h`) displays the command's usage, subcommands, and installation options. | ||
|
|
||
| ```bash | ||
| rs hooks --help | ||
| ``` | ||
|
|
||
| ## Uninstall hooks | ||
|
|
||
| Run the command from the project that installed the hooks: | ||
|
|
||
| ```bash | ||
| rs hooks uninstall | ||
| ``` | ||
|
|
||
| Rstack automatically finds the active hooks and removes the `core.hooksPath` setting and the generated `_` directory. It does not delete project hook files such as `.rstack/hooks/pre-commit`. Hooks managed by another project or tool are left untouched. | ||
|
|
||
| Remove `rs hooks` from the `prepare` script if you do not want the hooks to be installed again. | ||
|
|
||
| If `--force` previously took over hooks in `.git/hooks`, those hooks become active again after uninstalling. | ||
|
|
||
| ## Hook files | ||
|
|
||
| The default directory structure is: | ||
|
|
||
| ```text | ||
| .rstack/ | ||
| └── hooks/ | ||
| ├── pre-commit # Repository hook script: edit and commit | ||
| └── _/ # Generated by rs hooks; ignored by Git | ||
| ├── .gitignore | ||
| ├── .owner | ||
| ├── runner | ||
| ├── pre-commit | ||
| ├── commit-msg | ||
| └── ... | ||
| ``` | ||
|
|
||
| Files alongside `_` are repository hook scripts. The `_` directory contains generated files and is ignored by Git. `rs hooks` points `core.hooksPath` to `.rstack/hooks/_`. | ||
|
|
||
| ## Supported hooks | ||
|
|
||
| Rstack CLI supports these client-side Git hooks: | ||
|
|
||
| - `pre-commit` | ||
| - `pre-merge-commit` | ||
| - `prepare-commit-msg` | ||
| - `commit-msg` | ||
| - `post-commit` | ||
| - `applypatch-msg` | ||
| - `pre-applypatch` | ||
| - `post-applypatch` | ||
| - `pre-rebase` | ||
| - `post-rewrite` | ||
| - `post-checkout` | ||
| - `post-merge` | ||
| - `pre-push` | ||
| - `pre-auto-gc` | ||
|
|
||
| Create a file with the matching name alongside the `_` directory. | ||
|
|
||
| ## Hook runtime | ||
|
|
||
| Rstack CLI runs hook scripts with POSIX `sh -e`. It forwards Git's arguments and standard input, then returns the hook's exit code. Before running a hook, Rstack changes to the project that installed the hooks and prepends that project's `node_modules/.bin` to `PATH`. | ||
|
|
||
| ### Disable and debug | ||
|
|
||
| Set `RSTACK_HOOKS=0` to skip installation or hook execution: | ||
|
|
||
| ```bash | ||
| RSTACK_HOOKS=0 git commit -m "Skip hooks" | ||
| ``` | ||
|
|
||
| Set `RSTACK_HOOKS=2` to trace the Rstack CLI hook runtime, including how it invokes the hook script and handles its exit code; to trace commands inside the hook script, add `set -x` to the script: | ||
|
|
||
| ```bash | ||
| RSTACK_HOOKS=2 git commit -m "Trace hooks" | ||
| ``` | ||
|
|
||
| ### Configure the hook environment | ||
|
|
||
| Before running a hook script, Rstack CLI loads this optional POSIX shell file: | ||
|
|
||
| ```text | ||
| ${XDG_CONFIG_HOME:-$HOME/.config}/rstack/hooks-init.sh | ||
| ``` | ||
|
|
||
| Use it to initialize a Node.js version manager, update `PATH`, or set `RSTACK_HOOKS=0` for the current user. | ||
|
|
||
| ## Ownership safety | ||
|
|
||
| Each generated hooks directory records its owning project. Only that project should include `rs hooks` in its `prepare` script. Rstack skips installation from any other project, even with `--force`, and refuses to remove hooks owned by another project. | ||
|
|
||
| To transfer ownership: | ||
|
|
||
| 1. Remove `rs hooks` from the previous owner's `prepare` script. | ||
| 2. Run `rs hooks uninstall` from the previous owner. | ||
| 3. Add `rs hooks` to the new owner's `prepare` script and run it once. | ||
|
|
||
| ## Monorepo | ||
|
|
||
| In a monorepo, the project that provides Rstack CLI may live in a subdirectory such as `frontend/`. Running `rs hooks` there still installs hooks at the Git repository root: | ||
|
|
||
| ```text | ||
| repo/.rstack/hooks/ | ||
| repo/.rstack/hooks/_/ | ||
| core.hooksPath=.rstack/hooks/_ | ||
| ``` | ||
|
|
||
| Rstack records `frontend` as the owning project. The hook scripts stay at the repository root but run from `frontend`, allowing them to use its configuration and dependencies without an explicit `cd`: | ||
|
|
||
| ```sh title=".rstack/hooks/pre-commit" | ||
| rs staged | ||
| ``` | ||
|
|
||
| ## Worktree behavior | ||
|
|
||
| Rstack preserves the Git configuration scope of the active `core.hooksPath`. If a linked worktree uses a worktree-scoped hooks path, `rs hooks --force` replaces it in that scope instead of writing a local setting that Git would ignore. | ||
|
|
||
| `rs hooks uninstall` also removes the setting from that scope. Removing a worktree-scoped installation affects only the current worktree and leaves hooks in other linked checkouts unchanged. A local `core.hooksPath` setting is shared across linked checkouts, so changing or removing it affects every checkout that does not override it. | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Hook does not run | ||
|
|
||
| - Check that the hook script has a [supported name](#supported-hooks) and is next to the `_` directory. | ||
| - Run `git config --show-scope --get core.hooksPath` and verify the effective scope and path. | ||
| - Rerun `rs hooks` to restore generated files and executable permissions. | ||
| - Check that `RSTACK_HOOKS` is not set to `0` in the environment or initialization file. | ||
| - If another hook setup is detected, run `rs hooks --force`. | ||
| - If another project is reported as the hooks owner, follow the steps in [Ownership safety](#ownership-safety). | ||
|
|
||
| Hook scripts do not need to be executable because Rstack CLI runs them with `sh`. | ||
|
|
||
| ### Command not found | ||
|
|
||
| For exit code 127, Rstack CLI prints the effective `PATH`. If a GUI Git client cannot find Node.js or the package manager, initialize them in `hooks-init.sh`. | ||
|
|
||
| ### Windows and Yarn | ||
|
|
||
| On Windows, hooks run in the POSIX shell included with [Git for Windows](https://gitforwindows.org/). Use LF line endings and `/` path separators in hooks. | ||
|
|
||
| [Yarn PnP](https://yarnpkg.com/features/pnp) does not provide `node_modules/.bin`. Run tools through a Yarn script, such as `yarn run test`, and make Node.js and Yarn available through `hooks-init.sh` when needed. | ||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.