A tiny, dependency-free Go CLI to hash a file or an entire directory tree with excludes.
- Default algorithm: SHA-256
- Algorithms:
sha256,sha512,sha1,md5 - Exclude files/folders with simple patterns
- Deterministic directory digest (stable fingerprint)
- Optional compact output and hash-only mode
# Inside repo root
go mod tidy
go build -o hashit
# or install to $GOBIN (on your PATH)
go install .GOOS=linux GOARCH=amd64 go build -o hashitmake # build ./hashit
make install # go install
make tidy # go mod tidy
make clean # remove ./hashithashit [flags] <path>
<path> can be a file or a directory. If it’s a directory, hashit recursively walks all subfolders (unless excluded), produces per-file hashes when --list is enabled, and always prints a final directory digest (a single hash that represents the entire directory state).
| Flag | Type | Default | Description |
|---|---|---|---|
--algo |
string | sha256 |
Hash algorithm: sha256, sha512, sha1, md5. |
--exclude |
string (repeatable) | – | Exclusion patterns. Use dir/** to skip a whole subtree, *.ext to skip files by glob, or exact relative paths. |
--list |
bool | false |
When hashing a directory, also print each file’s hash on its own line. |
--follow-symlinks |
bool | false |
Follow file symlinks (directory symlinks are never followed). |
--no-name |
bool | false |
Print only the hash (omit file/dir name). |
--short |
int | 0 |
Print only the first N hex characters of the hash (0 = full length). |
-h, --help |
– | – | Show help. |
Notes on excludes
- Folder subtree:
.git/**,build/**,node_modules/** - File glob (by basename):
*.log,*.tmp - Full relative path:
path/to/file.txt - Matching is case-sensitive, uses
/as separator internally. - Exclusions apply to both files and directories during the walk.
./hashit ./README.md
# 9b1a...c0d1 README.md./hashit .
# b0e5...7f2c your-dir-name./hashit --list .
# 1a2b... fileA.txt
# 3c4d... sub/fileB.bin
# ...
# e5f6... your-dir-name <-- directory digest (always printed)./hashit --list --exclude ".git/**" --exclude "*.log" ../hashit --algo sha512 ../hashit --follow-symlinks ../hashit --no-name ./hashit
# 4c33ae55de4760fe9bb4...2276fad36./hashit --short 12 ./hashit
# 4c33ae55de47 hashit
./hashit --short 12 --no-name ./hashit
# 4c33ae55de47# Node / JS projects
./hashit --list --exclude ".git/**" --exclude "node_modules/**" --exclude "*.log" .
# Go projects
./hashit --list --exclude ".git/**" --exclude "bin/**" --exclude "*.test" .
# Large repos (skip vendor + build outputs)
./hashit --list --exclude "vendor/**" --exclude "build/**" --exclude "dist/**" .When hashing a directory:
hashitwalks files recursively (deterministically, sorted).- It computes each file’s hash using the chosen algorithm.
- It builds a manifest: lines of
"filehash␠␠relative/path ". - It hashes that manifest with the same algorithm.
The result is a stable fingerprint of the directory contents and structure (ignoring excluded files).
This makes it ideal for:
- detecting changes between builds,
- caching, CI invalidation,
- quick integrity checks.
- On Windows, use
hashit.exe. - To get the digest only (useful for scripts), add
--no-name. - To emulate “git short hashes,” use
--short 12(or your preferred length).
# Format and tidy
go fmt ./...
go mod tidy
# Build
go build -o hashit
# Run ad-hoc
go run . --list --exclude ".git/**" .MIT
