| Crates.io | get_dir_hash |
| lib.rs | get_dir_hash |
| version | 0.1.0 |
| created_at | 2025-08-08 12:30:06.835651+00 |
| updated_at | 2025-08-08 12:30:06.835651+00 |
| description | Deterministic directory hashing with glob ignores and optional metadata. |
| homepage | |
| repository | https://github.com/ARyaskov/get_dir_hash |
| max_upload_size | |
| id | 1786707 |
| size | 38,211 |
Deterministic directory hashing with glob ignores and optional metadata — powered by BLAKE3.
Tiny, fast, and predictable. Great for cache keys, change detection, CI, and reproducible builds.
.gitignore-like glob rules (via globset)blake3, globset, walkdir, tiny CLI parser)# CLI
cargo install get_dir_hash
# Library
cargo add get_dir_hash
# hash current directory
get_dir_hash
# pick a dir
get_dir_hash ./my-project
# ignore patterns (can be repeated)
get_dir_hash --ignore "target/**" --ignore "**/*.log"
# load patterns from a file
get_dir_hash --ignore-file .get_dir_hashignore
# follow symlinks and include basic metadata (mode + mtime)
get_dir_hash --follow-symlinks --include-metadata
# disable auto-loading of .get_dir_hashignore in root
get_dir_hash --no-dotfile
get_dir_hash also auto-loads .get_dir_hash_ignore from the root directory unless --no-dotfile is passed.
Example .get_dir_hash_ignore:
# ignore build artifacts and logs
target/**
**/*.log
*.tmp
Output format:
<hex-digest> <path>
use get_dir_hash::{Options, get_dir_hash};
use std::path::Path;
fn main() -> std::io::Result<()> {
let mut opts = Options::default();
opts.ignore_patterns = vec!["target/**".into(), "**/*.tmp".into()];
// opts.include_metadata = true; // opt-in
// opts.follow_symlinks = true; // opt-in
let digest = get_dir_hash(Path::new("."), &opts)?;
println!("{digest}");
Ok(())
}
For every regular file (after ignore rules):
Framing: we feed the outer BLAKE3 hasher with a domain tag b"get_dir_hash-v1\0" and, per file, a record:
b"F\0" + <normalized-relative-path> + b"\0" + <BLAKE3(content)>
Optional metadata (--include-metadata / Options::include_metadata):
(secs, nanos) is included.Relative paths are normalized to Unix-style separators (/).
Ordering is stable (sorted by normalized path). You can also opt into case-insensitive path ordering via Options if needed for Windows-like behavior in caches.
Syntax provided by globset: supports **, *, ?, etc.
Patterns are evaluated relative to the root.
Not supported: !-negations.
Sources of patterns:
--ignore / Options::ignore_patterns--ignore-file / Options::ignore_files.get_dir_hash_ignore in root (unless --no-dotfile)blake3 crate)Options::follow_symlinks = false)./ as a separator in the digest framing.Tested with Rust v1.88
v0.1.0.Licensed under MIT.
Issues and PRs are welcome! Please keep changes minimal and deterministic, and avoid heavy dependencies. Cheers!