git-hash finds an author timestamp for HEAD such that the resulting commit
SHA-1 starts with a hex prefix you choose. Useful for vanity hashes
(e.g. deadbeef…, c0ffee…).
Requires Python 3.8+ and a working git on PATH.
pip install git-hashInside a git repository, run:
git-hash <prefix> [--verbose]<prefix> must be lowercase hexadecimal (0-9, a-f).
Example:
> git-hash aaaaaa --verbose
Hash to find: aaaaaa
Approximate number of permutations 1048576
Iteration 130000, compute 12%, elapsed 0 sec, estimated 1 sec.
Iteration 260000, compute 25%, elapsed 0 sec, estimated 1 sec.
Iteration 390000, compute 37%, elapsed 1 sec.
Commit hash: aaaaaa3ad991376a76b69853969c8414392ba03a
Author date: 1595131373
You can change commit hash by:
GIT_COMMITTER_DATE="1595131400 +0700" git commit --amend --no-edit --date "1595131373 +0700"Copy the printed git commit --amend line and run it. After the amend, git rev-parse HEAD will equal the Commit hash printed by the tool — the committer date is preserved via GIT_COMMITTER_DATE, and the new author date is passed in git's raw <unix> <tz> format.
A git commit object is hashed as:
sha1("commit " + len(body) + "\0" + body)
where body is the textual commit (tree, parents, author, committer, message). Changing any byte changes the SHA-1. git-hash mutates only the author timestamp of HEAD's commit body and re-hashes in a tight loop, decrementing the timestamp by one second each iteration until the digest's prefix matches. The committer line is left untouched, which is why the suggested git commit --amend sets GIT_COMMITTER_DATE to its original value — together they reproduce the exact body that was hashed.
- Only
HEADis rewritten. To re-hash older commits, use an interactive rebase and apply this tool at each step. - Search cost is
~16^NSHA-1s for anN-character prefix. More than 8 characters is not recommended (16⁸ ≈ 4·10⁹ hashes, easily minutes-to-hours on a single core). - The author timestamp must remain 10 digits (years ~2001–2286). The tool aborts cleanly if it would leave that range.
- Forging vanity hashes is for fun and aesthetics. Don't use it to imitate other authors or backdate commits in contexts where that would mislead anyone.
python -m unittest discover -s testsWith coverage:
python -m coverage run --source=githash -m unittest discover -s tests
python -m coverage report -mApache License 2.0. See LICENSE.