JJ-FZF is a TUI
(Terminal-based User Interface) for Jujutsu, built on top
of fzf. It centers around
the jj log view, providing key bindings for common
operations on JJ/Git repositories.
About six months ago, I revisited JJ, drawn in by its promise of Automatic
rebase and conflict resolution
. I have since found it very
useful and started to integrate it into my daily work. Previously, I
have been relying on shell wrappers and aliases (yyhelp)
for most of my Git interactions. To better understand JJ’s operations, I
decided to wrap the command details inside shell functions and bind them
to keys in jj log | fzf. The result is
jj-fzf.
Since I tend to maintain a clean, linear history in my repositories,
I found myself switching between gitk and
git rebase -i way too much. With having
jj squash available at a single key press and
jj rebase where you can specify the source as
--branch, --source, --revisions and the target as
--destination, --insert-after, --insert-before, this has
become a thing of the past. But, since jj introduces
completely new ways to modify the history, having the constant feedback
that jj-fzf provides allowed me to grow the needed
understanding of how the history evolves after certain jj
command variants. All repository modifications carried out by
jj-fzf are printed to stderr, which helps a
lot in debugging and serves as a good learning aid.
A major game-changer for me was the Mega-Merge Workflow as
described by Benjamin Tan. With jj’s conflict handling,
this workflow enables to combine selected feature branches into a single
Mega-Merge
commit that the working copy is based on. This means I
can activate
or ignore feature branches as needed in my working
directory. I was pleasantly surprised by how few conflicts I encountered
with this workflow. At this point, when I do run into conflicts, I
almost never resolve them by editing the source code. Instead, conflicts
can usually be resolved with a few key presses in jj-fzf,
such as swapping commits (Alt+X), rebasing only a single
commit (Alt+R Alt+R), or splitting a commit interactively
before rebasing (Alt+I). Being able to jj undo
(Alt+Z) a rebase attempt or other jj
operations is a tremendous help.
jj-fzf 0.22.0:
So far jj-fzf has been residing in my
tools/ repository, but due to external demands it is now
migrated into its own repository and will get regular releases. I just
tagged the jj-fzf
0.22.0 release (which depends on jj-0.22.0).
Mega-Merge
Workflow:
I really recommend checking out this screencast demonstrating the Mega-Merge workflow.
It allows to combine selected feature branches into a single
Mega-Merge
commit that the working copy is based on. It begins by
creating a new commit (Ctrl+N) based on a feature branch
and then adds other feature branches as parents to the commit with the
parent editor (Alt+P). As part of the workflow, new commits
can be squashed (Alt+W) or rebased (Alt+R)
into the existing feature branches. To end up with a linear history, the
demo then shows how to merge a single branch into master
and rebases everything else to complete a work phase.
If you find jj-fzf to be interesting, leave a star in
the Github repository or hit me up with any questions you might have.
I’d love to hear about other experiences with jj,
jj-fzf and with the Mega-Merge
workflow!
Mega-Merge: