Let `jj absorb` help you keep a clean commit history
38 points by paulsmith
38 points by paulsmith
Reminder that Lobsters named this feature! (originally for Mercurial)
https://lobste.rs/s/nws1uj/help_us_name_new_mercurial_feature
It’s a feature that doesn’t exist in Git and would be difficult to replicate, so it’s a great example of the power of jj’s design
There is this and it does work, but it’s a bit clunky.
It’s a feature that doesn’t exist in Git and would be difficult to replicate, so it’s a great example of the power of jj’s design
There is this and it does work, but it’s a bit clunky.
As an example of even earlier prior art, git-autofixup exists.
Changed that sentence on the post, thanks - gave me a chance to use jj absorb
on the blog repo itself ;^)
Oddly, the thing I dislike most about absorb
is that its two letter abbreviation clashes with abandon
. I’m new enough at jj to not have a history of which came first, but that seems like an annoying mistake to me.
Slightly off topic, but I’m wondering if anyone has advice on transitioning to jj as a git user that frequently rewrites local history. My typical git workflow looks something like:
git pull --rebase
git push -f
(ya I know Github tends to lose revision history along with associated comments)Has anyone who had a similar workflow made the transition? I tried jj on a small personal project a while back and ran into some friction with rewriting history, but it’s been long enough that I can’t provide specific, actionable details.
This is basically my normal workflow (minus the -f
) and it’s a bit simpler in jj because it more closely matches the way jj “thinks”:
jj new
jj new
and then later pull it back in (“amend”) with jj squash
Yes! The effortlessness of this process is one of the beautiful things about jj
. There’s no need for a branch, of course. There’s also no need to amend the commit (you’re always “amending” the currently-editing change). You just new
whenever you start a thought, squash
/split
/absorb
as needed to organize, and rebase --insert-before/after
to reorder.
I just leave jjui
up all the time in a terminal window and am constantly in there rearranging, splitting, and squashing before I push anything. It makes it really easy — r
for rebase, a
for after, cursor down, return, done!
Another technique when I find a bug is to just cursor down to the change for the relevant code, new
on that change, fix the bug, and squash
the fix back into that change. Basically git commit --fixup
with much less hassle. If things go sideways, just abandon
the fix and start over.
Edit: This may not be obvious: you don’t even need to do this all the time, because you can directly edit a change that isn’t the topmost one. If you don’t need the later stuff for what you’re working on, you can just work inside that change and let the magical auto-rebasing do its thing for the later ones.
Edit: And git push -f
is just jj bookmark move branchname -t @ --allow-backwards; jj git push
. Or, in jjui
, for the most recent bookmark, just b
, m
, enter
, esc
, g
, p
, enter
.
I have a special dispensation in my config so I don’t need to do anything special to force push “my” branches (ones with wrs
in them):
[revset-aliases]
# Don't allow force-push to any remote branches that aren't "mine"
'immutable_heads()' = '(present(trunk()) | tags() | remote_bookmarks()) & ~remote_bookmarks("wrs")'