Let's say you've got a few feature branches, all based of the trunk branch.
$ jj
@ ozywpwxm samfredrickson@gmail.com 2025-08-31 13:21:59 b2f1364d
│ (empty) (no description set)
│ ○ qxoklwxv samfredrickson@gmail.com 2025-08-31 13:21:27 9cda0936
├─╯ (empty) Feature C
│ ○ ukqynvts samfredrickson@gmail.com 2025-08-31 13:21:26 ceee7029
├─╯ (empty) Feature B
│ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 13:21:24 9ccbedf6
├─╯ (empty) Feature A
◆ yxuvtolz samfredrickson@gmail.com 2025-08-27 09:49:16 master git_head() 8e80b150
│ Update Claude Code to 1.0.93.
One neat workflow supported by Jujutsu is "working on all branches at the same time." $ jj new q u n
Working copy (@) now at: zzxxqlzr fb73d4dc (empty) (no description set)
Parent commit (@-) : qxoklwxv 9cda0936 (empty) Feature C
Parent commit (@-) : ukqynvts ceee7029 (empty) Feature B
Parent commit (@-) : nwtxnvxp 9ccbedf6 (empty) Feature A
$ jj
@ rzouzmyw samfredrickson@gmail.com 2025-08-31 13:25:56 fb73d4dc
├─┬─╮ (empty) (no description set)
│ │ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 13:21:24 9ccbedf6
│ │ │ (empty) Feature A
│ ○ │ ukqynvts samfredrickson@gmail.com 2025-08-31 13:21:26 ceee7029
│ ├─╯ (empty) Feature B
○ │ qxoklwxv samfredrickson@gmail.com 2025-08-31 13:21:27 git_head() 9cda0936
├─╯ (empty) Feature C
◆ yxuvtolz samfredrickson@gmail.com 2025-08-27 09:49:16 master 8e80b150
│ Update Claude Code to 1.0.93.
~
Now you can use the merge revision as a scratch space, and then squash changes from it into one of the feature revisions. $ vim README.md
$ jj squash --into n
Working copy (@) now at: rzouzmyw 30ff9b0f (empty) (no description set)
Parent commit (@-) : qxoklwxv 9cda0936 (empty) Feature C
Parent commit (@-) : ukqynvts ceee7029 (empty) Feature B
Parent commit (@-) : nwtxnvxp fb3cca28 Feature A
$ jj
@ rzouzmyw samfredrickson@gmail.com 2025-08-31 13:27:41 30ff9b0f
├─┬─╮ (empty) (no description set)
│ │ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 13:27:41 fb3cca28
│ │ │ Feature A
│ ○ │ ukqynvts samfredrickson@gmail.com 2025-08-31 13:21:26 ceee7029
│ ├─╯ (empty) Feature B
○ │ qxoklwxv samfredrickson@gmail.com 2025-08-31 13:21:27 git_head() 9cda0936
├─╯ (empty) Feature C
◆ yxuvtolz samfredrickson@gmail.com 2025-08-27 09:49:16 master 8e80b150
│ Update Claude Code to 1.0.93.
Later, you decide to fetch changes from your remote, and notice that your revisions are based on an out-of-date version of the trunk. $ jj git fetch
remote: Enumerating objects: 17, done.
remote: Total 12 (delta 6), reused 0 (delta 0), pack-reused 0
bookmark: master@origin [updated] tracked
$ jj
@ rzouzmyw samfredrickson@gmail.com 2025-08-31 13:27:41 30ff9b0f
├─┬─╮ (empty) (no description set)
│ │ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 13:27:41 fb3cca28
│ │ │ Feature A
│ ○ │ ukqynvts samfredrickson@gmail.com 2025-08-31 13:21:26 ceee7029
│ ├─╯ (empty) Feature B
○ │ qxoklwxv samfredrickson@gmail.com 2025-08-31 13:21:27 git_head() 9cda0936
├─╯ (empty) Feature C
│ ◆ zvpmmzru samfredrickson@gmail.com 2025-08-29 15:59:55 master 658a3d12
│ │ Update Claude Code to 1.0.98.
│ ~ (elided revisions)
├─╯
◆ yxuvtolz samfredrickson@gmail.com 2025-08-27 09:49:16 8e80b150
│ Update Claude Code to 1.0.93.
~
With Jujutsu, you can run one command to rebase _everything_ against the latest trunk revision. $ jj rebase -s 'roots(trunk()..mutable())' -d 'trunk()'
Rebased 4 commits to destination
Working copy (@) now at: rzouzmyw 88ed8085 (empty) (no description set)
Parent commit (@-) : qxoklwxv 005442c3 (empty) Feature C
Parent commit (@-) : ukqynvts 23923cf2 (empty) Feature B
Parent commit (@-) : nwtxnvxp 769d0539 Feature A
Added 0 files, modified 2 files, removed 0 files
$ jj
@ rzouzmyw samfredrickson@gmail.com 2025-08-31 13:32:08 88ed8085
├─┬─╮ (empty) (no description set)
│ │ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 13:32:08 769d0539
│ │ │ Feature A
│ ○ │ ukqynvts samfredrickson@gmail.com 2025-08-31 13:32:08 23923cf2
│ ├─╯ (empty) Feature B
○ │ qxoklwxv samfredrickson@gmail.com 2025-08-31 13:32:08 git_head() 005442c3
├─╯ (empty) Feature C
◆ zvpmmzru samfredrickson@gmail.com 2025-08-29 15:59:55 master 658a3d12
│ Update Claude Code to 1.0.98.
~
I use this command so much that it's aliased as "jjsr", "Jujutsu Super Rebase".The "super rebase" seams to be nice though. However I just tested it and achieved the same with git rebase --rebase-merges --update-refs. Have I missed something?
Anyway, I just tried that command you suggested, but it didn't seem to work?
$ jj new
$ jj bookmark create woot -r @-
$ jj
@ wxkrvmxs samfredrickson@gmail.com 2025-08-31 14:53:19 4bbb7f5a
│ (empty) (no description set)
○ rzouzmyw samfredrickson@gmail.com 2025-08-31 13:27:41 woot git_head() 30ff9b0f
├─┬─╮ (empty) (no description set)
│ │ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 13:27:41 fb3cca28
│ │ │ Feature A
│ ○ │ ukqynvts samfredrickson@gmail.com 2025-08-31 13:21:26 ceee7029
│ ├─╯ (empty) Feature B
○ │ qxoklwxv samfredrickson@gmail.com 2025-08-31 13:21:27 9cda0936
├─╯ (empty) Feature C
│ ◆ zvpmmzru samfredrickson@gmail.com 2025-08-29 15:59:55 master 658a3d12
│ │ Update Claude Code to 1.0.98.
│ ~ (elided revisions)
├─╯
◆ yxuvtolz samfredrickson@gmail.com 2025-08-27 09:49:16 8e80b150
│ Update Claude Code to 1.0.93.
~
$ git checkout woot
$ git log --graph
*-. commit 30ff9b0f274c9adaca4eeadcf21d5e918e4e3578 (HEAD -> woot)
|\ \ Merge: 9cda093 ceee702 fb3cca2
| | | Author: Sam Fredrickson <samfredrickson@gmail.com>
| | | Date: Sun Aug 31 13:27:41 2025 -0700
| | |
| | * commit fb3cca2823b4dffe374b67d28e3c91c206828d47
| | | Author: Sam Fredrickson <samfredrickson@gmail.com>
| | | Date: Sun Aug 31 13:21:24 2025 -0700
| | |
| | | Feature A
| | |
| * | commit ceee7029730c49ae30890c1641c7d6645e60fca4
| |/ Author: Sam Fredrickson <samfredrickson@gmail.com>
| | Date: Sun Aug 31 13:21:26 2025 -0700
| |
| | Feature B
| |
* | commit 9cda09363efe257a954b5563ce6af287a506d808
|/ Author: Sam Fredrickson <samfredrickson@gmail.com>
| Date: Sun Aug 31 13:21:27 2025 -0700
|
| Feature C
|
* commit 8e80b15010c4d9373c5828fdf8a83c53df75ec00
| Author: Sam Fredrickson <samfredrickson@gmail.com>
| Date: Wed Aug 27 09:48:45 2025 -0700
|
| Update Claude Code to 1.0.93.
$ git rebase --rebase-merges --update-refs master
Trying simple merge with cfa85486fa3d53401be518cb42936fb6fd3c128c
Trying simple merge with ffebef1cb34ca1670b48c594b2014e71be7d1b2b
error: Empty commit message.
Not committing merge; use 'git commit' to complete the merge.
Could not apply 30ff9b0... rev-ceee702 rev-fb3cca2 #
$ git status
interactive rebase in progress; onto 658a3d1
Last commands done (10 commands done):
pick 9cda093 # Feature C # empty
merge -C 30ff9b0f274c9adaca4eeadcf21d5e918e4e3578 rev-ceee702 rev-fb3cca2 #
(see more in file .git/rebase-merge/done)
No commands remaining.
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: README.md
$ jj
Reset the working copy parent to the new Git HEAD.
@ tymwqlyq samfredrickson@gmail.com 2025-08-31 14:57:22 d083f61e
│ (no description set)
○ vmnnlqro samfredrickson@gmail.com 2025-08-31 14:56:55 git_head() f92f7505
│ (empty) Feature C
◆ zvpmmzru samfredrickson@gmail.com 2025-08-29 15:59:55 master 658a3d12
│ Update Claude Code to 1.0.98.
~ (elided revisions)
│ ○ rzouzmyw samfredrickson@gmail.com 2025-08-31 13:27:41 woot 30ff9b0f
│ ├─┬─╮ (empty) (no description set)
│ │ │ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 13:27:41 fb3cca28
├─────╯ Feature A
│ │ ○ ukqynvts samfredrickson@gmail.com 2025-08-31 13:21:26 ceee7029
├───╯ (empty) Feature B
│ ○ qxoklwxv samfredrickson@gmail.com 2025-08-31 13:21:27 9cda0936
├─╯ (empty) Feature C
◆ yxuvtolz samfredrickson@gmail.com 2025-08-27 09:49:16 8e80b150
│ Update Claude Code to 1.0.93.
~
Maybe I'm using the git command incorrectly?Also, though, I'm assuming that git command will only rebase the branch you have currently checked out, whereas the jj command I gave will rebase _everything_, not just revisions that are parents of HEAD.
Edit: I figured out my issue. Git doesn't like empty commits & merge commits with no description. After addressing that, then the `git rebase --rebase-merges --update-refs master` command worked.
There's still the caveat though that the Git command will only rebase the "woot" branch. If I had some other "feature D" commit that wasn't included in "woot", that commit wouldn't be rebased. But the `jjsr` command would see and rebase that commit as well.
$ jj
@ qsvwusnk samfredrickson@gmail.com 2025-08-31 16:17:35 6fd02707
│ (empty) (no description set)
○ rzouzmyw samfredrickson@gmail.com 2025-08-31 16:17:35 woot git_head() e6d64886
├─┬─╮ (empty) Merge
│ │ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 13:27:41 fb3cca28
│ │ │ Feature A
│ ○ │ ukqynvts samfredrickson@gmail.com 2025-08-31 16:16:36 9957dca2
│ ├─╯ Feature B
○ │ qxoklwxv samfredrickson@gmail.com 2025-08-31 16:16:44 4361de8b
├─╯ Feature C
│ ○ nwoxyzlx samfredrickson@gmail.com 2025-08-31 16:14:42 ce8de62d
├─╯ Feature D
│ ◆ zvpmmzru samfredrickson@gmail.com 2025-08-29 15:59:55 master 658a3d12
│ │ Update Claude Code to 1.0.98.
│ ~ (elided revisions)
├─╯
◆ yxuvtolz samfredrickson@gmail.com 2025-08-27 09:49:16 8e80b150
│ Update Claude Code to 1.0.93.
~
$ git checkout woot
Switched to branch 'woot'
$ git rebase --rebase-merges --update-refs master
Trying simple merge with f339926f729437f78ac407c28fc84ce3b0441eb7
Trying simple merge with 4372b2c4f538164a10bb9d8e81899bf61eeecaf2
Merge made by the 'octopus' strategy.
Successfully rebased and updated refs/heads/woot.
$ jj
Reset the working copy parent to the new Git HEAD.
Abandoned 4 commits that are no longer reachable.
Done importing changes from the underlying Git repo.
@ zlxqyrmq samfredrickson@gmail.com 2025-08-31 16:17:59 970c80f8
│ (empty) (no description set)
○ qumulkxr samfredrickson@gmail.com 2025-08-31 16:17:42 woot git_head() cc189c82
├─┬─╮ (empty) Merge
│ │ ○ vkuwsssr samfredrickson@gmail.com 2025-08-31 16:17:42 4372b2c4
│ │ │ Feature A
│ ○ │ lmsrxxzm samfredrickson@gmail.com 2025-08-31 16:17:42 f339926f
│ ├─╯ Feature B
○ │ wrsnrokn samfredrickson@gmail.com 2025-08-31 16:17:42 53ec4dc0
├─╯ Feature C
◆ zvpmmzru samfredrickson@gmail.com 2025-08-29 15:59:55 master 658a3d12
│ Update Claude Code to 1.0.98.
~ (elided revisions)
│ ○ nwoxyzlx samfredrickson@gmail.com 2025-08-31 16:14:42 ce8de62d
├─╯ Feature D
◆ yxuvtolz samfredrickson@gmail.com 2025-08-27 09:49:16 8e80b150
│ Update Claude Code to 1.0.93.
~
Versus: $ jjsr
Rebased 6 commits to destination
Working copy (@) now at: qsvwusnk e793b1e4 (empty) (no description set)
Parent commit (@-) : rzouzmyw 3927be34 woot | (empty) Merge
Added 0 files, modified 2 files, removed 0 files
$ jj
@ qsvwusnk samfredrickson@gmail.com 2025-08-31 16:18:58 e793b1e4
│ (empty) (no description set)
○ rzouzmyw samfredrickson@gmail.com 2025-08-31 16:18:58 woot git_head() 3927be34
├─┬─╮ (empty) Merge
│ │ ○ nwtxnvxp samfredrickson@gmail.com 2025-08-31 16:18:58 12f659cf
│ │ │ Feature A
│ ○ │ ukqynvts samfredrickson@gmail.com 2025-08-31 16:18:58 5c0ce98f
│ ├─╯ Feature B
○ │ qxoklwxv samfredrickson@gmail.com 2025-08-31 16:18:58 f9f217e8
├─╯ Feature C
│ ○ nwoxyzlx samfredrickson@gmail.com 2025-08-31 16:18:58 373d6ab1
├─╯ Feature D
◆ zvpmmzru samfredrickson@gmail.com 2025-08-29 15:59:55 master 658a3d12
│ Update Claude Code to 1.0.98.
~