Skip to content

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:

Terminal window
jj edit abc

Now your working copy is the user-model commit.

Step 2: Make Your Changes

Edit files normally:

Terminal window
vim src/models/user.js
vim src/models/user.test.js

There’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:

Terminal window
jj diff # See changes in current commit
jj status # See overall status

Step 4: Return to Top

Go back to the top of your stack:

Terminal window
jj stack-top

Step 5: Push Updates

Push your updated stack:

Terminal window
jj stack-submit

All PRs in the stack will be updated.

What Happens Automatically

When you edit a mid-stack commit, JJ automatically:

  1. Rebases dependent commits - The user-api commit is rebased on top of your modified user-model
  2. Updates bookmarks - Bookmark pointers are adjusted
  3. 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:

  1. git rebase -i to mark the commit for editing
  2. git commit --amend to modify it
  3. git rebase --continue to finish
  4. Resolve conflicts at each step
  5. Force push all affected branches

In JJ, it’s automatic. Edit the commit, descendants rebase.

Complete Example

Terminal window
# View your stack
jj 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 commit
jj edit abc
# Make your changes
vim src/models/user.js
# Check the diff
jj diff
# Return to top
jj stack-top
# View updated stack - notice xyz has been rebased
jj stack-view
# Push all updates
jj stack-submit

Handling Conflicts

If your changes conflict with later commits:

Terminal window
# After editing a mid-stack commit
jj stack-top
jj status
# May show: "Commit xyz has conflicts"
# View which commits have conflicts
jj log -r "stack"
# Navigate to the conflicted commit
jj edit xyz
# Resolve conflicts
jj resolve
# Push updates
jj stack-submit

What 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:

Terminal window
# Edit first commit
jj edit abc
vim src/models/user.js
# Edit another commit
jj edit def
vim src/database/schema.sql
# Return to top
jj stack-top
# Push everything
jj stack-submit

Tips

Check the Diff Before Pushing

After editing, verify your changes:

Terminal window
# See all changes in the stack relative to trunk
jj diff -r "trunk..@"
# Or see changes in specific commit
jj diff -r "abc"

Use Status to Confirm

Terminal window
jj status

Shows:

  • Current commit
  • Any pending changes
  • Conflict status

Don’t Forget to Push

After editing mid-stack, your remote PRs are out of date:

Terminal window
jj stack-submit # Updates all PRs

Why This Is Easier Than Git

In Git, editing a mid-stack commit requires:

  1. git rebase -i to mark the commit for editing
  2. git commit --amend to modify it
  3. git rebase --continue to finish
  4. Resolving conflicts manually at each step
  5. Force pushing all affected branches

In JJ, it’s just:

  1. jj edit <commit>
  2. Make changes
  3. jj stack-submit

JJ handles all the rebasing automatically.

Next Steps

Project by Ernesto Jiménez Ernesto Jiménez Bluesky GitHub