Change IDs in Jujutsu
jj vcs
I’ve been playing around with Jujutsu1 (or jj) lately. It’s a new version control system (VCS) that takes some good ideas from older VCS’s, like git and mercurial, and introduces some of its own. One feature that I’ve been really enjoying about it is change IDs. Change IDs are not unique to JJ but this is my first time using them. In JJ, change IDs are 16 byte randomly generated IDs. Since they’re not based on the content of a change adding to the change doesn’t cause them to be mutated. You don’t need to worry about change IDs clashing as you can’t control the change ID in JJ (as you can with something like Gerrit). So, there isn’t much risk of change IDs clashing. We have 128 bits (16 bytes) of entropy, giving 2128 possible change IDs. A collision is pretty unlikely!
As someone who has really only used git and Github extensively, having a persistent ID that doesn’t change when mutating a commit is really useful}. From a practical point of view, it allows for things like squashing2 into a commit by just grabbing the command out of your shell history. The JJ UI is even nice enough to show you how many characters you need of a change ID to uniquely identify it, further cutting down on typing. In git the commit ID changes each time you amend to it so you need to grab the new one. From a conceptual point of view, I think the change ID also maps better to many people’s mental model where the commit wraps up a particular change and the fact that in git the ID is based on the content hash is annoying implementation detail that leads to it changing all the time.
JJ does also have commit ID, however, I hardly ever use it. JJ does commonly display the change ID and commit ID together. However, for the change ID it uses reverse hex (characters in the space k-z, rather than 0-9 and a-f). Commits use the usual hex space so the two IDs are visually very different.
What you would call amending in git is called squashing in JJ. There is no “amend” command. I believe the reason for this is that the working copy is actually a commit so you’re squashing the commit into the target one, rather than amending the target one.