Samoyed
A single-binary, minimal, ultra-fast Git hooks manager for every platform.
Samoyed keeps Git hook management small, transparent, and safe. It ships as one Rust binary plus a POSIX wrapper script, so developers can install it quickly, version it with their repositories, and stay in control of what runs on commit.

Table of Contents
Background
Samoyed was built to strip Git hook tooling down to the essentials:
- One file of Rust code (
src/main.rs) manages CLI parsing, repository safety checks, and file generation. - One POSIX shell wrapper (
assets/samoyed) bootstraps every Git hook and keeps behaviour consistent across macOS, Linux, and Windows (via WSL or compatible shells). - Zero runtime dependencies. The compiled binary embeds the wrapper with
include_bytes!, so distributing Samoyed is as simple as copying the executable.
Version 0.2.0 doubles down on clarity: the samoyed init command seeds every Git hook, wires them through the shared wrapper, and leaves a template pre-commit script ready for teams to adapt. Environment variables such as SAMOYED=0 (bypass) and SAMOYED=2 (debug) give developers predictable escape hatches without extra plugins.
This represents a fundamental architectural simplification from version 0.1.17, which scattered functionality across 23 separate Rust modules totaling nearly 6,000 lines of code. The current single-file implementation achieves the same functionality in just 942 lines—an 84% reduction in code size. By consolidating everything into src/main.rs, the codebase becomes dramatically easier to understand, debug, and maintain, while eliminating the cognitive overhead of navigating complex module hierarchies and cross-file dependencies.
Install
Samoyed is a Cargo binary. Install straight from source:
# Clone the repository
# Build and place the binary on your PATH
To publish Samoyed for a project, commit the compiled binary (or vendor the repository) into your tooling workflow, then run samoyed init inside each Git repository that should use the hooks.
Usage
# inside a Git repository
samoyed-dirnamedefaults to.samoyed. The directory must resolve inside the repository; otherwise the command aborts with a clear error.- When the command succeeds, Samoyed creates
samoyed-dirname, seeds a_subdirectory with all 14 client-side Git hooks, installs the shared wrapper atsamoyed-dirname/_/samoyed, writes a.gitignore, and setscore.hooksPathto point at the new_directory. - A starter
samoyed-dirname/pre-commitscript is created with comments explaining where to add project-specific checks.
Bypass and debug modes
SAMOYED=0 samoyed init …prints a bypass message and leaves the repository untouched.SAMOYED=0 git commit …skips every hook sourced by the wrapper.SAMOYED=2 git commit …enablesset -xinside the wrapper for quick troubleshooting.
Configuration
Samoyed looks for an optional user init script at ${XDG_CONFIG_HOME:-$HOME/.config}/samoyed/init.sh. If present, it is sourced before any hook runs—use it to export shared environment variables or early exits. Because hooks are standard shell scripts, teams can customise individual hooks directly in .samoyed/<hook>.
Common workflows:
- Run
cargo checkfollowed bycargo fmtin.samoyed/pre-commit, then re-stage formatted files withgit add --update '*.rs'. - Place project-wide environment set-up (for example, secrets loading) in the optional init script, so every hook inherits the same session state.
Development
Clone the repository and work inside a Nix shell (nix develop) or your local Rust toolchain.
Core commands:
Integration tests live under tests/integration. Each script provisions a disposable repository via mktemp; run them individually, optionally preserving the workspace for inspection:
Guidelines for contributors are documented in AGENTS.md. Highlights:
- Keep all production Rust code inside
src/main.rs. - Avoid increasing cognitive complexity past 21 for any function.
- Do not add new runtime dependencies to
Cargo.toml.
Maintainers
Contributing
Issues and pull requests are welcome. Before submitting a change, please ensure:
cargo fmt,cargo check, andcargo testpass locally.- Relevant integration scripts succeed.
- Commit messages follow Conventional Commit style (
feat:,fix:,chore:, …).
License
MIT. See LICENSE for details.