Evan Pratten
Evan Pratten
Software Developer

Since September of 2018 (3 and a half years ago) I have been roughly holding a streak of going no more than three days without making a commit to some project on GitHub.

A screenshot of my commit history last year

This is not entirely intentional, and I have broken it a few times:

..but a streak is a streak. A few of my friends know about this and keep an eye on my commit graph and I do too. Recently, with most of my programming time allocated to work, my graph started looking like weeks of empty cells, implying I broke my streak for good.

In reality, that couldn't be farther from the truth. I have been writing quite a lot of code actually, its just all tracked in a company GIT instance with a separate account.

Time for some trickery

I happened to remember a little trick I used in a CI pipeline for Raider Robotics where you can backdate empty commits with arbitrary authors. I recall using this for some kind of version tagging system at some point.. idk.. the important part being it is possible to make "fake" commits with the right command-line flags.

The game plan

My idea was as follows:

  1. Scrape all work repos for commits authored by one of my email addresses
  2. Keep track of the commit timestamps
  3. Make empty commits to a GitHub repo and backdate them to the timestamps from the last step
  4. Enjoy having my GitHub contributor graph synced to my work account

For anyone concerned with the security issue of leaking commit data, In my real implementation, dates are shuffled a bit. This also all happens in a private repo, so the public can only ever see its affect on my commit graph, and can't actually see the commits themselves.

Scraping commits from repos

The git command has a log subcommand for querying info about commits. In its simplest form, you can dump all commits for a repo with:

git -C /path/to/repo log --pretty=format:"%H"

An example output for the repo behind this website:


Its just a bunch of hashes.

As a side note, if you are trying to replicate my work and also commit with multiple email addresses, you can chain --author flags together.

git -C /path/to/repo log --pretty=format:"%H" --author[email protected] --author[email protected]

Cloning commits

If we iterate over our list of hashes, we can perform the rest of the steps. The main data point we care about is the timestamp.

To fetch a commit timestamp from a repo, use the following, replacing $COMMIT_HASH with the hash in question:

git -C /path/to/repo show -s --format=%ci $COMMIT_HASH

And finally, with our timestamp (stored as $DATE) a new commit can be written to a target repo:

git -C /path/to/public/repo commit -m "A message." --date="$DATE" --no-edit --allow-empty

Importantly, the --allow-empty flag removes the requirement for any files to be contained in the commit, essentially allowing you to have a "zero size" repository.


Uh, ya. Cool. With your scripting language of choice, you can chain these commands together, toss a git push in there, stick this in a cron job, and have yourself a nice, healthy commit graph.