From c2210097f6131834996fb9f7e107b32bf1fef53f Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Wed, 18 May 2022 15:22:00 -0400 Subject: [PATCH] commit sync post --- content/blog/2022-05-18-commit-sync.md | 101 ++++++++++++++++++ .../images/posts/commit-sync/commit_graph.png | Bin 0 -> 11023 bytes 2 files changed, 101 insertions(+) create mode 100644 content/blog/2022-05-18-commit-sync.md create mode 100644 static/images/posts/commit-sync/commit_graph.png diff --git a/content/blog/2022-05-18-commit-sync.md b/content/blog/2022-05-18-commit-sync.md new file mode 100644 index 0000000..4738a9b --- /dev/null +++ b/content/blog/2022-05-18-commit-sync.md @@ -0,0 +1,101 @@ +--- +layout: page +title: "Commit syncing across hosted GIT instances" +description: "How I keep my commit graph alive" +date: 2022-05-18 +tags: random +draft: false +extra: + uses_katex: true + auto_center_images: true + excerpt: This post covers how to keep your commit graph alive across multiple GIT instances by syncing your commit history to magic repos. +--- + +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](/images/posts/commit-sync/commit_graph.png) + +This is not entirely intentional, and I have broken it a few times: + +- June 7, 2019 +- August 8, 2019 +- September 27, 2019 +- November 3, 2021 + +..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](https://github.com/frc5024/) 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: + +```sh +git -C /path/to/repo log --pretty=format:"%H" +``` + +An example output for the repo behind this website: + +```text +... +62d0c4833766671182ed0aeeb76bb16cc3f35174 +420b3cc4a9d61024e0dd6c32deafb57244d09433 +fed6fc374d02c2ae8f67bff837c8c8334760b303 +5a64788339afd750c3853468f89d275cf8fa49cd +01992912951d80631fa5069fce7d9a3593bbcd39 +d894387400158d231ed6559636169f1464bb630d +4a68456c7a5df699bc7620c9250b7a04aac5bd3c +ff87809b9c14c5132ecd5a39921b1cf2118b12cc +2b8797bbdcec61654540d995aaae67bcab8dc1c1 +c4d978c5d098846b8a0105c5b6d3f42b389c6ea7 +9791cdd979a17f0d5ebf9028d4778152ca07ae1d +dda08261872d3c2301cc02108c0f466dedaacaca +f408c1fa9785a40038e04b0ef017bd8d2897cdd6 +... +``` + +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. + +```sh +git -C /path/to/repo log --pretty=format:"%H" --author=ewpratten@example.com --author=evan@work.com +``` + +### 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: + +```sh +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: + +```sh +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. + +## Conclusion + +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. + diff --git a/static/images/posts/commit-sync/commit_graph.png b/static/images/posts/commit-sync/commit_graph.png new file mode 100644 index 0000000000000000000000000000000000000000..db481248fb271e22b4bfecf6eb1d2f80881ee27e GIT binary patch literal 11023 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 T>=p2$D}kz#CiIhndC>m@l5$i_ literal 0 HcmV?d00001