From eeb43d7b9381009ad560d5495e7bacf1fdcc80d8 Mon Sep 17 00:00:00 2001 From: William Carroll Date: Wed, 26 Oct 2022 15:24:31 -0700 Subject: feat(wpcarro/blog): git revision numbers as refs See blog post Change-Id: I4b7dcdc85e5125876441b2f157e3d6ddc3cd3140 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7103 Tested-by: BuildkiteCI Reviewed-by: wpcarro --- users/wpcarro/website/blog/posts.nix | 7 ++ users/wpcarro/website/blog/posts/git-rev-refs.md | 85 ++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 users/wpcarro/website/blog/posts/git-rev-refs.md diff --git a/users/wpcarro/website/blog/posts.nix b/users/wpcarro/website/blog/posts.nix index 27a184a22ca7..514e3130b50e 100644 --- a/users/wpcarro/website/blog/posts.nix +++ b/users/wpcarro/website/blog/posts.nix @@ -78,4 +78,11 @@ content = ./posts/nixos-disk-full-note.md; draft = false; } + { + key = "git-rev-refs"; + title = "git revision numbers as refs (note to self)"; + date = 1666823030; + content = ./posts/git-rev-refs.md; + draft = false; + } ] diff --git a/users/wpcarro/website/blog/posts/git-rev-refs.md b/users/wpcarro/website/blog/posts/git-rev-refs.md new file mode 100644 index 000000000000..fdc0aaf5cc9f --- /dev/null +++ b/users/wpcarro/website/blog/posts/git-rev-refs.md @@ -0,0 +1,85 @@ +## Credit + +Credit goes to `tazjin@` for this idea :) + +## Background + +Using `git` revisions to pin versions is nice, but git SHAs aren't very +human-friendly: + +- They're difficult to type. +- They're difficult to say in conversation. +- They're difficult to compare. e.g. Which is newer? `2911fcd` or `db6ac90`? + +## Solution + +Let's assign monotonically increasing natural numbers to each of +our repo's mainline commits and create `git` refs so we can use references like +`r/123` instead of `2911fcd`. + +- They're easy to type: `r/123` +- They're easy to say in conversion: "Check-out rev one-twenty-three." +- They're easy to compare: `r/123` is an earlier version than `r/147`. + +## Backfilling + +Let's start-off by assigning "revision numbers" as refs for each of the mainline +commits: + +```shell +for commit in $(git rev-list --first-parent HEAD); do + git update-ref "refs/r/$(git rev-list --count --first-parent $commit)" $commit +done +``` + +We can verify with: + +```shell +λ git log --first-parent --oneline +``` + +If everything looks good, we can publish the refs to the remote: + +```shell +λ git push origin 'refs/r/*:refs/r/*' +``` + +## Staying Current + +In order to make sure that any newly merged commits have an associated revision +number as a ref, add something like the following to your CI system to run on +the builds of your repo's mainline branch: + +```shell +λ git push origin "HEAD:refs/r/$(git rev-list --count --first-parent HEAD)" +``` + +## Summary + +To verify that the remote now has the expected refs, we can use: + +```shell +λ git ls-remote origin | less # grep for refs/r +``` + +If that looks good, you should now be able to *manually* fetch the refs with: + +```shell +λ git fetch origin 'refs/r/*:refs/r/*' +``` + +Or you can use `git config` to automate this: + +```shell +λ git config --add remote.origin.fetch '+refs/r/*:refs/r/*' +λ git fetch origin +``` + +Now you can run fun commands like: + +```shell +λ git show r/1234 +λ git diff r/123{4,8} # see changes from 1234 -> 1238 +``` + +Thanks for reading! -- cgit 1.4.1