Edit Mid-Stack Commits
This is the workflow Git makes painful and JJ makes trivial.
This tutorial shows how to modify commits that aren’t at the top of your stack—a common need when responding to PR feedback. Research shows 18 out of 20 major JJ resources praise automatic rebasing as the killer feature.
The Scenario
You have a stack of three commits:
@ xyz user-api "Add user API endpoints"○ abc user-model "Add user model"○ def db-schema "Add user database schema"A reviewer requests changes to the user-model commit (abc). Here’s how to handle it.
Step 1: Navigate to the Commit
Use jj edit with the change ID:
jj edit abcNow your working copy is the user-model commit.
Step 2: Make Your Changes
Edit files normally:
vim src/models/user.jsvim src/models/user.test.jsThere’s no staging or amending needed. In JJ, your working copy is the commit. Changes are automatically part of it.
Step 3: Verify Changes
Check that your changes are in:
jj diff # See changes in current commitjj status # See overall statusStep 4: Return to Top
Go back to the top of your stack:
jj stack-topStep 5: Push Updates
Push your updated stack:
jj stack-submitAll PRs in the stack will be updated.
What Happens Automatically
When you edit a mid-stack commit, JJ automatically:
- Rebases dependent commits - The
user-apicommit is rebased on top of your modifieduser-model - Updates bookmarks - Bookmark pointers are adjusted
- Detects conflicts - If your change conflicts with later commits, JJ marks them
This is jj’s killer feature. Research across 20+ guides consistently highlights automatic rebasing as the workflow transformation that makes developers rave about JJ.
In Git, you’d manually:
git rebase -ito mark the commit for editinggit commit --amendto modify itgit rebase --continueto finish- Resolve conflicts at each step
- Force push all affected branches
In JJ, it’s automatic. Edit the commit, descendants rebase.
Complete Example
# View your stackjj stack-view# @ xyz user-api "Add user API endpoints"# ○ abc user-model "Add user model"# ○ def db-schema "Add user database schema"
# Edit the middle commitjj edit abc
# Make your changesvim src/models/user.js
# Check the diffjj diff
# Return to topjj stack-top
# View updated stack - notice xyz has been rebasedjj stack-view
# Push all updatesjj stack-submitHandling Conflicts
If your changes conflict with later commits:
# After editing a mid-stack commitjj stack-topjj status# May show: "Commit xyz has conflicts"
# View which commits have conflictsjj log -r "stack"
# Navigate to the conflicted commitjj edit xyz
# Resolve conflictsjj resolve
# Push updatesjj stack-submitWhat if my edit creates conflicts? See the Conflicts tutorial for details on JJ’s first-class conflict handling. Unlike Git, conflicts don’t block you—you can keep working and resolve them later.
Editing Multiple Commits
If you need to edit several commits:
# Edit first commitjj edit abcvim src/models/user.js
# Edit another commitjj edit defvim src/database/schema.sql
# Return to topjj stack-top
# Push everythingjj stack-submitTips
Check the Diff Before Pushing
After editing, verify your changes:
# See all changes in the stack relative to trunkjj diff -r "trunk..@"
# Or see changes in specific commitjj diff -r "abc"Use Status to Confirm
jj statusShows:
- Current commit
- Any pending changes
- Conflict status
Don’t Forget to Push
After editing mid-stack, your remote PRs are out of date:
jj stack-submit # Updates all PRsWhy This Is Easier Than Git
In Git, editing a mid-stack commit requires:
git rebase -ito mark the commit for editinggit commit --amendto modify itgit rebase --continueto finish- Resolving conflicts manually at each step
- Force pushing all affected branches
In JJ, it’s just:
jj edit <commit>- Make changes
jj stack-submit
JJ handles all the rebasing automatically.
Next Steps
- Learn about Syncing with Remote
- See Stack Workflow Reference
- Check out GitHub Integration
Ernesto Jiménez