Remarque
This feature is in public preview and subject to change.
As you iterate on a stack, you often need to make changes in a lower layer, rebase to keep a linear history, or restructure its branches. The gh stack extension in GitHub CLI handles these tasks with cascading operations that update every affected branch. See Stacked pull requests CLI commands.
Making changes to a lower layer
When you are working on the top layer and need to change something lower in the stack, make the change in the branch it belongs in and rebase, rather than working around it at the current layer.
-
Navigate to the branch that needs the change.
Shell gh stack down
gh stack downYou can also check out a specific branch with
gh stack checkout BRANCH-NAME. -
Make the change and commit it.
Shell git add . git commit -m "helpful-commit-message"
git add . git commit -m "helpful-commit-message" -
Rebase the branches above to pick up the change.
Shell gh stack rebase --upstack
gh stack rebase --upstack -
Push the updated branches and return to where you were working.
Shell gh stack push gh stack top
gh stack push gh stack top
Rebasing your stack
A stack must have a linear history between its branches before it can merge. Running gh stack rebase performs a cascading rebase where each branch is rebased on top of the branch below it, starting from main, so every branch picks up the latest changes from all lower layers.
-
Rebase the stack. By default, this rebases every branch from the bottom to the top.
Shell gh stack rebase
gh stack rebaseTo limit the rebase, use
--downstackto rebase from the lowest layer up to the current branch, or--upstackto rebase from the current branch up to the top. -
Push the updated branches. This uses
--force-with-leaseto safely update the rebased branches.Shell gh stack push
gh stack push
If a rebase encounters a conflict, gh stack rebase stops and lists the conflicted files.
- Resolve the markers in the affected files, stage them with
git add, then rungh stack rebase --continue. - To start over, run
gh stack rebase --abortto restore all branches to their pre-rebase state.
Remarque
You can also trigger a server-side rebase from the pull request, but those commits are not signed. If your repository requires signed commits, rebase from GitHub CLI so the commits follow your local Git commit signature configuration.
Rebasing from the GitHub website
When a stack is not linear, a Rebase stack button appears in the merge box. Selecting it triggers a server-side cascading rebase that:
- Rebases the entire stack on top of the latest trunk, such as
main. - Rebases every unmerged branch on top of its base branch, working from the bottom of the stack upward.
- Force-pushes each rebased branch to update the remote.
After the rebase completes, every pull request reflects the updated branches and CI checks are re-triggered.
Remarque
Commits created by a server-side rebase are not signed. If your repository requires signed commits, rebase from GitHub CLI with gh stack rebase so the commits follow your local Git commit signature configuration, then push with gh stack push.
Restructuring a stack
You may want to change the composition of a stack. For example if you need to drop a branch, combine branches, insert a branch, reorder, or rename, use the interactive command gh stack modify.
Before you run gh stack modify, ensure the following:
- You have an active stack checked out.
- Your working tree is clean.
- No rebase is in progress.
- No pull request is queued to merge.
- The commit history is linear.
-
Open the modify terminal UI.
Shell gh stack modify
gh stack modify -
Select a branch and stage an operation. Reordering and structural changes (drop, fold, insert, rename) cannot be mixed in the same session.
x— drop a branch and its commitsd— fold the branch into the one below itu— fold the branch into the one above iti/I— insert a new branch below or above the cursorr— rename a branch- Shift+↑ / Shift+↓ — reorder a branch
z— undo the last staged action
-
Apply your staged changes by saving. Nothing is modified until you save.
Use ctrl/cmd+s.
If a conflict occurs while applying, resolve it and run
gh stack modify --continue, or rungh stack modify --abortto restore the pre-modify state. -
Push the updated branches and recreate the stack on GitHub.
Shell gh stack submit
gh stack submit
Unstacking from the GitHub website
To dissolve a stack from the website, for example to reorder or reorganize it, use the Unstack option on the stack.
Unstacking removes the open, draft, and closed pull requests from the stack. Each keeps its current base branch but is no longer linked to the others, and the stack map and stack merge requirements disappear from them.
Merged and queued pull requests stay in the stack. Once a pull request has merged, or is queued for merge, as part of a stack, it can't be unstacked. A stack is dissolved entirely only when none of its pull requests have merged or are queued for merge; otherwise it persists with those pull requests still in it.
To reorder or restructure a stack without dissolving it, use the gh stack modify command instead. See Restructuring a stack.
Syncing your local environment after merges
When a pull request at the bottom of the stack merges, update your local state with a single sync command. To automatically prune local branches for merged pull requests at the same time, add the --prune option.
gh stack sync --prune
gh stack sync --prune
This fetches the latest changes, fast-forwards the trunk, rebases the remaining branches onto it, pushes the updated branches, and syncs the pull request status from GitHub.
Pulling in pull requests added to the stack on GitHub
If someone else adds pull requests to the stack on GitHub, gh stack sync fetches the new branches and appends them to your local stack so it mirrors the remote. A clean remote-ahead update like this is pulled down automatically, so gh stack sync is safe to run in automation.
Resolving a diverged stack
Your local and remote stacks diverge when neither is a clean extension of the other, for example, when you add a branch locally while different pull requests are added to the same stack on GitHub. When this happens, gh stack sync can't merge the two automatically. In an interactive terminal, it offers three choices:
- Use the remote stack as the source of truth. Replaces your local stack composition with the remote's, pulling any missing branches. If you were on a branch the remote stack no longer contains, you're moved to the nearest surviving branch. This requires a clean working tree with no uncommitted changes.
- Delete the stack on GitHub. Deletes the stack object on GitHub and stops the sync. Your pull requests and local branches are untouched. Recreate the stack with
gh stack submit, which also creates pull requests for any branches you haven't submitted yet. Rungh stack modifyfirst if you want to change its structure. - Cancel. Aborts the sync without pushing branches or updating any pull requests.
In a non-interactive terminal, such as CI, a divergence aborts the sync without pushing branches or updating pull requests. Resolve it by unstacking and recreating the stack.