Jujutsu (jj) VCS workflows and the convenience of its “operation log”
Over the last month or two I’ve been trying out the relatively new jujutsu version control system (VCS) — and loving it. At first, I discovered it and read their GitHub README with curiosity but skepticism. Then I sought a few YouTube videos[1] demonstrating jj in action, and a tutorial for a text-based reference. I became very interested. I initialized a jj repo in one of my small git projects and played around. Since then, I’ve migrated all of my personal repositories to jj, and use jj for practically everything.
From the time I’ve spent with jj, I’ve felt myself sliding into some general workflows:
- A
jj squashworkflow
In git, this would be a workflow where you make a commit and continually amend/extend that commit until its intended goal is completed.- Make progress toward a desired goal.
- Commit (
jj commit, orjj newthenjj describe -m "...") with a message describing this unit of work. - Continue making changes.
- Squash (perhaps interactively:
jj squash -i[2]) new changes until the desired goal is accomplished. - Maybe change the description of the previous commit commit.
- Work in the working copy
- Envision a goal for a new commit. Express that into the description of the working copy commit:
jj describe -m "...". - Work until much of that goal is met.
jj newto work on the next goal. Orjj split -iif some of the changes in the working copy belong in the next commit.jj editto hop between commits and work on each until completion. Perhapsjj new -A ...one or more times when when you don’t want certain changes in a commit: make changes across however many of those commits, thenjj squashthem all into your original commit when you’re happy. (You’re basically creating a new git branch!)
- Envision a goal for a new commit. Express that into the description of the working copy commit:
- Concurrent commits workflow
Work on several commits simultaneously, using combinations ofjj squash,jj new, andjj rebaseto make make reversible changes while having a cleanjj logat the end. In essence, this is point (3.4) above but with room for added complexity.
I’m not a VCS expert, and my projects are small, but I’ve gravitated to (1) and (2) without feeling any mental strain of keeping track of where this and that change is and what CLI operations avoid x problem or y merging conflict (which, by the way, jj permits! Jujutsu treats conflicts as first-class, so conflicts and their resolutions percolate through ancestors and descendants without problem.)[3]
Perhaps the most exciting part of using jj is fearlessly making changes and experimenting. This has been an extraordinary boon for my learning about how to use jj in accordance to its VCS concepts. The reason is jj’s operation log (jj op log) and the ability to revert back to any past repository state (jj op restore OPERATION_ID).
With jj op restore, I can merge branches, create conflicts, resolve conflicts, mess up… then go back as if it never happened. I can make sweeping repository changes without fear! In git, I’d be walking on egg shells, worried about the potential to ruin the entire state of my local repository if I’m not careful…
I’d definitely recommend trying jj out if you haven’t already! Easily turn a git repo into a jj repo with a git backend: jj git init \-\-colocate.