Maintains dependent GitHub PR stacks. Use for restacking, repairing PR bases, or coordinating stack merges and merge queues.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add edmundmiller/dotfiles --skill stack-maintenance --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Stack Maintenance?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/edmundmiller-stack-maintenance)More formats (shields.io, HTML) on the badges page.
---
name: stack-maintenance
description: Maintains dependent GitHub PR stacks. Use for restacking, repairing PR bases, or coordinating stack merges and merge queues.
---
# Stack Maintenance
Keep stacked GitHub pull requests boring: map the real stack, act from the bottom, verify after every remote action, and rewrite branches only with a lease.
Use this skill for PR chains, dependent branches, branch retargeting, merge queues, stale parent branches, and review/merge triage. Prefer existing stack tools (`gh stack`, `gh pr stack`, `jj spr`) when the repository has them; fall back to plain `gh` and `git` only after confirming the tool is unavailable or insufficient.
## Rules From Prior Stacked PR Incidents
- Trust fresh GitHub metadata, not memory. Fetch `baseRefName`, `headRefName`, `mergeStateStatus`, `mergeable`, `reviewDecision`, checks, and auto-merge state before acting.
- For evidence, compare against the PR head from GitHub (`headRefOid` or `origin/<headRefName>` after fetch), not just a local branch; local branches can be stale.
- Stacked PRs usually merge bottom-up. A child can become conflicted after its parent merges; expect to rebase or retarget it before merging.
- `mergeable` and `CLEAN` mean mergeable into the current `baseRefName`, not necessarily into `main`. Report the base explicitly in triage.
- Do not recommend `gh pr merge` for a PR whose base is another stack branch unless the intent is to merge into that parent branch; otherwise retarget or wait for the parent to land first.
- `gh pr merge --auto --squash` can merge immediately for intermediate stack branches. Re-read the PR afterward; do not infer from command text.
- Main may use a merge queue. If GitHub says the merge strategy is controlled by the queue, retry without an explicit strategy, then re-read `state`, `mergedAt`, and `mergeCommit`.
- Do not approve a PR before reviewing its diff and running the relevant local check. "Clean" only means mergeable, not reviewed.
- Use `--delete-branch=false` for stack branches unless the user explicitly asks to prune. Other PRs may still depend on them.
- Use `git push --force-with-lease`, never plain force, after rebasing a PR branch.
- Stop before rewriting someone else's branch unless ownership and permission are clear.
## Map The Stack First
Start with the current checkout and remote state:
```sh
git status --short --branch
git fetch origin --prune
```
List open PRs with the fields that matter:
```sh
gh pr list --state open --limit 100 \
--json number,title,author,baseRefName,headRefName,isDraft,mergeable,mergeStateStatus,reviewDecision,autoMergeRequest,statusCheckRollup,url
```
Classify PRs into four buckets:
1. **Merge candidates**: non-draft, `MERGEABLE`, `CLEAN`, no failing checks, not `CHANGES_REQUESTED`.
2. **Review candidates**: clean but unapproved; inspect before approving.
3. **Stack repair**: wrong base, conflicted, stale parent, or child branch blocked by a parent merge.
4. **Leave alone**: draft, changes requested, branch owned by someone else, or unclear intent.
For a focused PR, inspect the exact relationship:
```sh
gh pr view <n> --json number,title,author,baseRefName,headRefName,headRefOid,mergeable,mergeStateStatus,reviewDecision,autoMergeRequest,statusCheckRollup,url
```
## Merge Or Queue Safely
Merge bottom-up. After each merge, re-read the next child because the base may have changed.
For intermediate stack branches:
```sh
gh pr merge <n> --auto --squash --delete-branch=false
```
For a main-branch PR with merge queue behavior:
```sh
gh pr merge <n> --auto --delete-branch=false
```
Verify immediately:
```sh
gh pr view <n> --json number,state,mergedAt,mergedBy,mergeCommit,mergeStateStatus,autoMergeRequest,url,title
```
If the command reports an error that implies a race, stale base, or already-merged PR, re-read the PR before retrying. GitHub may have completed the merge while the CLI reported a confusing GraphQL error.
## Review Before Approval
For a clean but unapproved PR:
```sh
gh pr diff <n> --name-only
gh pr diff <n> --patch
```
Run the smallest relevant check in a clean checkout or temporary worktree. Approve only after the diff and check match the intended change:
```sh
gh pr review <n> --approve --body "Reviewed diff and validated with <command>."
```
Then merge or queue it using the rules above.
## Repair A Conflicted Child
Prefer stack tooling when available:
```sh
gh stack view
gh stack sync
gh stack submit
```
If using plain Git, repair in a throwaway worktree:
```sh
pr=123
base_branch=parent-branch
head_branch=child-branch
git fetch origin "$base_branch" "$head_branch"
tmp=$(mktemp -d "/tmp/pr${pr}.XXXXXX")
git worktree add -B "fix-pr${pr}" "$tmp" "origin/$head_branch"
cd "$tmp"
git rebase "origin/$base_branch"
```
Resolve conflicts, choosing the final intended content rather than mechanically taking either side:
```sh
git status --short
git add <file>
git rebase --continue
```
Run the relevant check. Push back with a lease:
```sh
git push --force-with-lease origin "fix-pr${pr}:$head_branch"
```
Re-read the PR. Merge only when it returns to `MERGEABLE` and `CLEAN`.
Clean temporary worktrees after use:
```sh
git worktree remove --force "$tmp"
```
## Retarget Wrong Bases
If the commits are correct but the PR targets the wrong parent:
```sh
gh pr edit <n> --base <correct-base-branch>
gh pr view <n> --json number,baseRefName,headRefName,mergeable,mergeStateStatus,url
```
If retargeting introduces conflicts, repair the branch against the new base before merging.
## Done Criteria
- Every acted-on PR has fresh `gh pr view` evidence after the action.
- Merged PRs show `state: MERGED`, `mergedAt`, and a merge commit.
- Queued PRs show auto-merge or merge-queue state expected by the repository.
- Rewritten branches were pushed with `--force-with-lease`.
- Local temporary worktrees are removed.
- Final report lists merged, queued, repaired, and intentionally skipped PRs separately.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!