Edit your local history with jj, then run jj-stack submit to update the corresponding
pull requests on GitHub.
Edit a change in your stack
Find your stack’s head change ID with jj-stack list or jj log. Edit the change you want,
then resubmit using that head:
jj edit <change-id>
# make the requested changes
jj-stack submit <head-change-id>
Scroll through the full transcript
# Edit B while C depends on it
❯ jj edit wyturxyz
Working copy (@) now at: wyturxyz fb784c8d B: add API
Parent commit (@-) : tswswlmq 518c2932 A: refactor shared model
Added 0 files, modified 0 files, removed 1 files
❯ printf 'typed response\n' >> api.py
# Select C to update the whole stack, even while the working copy is at B
❯ jj-stack submit qtopwpxl
Submitted changes:
○ qtopwpxl C: add UI: pushed, PR #3 unchanged
│
@ wyturxyz B: add API: pushed, PR #2 unchanged
│
○ tswswlmq A: refactor shared model: already pushed, PR #1 unchanged
│
◆ oktnlvsz base
│
Top of stack: PR #3
# PR #1 is unchanged; B and C still have PRs #2 and #3
❯ jj-stack view qtopwpxl
Submitted stack (PR #3):
○ qtopwpxl C: add UI: PR #3
│
@ wyturxyz B: add API: PR #2
│
○ tswswlmq A: refactor shared model: PR #1
│
◆ oktnlvsz base
jj edit takes the change you want to edit. jj-stack submit takes the top of the stack you
want to publish. For a stack A → B → C, use B’s ID to edit B and C’s ID to submit the whole stack.
When you edit B, jj automatically rebases C onto it. Both changes keep their existing pull
requests and discussions. C’s PR branch also needs updating because the rebase changes its
commit ID, even if you haven’t edited C’s contents.
Reorder changes
Rearrange your work with jj, then inspect and submit the result. Since a different change
may now be at the top, use jj log to find the new head before submitting:
jj arrange
jj log
jj-stack view <head-change-id>
jj-stack submit <head-change-id>
Use the head change ID from the new order. jj-stack submit updates the PR order and base
branches to match. If you are moving changes between stacks, follow
multiple stacks for the submission order.
Split or squash
When you split a change, the part that keeps the original change ID also keeps its pull request. The new change gets a new PR on the next submit.
When you squash your changes, whichever change survives keeps its pull request. PRs for the
other changes remain open. Submit the changes you kept before closing and cleaning up those PRs,
following the order for abandoning a submitted change
below. jj-stack never reuses those PRs for different work.
Abandon one of your submitted changes
After jj abandon removes a change from your local history, its pull request and PR branch
remain on GitHub. Submit the remaining changes first so their PRs no longer depend on that branch,
then close and clean up the removed change’s PR.
For example, to remove B from A → B → C while keeping A and C, first note B’s PR number in the
stack view. Replace the change-ID placeholders with the IDs from jj log:
jj-stack view <C-change-id>
jj abandon <B-change-id>
Resolve any conflicts in C with jj, then submit the remaining A → C stack and clean up B’s PR.
Replace <B-pr> with the PR number you noted:
jj-stack submit <C-change-id>
jj-stack cleanup --pull-request <B-pr> --close
Submitting updates C’s base to A’s PR branch and removes B’s PR from the GitHub stack. Cleanup then closes B’s PR and removes its unused branch and saved link. A and C keep their PRs and discussions.
If no changes remain to submit, follow close an orphaned pull request. If cleanup keeps the branch, follow what to do when cleanup keeps a branch.
To close a whole stack, follow Separate a stack or close pull requests.