stack

>

cameronjlarsen/stack2 installsMITSynced Aug 22

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: stack
description: >
license: MIT
---

# Stack

Use the local `stack` CLI for squash-safe stacked change repair. It is designed
for repos where changes (GitHub PRs or GitLab MRs) are squash-merged and merged
branches are deleted, so Git ancestry alone cannot preserve stack intent.

## Setup

Works against GitHub (via `gh`), GitLab (via `glab`), and Azure DevOps (via
`az repos pr` with the `azure-devops` extension). Install and authenticate the
matching CLI before running `stack`.

- `github.com`, `gitlab.com`, and cloud Azure DevOps hosts (`dev.azure.com`,
  `ssh.dev.azure.com`, legacy `{org}.visualstudio.com`) are detected
  automatically from `origin`.
- Enterprise or on-prem host: `git config stack.codeHost github|gitlab|azuredevops`
  (or `STACK_CODE_HOST` env override).
- Custom trunks: `git config stack.trunks dev,develop,main,master`.
- Drop the attribution link from stack blocks: `git config stack.blockLink false`.
- `--admin` is not supported on GitLab or Azure DevOps.
- Azure DevOps does not expose fork `headRepository` routing through `az repos pr`.
  Label-on-create uses REST after PR creation when supported; otherwise create still
  succeeds without labels. Run `stack doctor` to verify `az`, the `azure-devops`
  extension, and auth before sync or merge.

Keep ordinary editing and commits on plain `git`. Use `stack` only for stack
intent, inspection, sync, merge, and undo.

## Mental Model

```text
dev
└─ stack-a  #101
   └─ stack-b  #102
      └─ stack-c  #103
```

Stack intent is persisted in `.git/stack/state.json` as stack links (branch,
parent, merge-base anchor, change number). Mutating workflows write
`.git/stack/undo.json` so `stack undo --apply` can restore the previous state.
Do not edit these files by hand — run `stack sync` to preview, `stack sync --apply` to fix.

## Happy Path

Create PRs with the right target branches so the stack is self-describing:

```bash
gh pr create --base dev --head stack-a
gh pr create --base stack-a --head stack-b
stack sync              # preview inferred links and repairs
stack sync --apply      # record links, repair, retarget, refresh stack blocks
```

GitLab:

```bash
glab mr create --source-branch stack-a --target-branch dev --title "stack-a"
glab mr create --source-branch stack-b --target-branch stack-a --title "stack-b"
stack sync
stack sync --apply
```

Azure DevOps:

```bash
az repos pr create --source-branch stack-a --target-branch dev --title "stack-a" --squash true
az repos pr create --source-branch stack-b --target-branch stack-a --title "stack-b" --squash true
stack sync
stack sync --apply
```

That's the common loop. `stack sync` previews; `stack sync --apply` does the
work. Repeat after any parent branch changes or a squash merge lands.

## Commands

- `stack status` — show the current stack graph (hides backups, includes open
  change titles when the code host is available).
- `stack skill` — print this skill for AI agent discovery.
- `stack doctor` — check Git, code-host access, stack metadata, trunks, and undo
  journal health without mutating anything. For Azure DevOps, doctor also checks
  `az`, the `azure-devops` extension, and pull-request access.
- `stack track <branch> --onto <parent>` — manually record stack intent only
  when target branches don't already encode it.
- `stack sync [branch]` — preview inferred links and repairs (non-mutating).
  Scopes to the current stack if no branch is given.
- `stack sync --apply [branch]` — infer links, remove stale links, repair
  descendants, retarget changes, refresh stack blocks, show a tree summary.
- `stack sync --apply --keep-going` — process independent stacks separately,
  report successes and failures, exit nonzero if any failed.
- `stack merge [branch]` — dry-run root merge plus descendant repair. Infers
  the root from the current branch.
- `stack merge --apply` — retarget child changes, squash-merge the root, repair
  descendants.
- `stack merge --auto` — retarget children, enable code-host auto-merge, wait,
  then repair descendants.
- `stack merge --auto --through <branch-or-change>` — repeat auto-merge one root
  at a time until the target lands.
- `stack history` — show the most recent applied repair journal.
- `stack undo` — dry-run restore of the last applied mutation.
- `stack undo --apply` — restore branch tips, change targets, and stack metadata.

## Stack Blocks

`stack sync --apply` and `stack merge --apply/--auto` refresh a deterministic
block in each open change description:

```md
<!-- stack:links:start -->

### [Stack](https://github.com/kitlangton/stack)

1. #101
2. #102
3. **#103** 👈 current
<!-- stack:links:end -->
```

Earlier entries are landed history. The current change is bold with `👈 current`.
GitHub uses `#123`; GitLab uses `!123 - Title`; Azure DevOps uses `!123` (`#`
in ADO descriptions links to work items).

## Safety Rules

- Bare `stack sync` never mutates branches, changes, or stack metadata.
- `stack merge` is dry-run by default.
- Mutating commands need `--apply` (except `merge --auto`, which waits for the
  code host and repairs after the root lands).
- Never mutate trunk branches (`dev`, `main`, `master`, or any configured trunk).
- Before rebasing, the tool creates a local backup branch.
- Clean sibling worktrees can own branches being repaired or cleaned up; dirty
  sibling owners fail before mutation.
- If a replay fails, the tool aborts the cherry-pick, restores the original
  branch, keeps backups and the undo journal, and tells you which branch to
  repair before running `stack sync --apply` again.
- If output is unclear, inspect with `stack status`, `stack history`, or command
  help before applying.

More Debugging skills

← All Debugging skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY