name: glab-stack
description: Manage stacked diffs and merge requests with the GitLab CLI. Use when the user wants to create, save, amend, sync, navigate, or reorder a stack of dependent merge requests. Triggers on tasks involving stacked diffs, stacked MRs, dependent merge requests, or incremental code review workflows using glab stack.
glab stack
glab stack is a feature of the GitLab CLI for managing stacked diffs — a series of small, dependent merge requests that build on each other to deliver a larger feature. Each entry in the stack is a separate branch with its own MR. Reviewers see only the diff for their layer; you keep building while earlier changes are in review.
Status: Experiment, released in GitLab CLI v1.42.0. The interface may change.
How glab stack works
glab stack uses a save-centric model: glab stack save bundles staging, committing, and branch creation into a single step. There are no separate Git operations for creating stack branches — the CLI manages branch creation automatically. Stack metadata lives in .git/stacked/ in the repo.
Each diff gets its own branch named {branch_prefix}-{stack-title}-{8-char-hex}. The branch prefix defaults to $USER (your local username), or can be set with glab config set branch_prefix <value>. The hash is generated at save time from the message, title, author, and timestamp — branch names are not sequential or predictable in advance. Use glab stack list to see the current branch names for each diff.
main (default branch)
└── karmstrong-add-auth-5b337685 → MR !1 (targets main) ← first diff (oldest)
└── karmstrong-add-auth-74f87791 → MR !2 (targets karmstrong-add-auth-5b337685)
└── karmstrong-add-auth-c3a91b02 → MR !3 (targets karmstrong-add-auth-74f87791) ← last diff (newest)
Stack names are sanitized on creation: spaces and special characters are replaced with dashes. The name "add auth feature" becomes add-auth-feature. Always use the sanitized form with glab stack switch.
You can have multiple named stacks per repo and switch between them with glab stack switch.
When to use stacks
Stacks work well when:
- A feature is large enough that a single MR would be hard to review
- Changes have a clear dependency order — data layer feeds the API layer feeds the UI
- You want to unblock reviewers on completed layers while you keep building
- Feedback on one layer shouldn't block progress on the layers above it
Each diff should represent a discrete, logical concern that can be reviewed independently. A reviewer reading the MRs in sequence should understand the progression as a cohesive story.
Agent rules
These commands launch interactive TUIs or prompt for input — they will hang:
- ❌
glab stack move— fuzzy-finder for selecting a diff; agents cannot interact with it - ❌
glab stack reorder— opens a text editor to reorder diffs; requires user interaction - ❌
glab stack savewithout-m— prompts interactively for a commit message if none is provided - ❌
glab stack amendwithout-m— prompts interactively for a description if none is provided - ❌
glab stack createwithout a name argument — may prompt
Always do the following:
- Always pass
-mtosaveandamend. This is the most common footgun — without it, the CLI prompts interactively and hangs. - Use
glab stack listto inspect the stack, notglab stack move.listis non-interactive;moveis not usable by agents. - Navigate with
first,last,prev,next. These are all non-interactive. Do not usemovefor navigation. - Pass an explicit name to
glab stack switch. Stack names are the directory names under.git/stacked/. Note:switchonly changes the active stack in config — it does not check out any branch. After switching, useglab stack last(orfirst,next, etc.) to move to a diff in the new stack. - If the user needs to reorder diffs, tell them to run
glab stack reorderin their terminal directly — agents cannot do this.
Stack structure
Plan your diff boundaries before writing code. Earlier diffs (closer to main) are the foundation; later diffs depend on them. If code in one diff depends on code in another, the dependency must be in the same diff or an earlier one.
save vs amend:
glab stack save— creates a new diff (new commit, new branch). Use when adding a new logical concern on top of what exists.glab stack amend— modifies the current diff. Use when addressing review feedback or fixing a mistake in the current layer.
Important: If you navigate to an earlier diff and run save instead of amend, the CLI will warn you but still proceed — appending the new diff to the end of the stack, not inserting it at the current position. Always use amend when you've navigated to a specific diff to address feedback. Only use save from the last diff in the stack.
For precise control over which files go into a diff, stage with git add <files> first, then glab stack save -m "...". For convenience, -a stages all tracked/modified files, and passing . stages everything including untracked files.
Quick reference
| Task | Command |
|---|---|
| Create a new stack | glab stack create <stack-name> |
| Save staged changes as a new diff | glab stack save -m "description" |
| Stage all tracked files and save | glab stack save -a -m "description" |
| Stage all files (incl. untracked) and save | glab stack save . -m "description" |
| Amend the current diff | glab stack amend -m "description" |
| Amend with all tracked files staged | glab stack amend -a -m "description" |
| Push branches and create/update MRs | glab stack sync |
| Sync and set reviewer/assignee/label | glab stack sync --reviewer <user> --assignee <user> --label <label> |
| Rebase stack onto latest base branch | glab stack sync --update-base |
| List all diffs in the current stack | glab stack list |
| Go to the oldest diff | glab stack first |
| Go to the newest diff | glab stack last |
| Step toward main | glab stack prev |
| Step away from main | glab stack next |
| Switch to a different stack | glab stack switch <stack-name> |
Core workflow
# 1. Create a stack for a feature
glab stack create add-authentication
# 2. Build the first layer (data model)
git add app/models/user.rb db/migrate/001_create_users.rb
glab stack save -m "Add user model and migration"
# 3. Build the second layer (API) — depends on the model above
git add app/controllers/sessions_controller.rb
glab stack save -m "Add session controller"
# 4. Build the third layer (UI) — depends on the API above
glab stack save . -m "Add login view and assets"
# 5. Push all branches and open MRs on GitLab
glab stack sync
After sync, each diff has its own MR: !1 targets main, !2 targets the !1 branch, and so on. Reviewers see only the delta for their layer.
sync fetches from origin first, then pushes each branch and creates or updates MRs. If a branch is detected as behind its remote (e.g., a reviewer applied a suggestion through the GitLab web UI), sync will pull those changes before pushing. You don't need to manually pull stack branches before syncing in the common case.
Setting reviewers, assignees, and labels: Pass --reviewer, --assignee, and --label flags to sync to set these on newly created MRs. If no --assignee is specified, new MRs are auto-assigned to the current authenticated user. These flags only affect MR creation — they do not update MRs that already exist. To update an existing MR, use glab mr update <mr-number>.
Merged and closed MRs: During sync, any MR that has been merged has its ref automatically removed from the stack. Closed MRs are flagged in output but not removed — the ref stays in the stack.
Rebasing onto an updated base branch: If the base branch (e.g., main) has moved forward, run glab stack sync --update-base to rebase the entire stack onto the latest base.
Merge diffs bottom-to-top. Always merge the first diff (oldest, closest to main) before merging the ones above it. When the first diff merges, sync automatically retargets the next MR onto main. If a middle diff is merged out of order, the lower MR will show a combined diff that doesn't belong to its layer — there's no clean automated recovery.
Responding to review feedback
# Navigate to the diff that needs changes
glab stack list # see all diffs and where you are
glab stack first # or: prev, next, last
# (make edits)
glab stack amend -a -m "Address review: improve null handling"
# Sync rebases all downstream diffs automatically
glab stack sync
Handling sync conflicts
If sync hits a conflict during rebase:
# Resolve conflict markers in affected files, then:
git add <resolved-files>
git rebase --continue
# Re-run sync to push the resolved stack
glab stack sync