Git hooks manager for Rust projects. Like Husky, but for Rust.
Inspired by Sloughi and the Node.js Husky project.
- Truly idempotent: Never overwrites your existing hook scripts
- No magic: Just sets
core.hooksPathin git config - CI-aware: Skips installation in CI environments
- Zero dependencies: Pure Rust, no external crates
Add rhusky to your build-dependencies:
[build-dependencies]
rhusky = "0.0.1"Create a build.rs file at the root of your project:
fn main() {
rhusky::Rhusky::new()
.hooks_dir(".githooks") // Custom hooks directory (default: ".githooks")
.skip_in_env("GITHUB_ACTIONS") // Skip when this env var is set (CI always skipped)
.with_default_hooks() // Create default hooks if they don't exist
.install()
.ok();
}Create your hooks directory and add your hooks:
mkdir -p .githooks
cat > .githooks/pre-commit << 'EOF'
#!/bin/sh
cargo fmt --check
cargo clippy -- -D warnings
EOF
chmod +x .githooks/pre-commitrhusky::Rhusky::new()
.hooks_dir(".git-hooks") // default is ".githooks"
.install()
.ok();By default, installation is skipped when the CI environment
variable is set. Add more:
rhusky::Rhusky::new()
.skip_in_env("GITHUB_ACTIONS")
.skip_in_env("GITLAB_CI")
.install()
.ok();Optionally create default hook scripts for Rust projects:
rhusky::Rhusky::new()
.with_default_hooks()
.install()
.ok();This creates three hooks (if they don't already exist):
- pre-commit: Runs
cargo +nightly fmt --checkandcargo +nightly clippyon staged Rust files - commit-msg: Validates conventional commit format with
mandatory scope (e.g.,
feat(api): add endpoint) - post-commit: Verifies the commit is signed
Existing hooks are never overwritten.
Rhusky sets Git's core.hooksPath configuration to point to your
hooks directory. This tells Git to look for hooks in that directory
instead of the default .git/hooks/.
Unlike other tools, Rhusky:
- Never overwrites existing hooks - truly idempotent
- Optionally creates defaults - use
with_default_hooks()or manage your own - Minimal by default - just sets git config unless you opt in
#!/bin/sh
cargo +nightly fmt --check
cargo +nightly clippy --all-targets -- -D warnings#!/bin/sh
# Verify conventional commit format with Cocogitto
if command -v cog &> /dev/null; then
cog verify --file "$1"
fi| Feature | Rhusky | Sloughi | cargo-husky | husky-rs |
|---|---|---|---|---|
Sets core.hooksPath |
Yes | Yes | No | No |
| Creates hook files | Optional | Yes | Yes | Yes |
| Overwrites existing hooks | Never | Yes | Yes | Yes |
| Zero dependencies | Yes | Yes | No | No |
| Customizable hooks dir | Yes | Yes | Limited | Limited |
| CI-aware | Yes | Yes | No | No |
Sloughi was the inspiration
for Rhusky. It uses the same core.hooksPath approach but creates
default hook files on every cargo build, overwriting any custom
hooks you've written. Rhusky fixes this by never creating or
modifying hook files.
cargo-husky copies hook
scripts into .git/hooks/ rather than using core.hooksPath. This
means hooks aren't easily shareable via version control and can
conflict with other tools that manage .git/hooks/.
husky-rs also copies hooks
into .git/hooks/. Like cargo-husky, it doesn't use the modern
core.hooksPath approach and overwrites existing hooks.
