• Stars
    star
    1,163
  • Rank 40,128 (Top 0.8 %)
  • Language
    Rust
  • License
    MIT License
  • Created almost 9 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Customize your git commit hashes!

lucky-commit

Make your git commits lucky!

What?

With this simple tool, you can change the start of your git commit hashes to whatever you want.

$ git log
1f6383a Some commit
$ lucky_commit
$ git log
0000000 Some commit

As a demonstration, see the latest commit in this repository.

How?

lucky-commit amends your commit messages by adding a few characters of various types of whitespace, and keeps trying new messages until it finds a good hash. By default, it will look for a commit hash starting with "0000000".

To find a hash starting with something other than "0000000", pass the desired prefix as a command-line argument:

$ lucky_commit 1010101
$ git log
1010101 Some commit

The command-line argument can also contain _ placeholders (e.g. lucky_commit 00_111), indicating that the hash is allowed to have any hex character in the given slot.

Why?

¯\_(ツ)_/¯

Installation

  • Make sure you have rustc and cargo installed. Installation instructions can be found here.
  • Run cargo install lucky_commit --locked

Depending on your cargo setup, this will usually add the binary to your $PATH. You can then use it by running lucky_commit.

Alternatively, you can build from source:

$ git clone https://github.com/not-an-aardvark/lucky-commit
$ cd lucky-commit/
$ cargo build --release

This will create the lucky_commit binary (lucky_commit.exe on Windows) in the target/release directory. You can move this to wherever you want, or set up an alias for it.

Troubleshooting linker errors

By default, lucky-commit links with your system's OpenCL headers and runs on a GPU. This makes it significantly faster.

However, if you encounter a linker error along the lines of /usr/bin/ld: cannot find -lOpenCL, there are a few workarounds:

  • Compile lucky-commit without OpenCL by adding the flag --no-default-features to your install or build command (i.e. cargo install lucky_commit --locked --no-default-features or cargo build --release --no-default-features). This will make lucky-commit fall back to a multithreaded CPU implementation. The CPU implementation is about 20x slower on my laptop, but depending on what you're planning to use the tool for, there's a good chance it's fast enough anyway.

    This is the recommended approach if you just want a stable build, and you don't need the extra performance from GPUs.

  • You can try installing the OpenCL libraries for your system. The instructions for this will vary by OS (see e.g. here). Note that this will only be useful if your machine has a GPU.

  • You can try installing an older version of the library written in a different language (see the branches for Node.js, C, and pure Rust without OpenCL). Note that these older versions are drastically slower than the current version, and are also unmaintained.

Distro packages

Arch Linux

lucky-commit can be installed from the community repository using pacman:

$ pacman -S lucky-commit

Funtoo Linux

lucky-commit can be installed from dev-kit:

$ emerge dev-util/lucky-commit

Homebrew

lucky-commit is available from the default Homebrew tap:

brew install lucky-commit

Performance

lucky-commit's performance is determined by how powerful your computer is, whether you GPG-sign your commits, and whether you use experimental git features.

Hash rate

lucky-commit's main bottleneck is SHA1 throughput. The default hash prefix of 0000000 has length 7, so on average, lucky-commit needs to compute 167 SHA1 hashes.

For non-GPG-signed commits, lucky-commit adds its whitespace to a 64-byte-aligned block at the very end of the commit message. Since everything that precedes the whitespace is constant for any particular commit, this allows lucky-commit to cache the SHA1 buffer state and only hash a single 64-byte block on each attempt. For an average-sized commit, this speeds up the search by a factor of ~5 over the naive approach of hashing the entire commit on each attempt.

Hash searching is extremely parallelizable, and lucky-commit takes advantage of this by running on a GPU. When no GPU is available, it falls back to a multithreaded CPU implementation.

The GPU on my 2021 MacBook Pro can compute about 1.5 billion single-block hashes per second. As a result, the theoretical average time to find a 0000000 commit hash on my laptop is (167 hashes) / (1500000000 hashes/s) = 0.18 seconds. You can estimate the average time for your computer by running time lucky_commit --benchmark.

Outside of hashing, the tool also has to do a constant amount of I/O (e.g. spawning git a few times), resulting in an observed average time on my laptop of about 0.24 seconds.

GPG signatures

For GPG-signed commits, the commit message is part of the signed payload, so lucky-commit can't edit the commit message without making the signature invalid. Instead, it adds its whitespace to the end of the signature itself. Since the signature precedes the commit message in git's commit encoding, this requires lucky-commit to do more work on each attempt (it can't cache the SHA1 buffer state as effectively, and it needs to rehash the commit message every time). As a result, the performance for GPG-signed commits depends on the length of the commit message. This multiplies the average search time by roughly 1 + ceiling(commit message length / 64 bytes).

SHA256 repositories

Finally, lucky-commit also supports git repositories using the experimental sha256 object format. If lucky-commit detects that it's being run in a repository with sha256 objects, it will automatically customize the sha256 shorthash of the commit at HEAD, rather than the sha1 shorthash. The hash rate for sha256 is a bit slower than the hash rate for sha1.

If you're wondering whether your repository uses sha256, then it probably doesn't. At the time of writing, this is a highly experimental feature and is very rarely used.

Related projects

More Repositories

1

snoowrap

A JavaScript wrapper for the reddit API
JavaScript
1,014
star
2

git-delete-squashed

Delete branches that have been squashed and merged into main
JavaScript
388
star
3

every-git-commit-shorthash

Git repository with a commit for every single shorthash
Rust
182
star
4

reddit-oauth-helper

A quick script that creates reddit oauth tokens for you
JavaScript
148
star
5

eslint-plugin-eslint-plugin

An ESLint plugin for linting ESLint plugins
JavaScript
116
star
6

eslint-rule-composer

A utility for composing ESLint rules from other ESLint rules
JavaScript
49
star
7

eslint-plugin-rulesdir

An ESLint plugin to load project-specific ESLint rules
JavaScript
39
star
8

eslint-plugin-self

Allows ESLint plugins to lint themselves
JavaScript
15
star
9

promise-chains

A wrapper to allow easily-chainable JavaScript Promises using synchronous syntax
JavaScript
6
star
10

git-structured-log

Extract git data in bulk
Rust
4
star
11

switch-album-import

Imports your screenshots and videos from the Nintendo Switch album
Swift
3
star
12

node-matrices

A simple and lightweight matrix library for Node.js
JavaScript
2
star
13

very-pessimistic-concurrency-control

a database concurrency protocol
Python
2
star
14

node-release-script

Script for automatically generating releases
JavaScript
2
star
15

reddit-thread-nuke

https://not-an-aardvark.github.io/reddit-thread-nuke/
JavaScript
2
star
16

endian

Tests system endianness
JavaScript
1
star
17

oom

Uses up all available memory as fast as possible
JavaScript
1
star
18

github-status-check-editor

A web editor for GitHub status checks
JavaScript
1
star