| Crates.io | samoyed |
| lib.rs | samoyed |
| version | 0.2.3 |
| created_at | 2025-08-01 19:49:56.532186+00 |
| updated_at | 2025-10-04 10:57:08.843907+00 |
| description | A single-binary, minimal, cross-platform Git hooks manager |
| homepage | https://github.com/nutthead/samoyed |
| repository | https://github.com/nutthead/samoyed |
| max_upload_size | |
| id | 1777472 |
| size | 146,400 |
A single-binary, minimalist, 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.

src/main.rs). No hidden complexity.SAMOYED=0 to bypass, SAMOYED=2 to debug. Simple escape hatches when you need them.Get started in under a minute:
# Install Samoyed
curl -fsSL https://raw.githubusercontent.com/nutthead/samoyed/main/install.sh | bash
# Navigate to your Git repository
cd your-project
# Initialize hooks
samoyed init
# Edit the starter pre-commit hook
$EDITOR .samoyed/pre-commit
# Test it
git commit --allow-empty -m "test hooks"
The fastest way to install Samoyed is with a single command:
curl -fsSL https://raw.githubusercontent.com/nutthead/samoyed/main/install.sh | bash
This downloads the latest pre-built binary for your platform, verifies its checksum, and places it in ~/.local/bin. To customize the installation directory:
curl -fsSL https://raw.githubusercontent.com/nutthead/samoyed/main/install.sh | INSTALL_DIR=~/bin bash
If you prefer to inspect the installer before running it:
curl -fsSL https://raw.githubusercontent.com/nutthead/samoyed/main/install.sh -o install.sh
less install.sh
bash install.sh
If you have Rust installed, use cargo install:
cargo install samoyed
Clone the repository and build locally:
git clone https://github.com/nutthead/samoyed.git
cd samoyed
cargo install --path .
Windows users should install via WSL (Windows Subsystem for Linux) and follow the Linux installation instructions above, or use cargo install samoyed in a native Windows terminal with the Rust toolchain installed.
To remove Samoyed:
curl -fsSL https://raw.githubusercontent.com/nutthead/samoyed/main/uninstall.sh | bash
Or manually:
rm ~/.local/bin/samoyed
# Remove PATH entry from your shell config if added by the installer
Inside your Git repository, run:
samoyed init [samoyed-dirname]
The samoyed-dirname defaults to .samoyed and must reside within the repository. On success, Samoyed creates:
.samoyed/
├── _/ # Hook wrappers (git-ignored)
│ ├── pre-commit
│ ├── commit-msg
│ ├── pre-push
│ ├── ... (all 14 hooks)
│ └── samoyed # POSIX wrapper script
├── pre-commit # Your editable hook (starter template)
└── .gitignore # Ignores the _/ directory
Git's core.hooksPath is configured to point to .samoyed/_/, routing all hook events through the wrapper.
The starter pre-commit script includes helpful comments. Edit it to add project-specific checks:
#!/bin/sh
# .samoyed/pre-commit
# Example: Format Rust code before commit
if ! cargo fmt --check; then
echo "Running cargo fmt..."
cargo fmt
git add --update '*.rs'
fi
# Example: Run linter
cargo clippy -- -D warnings
# Example: Ensure tests pass
cargo test --all
Make it executable and commit it to version control:
chmod +x .samoyed/pre-commit
git add .samoyed/
git commit -m "Add pre-commit hook for Rust formatting and tests"
Now every commit will automatically run these checks.
Bypass all hooks when you need to commit without running checks:
SAMOYED=0 git commit -m "emergency fix"
Enable debug mode to see exactly what the wrapper is doing:
SAMOYED=2 git commit -m "debug this hook"
This runs the wrapper with set -x, printing each command as it executes.
Bypass during initialization to prepare hooks without activating them:
SAMOYED=0 samoyed init
Samoyed sources an optional initialization script at ${XDG_CONFIG_HOME:-$HOME/.config}/samoyed/init.sh before running any hook. Use this for environment setup shared across all hooks:
# ~/.config/samoyed/init.sh
# Load secrets
export DATABASE_URL="$(cat ~/.secrets/db_url)"
# Set project defaults
export RUST_BACKTRACE=1
# Skip hooks in CI (optional)
if [ -n "$CI" ]; then
exit 0
fi
Because hooks are standard shell scripts, customize them directly in .samoyed/<hook>:
# .samoyed/pre-push - runs before git push
# Ensure main branch is never pushed directly
branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
if [ "$branch" = "main" ]; then
echo "Direct pushes to main are forbidden"
exit 1
fi
# Run full test suite before pushing
cargo test --all --release
Samoyed was built to strip Git hook tooling down to the essentials:
src/main.rs) manages CLI parsing, repository safety checks, and file generation.assets/samoyed) bootstraps every Git hook and keeps behaviour consistent across macOS, Linux, and Windows (via WSL or compatible shells).assets/samoyed---with include_bytes!, so distributing Samoyed is as simple as copying the executable.In 0.2.x, Samoyed 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 about 1000 lines of code---an ~80% 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.
*Support for samoyed.toml is removed in version 0.2.0. However I will re-introduce a well-thought-out option for configuring hooks "declaratively" in a future release.
Clone the repository and work inside a Nix shell (nix develop) or your local Rust toolchain.
Core commands:
cargo check # Fast type checks
cargo fmt # Format Rust code
cargo build --release # Build the optimised binary used in production
cargo test # Run unit tests
Integration tests live under tests/integration. Each script provisions a disposable repository via mktemp; run them individually, optionally preserving the workspace for inspection:
cd tests/integration
./01_default.sh # Run a single scenario
./08_samoyed_0.sh --keep # Keep the temporary repo after the test exits
Issues and pull requests are welcome. Before submitting a change, please ensure:
cargo fmt, cargo check, and cargo test pass locally.feat:, fix:, chore:, …).