Skip to content

Commit c02590a

Browse files
committed
docs: add stack maintenance skill
1 parent d4ad014 commit c02590a

1 file changed

Lines changed: 156 additions & 0 deletions

File tree

  • skills/catalog/stack-maintenance
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---
2+
name: stack-maintenance
3+
description: Maintains stacked GitHub PRs and branches. Triggers on "fix stacked PRs", "merge this PR stack", "restack branches", "turn on auto-merge", `gh stack`, `gh pr`, `jj spr`, wrong PR bases, merge queues, or force-pushing stack repairs.
4+
---
5+
6+
# Stack Maintenance
7+
8+
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.
9+
10+
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.
11+
12+
## Rules From Prior Stacked PR Incidents
13+
14+
- Trust fresh GitHub metadata, not memory. Fetch `baseRefName`, `headRefName`, `mergeStateStatus`, `mergeable`, `reviewDecision`, checks, and auto-merge state before acting.
15+
- Stacked PRs usually merge bottom-up. A child can become conflicted after its parent merges; expect to rebase or retarget it before merging.
16+
- `gh pr merge --auto --squash` can merge immediately for intermediate stack branches. Re-read the PR afterward; do not infer from command text.
17+
- 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`.
18+
- Do not approve a PR before reviewing its diff and running the relevant local check. "Clean" only means mergeable, not reviewed.
19+
- Use `--delete-branch=false` for stack branches unless the user explicitly asks to prune. Other PRs may still depend on them.
20+
- Use `git push --force-with-lease`, never plain force, after rebasing a PR branch.
21+
- Stop before rewriting someone else's branch unless ownership and permission are clear.
22+
23+
## Map The Stack First
24+
25+
Start with the current checkout and remote state:
26+
27+
```sh
28+
git status --short --branch
29+
git fetch origin --prune
30+
```
31+
32+
List open PRs with the fields that matter:
33+
34+
```sh
35+
gh pr list --state open --limit 100 \
36+
--json number,title,author,baseRefName,headRefName,isDraft,mergeable,mergeStateStatus,reviewDecision,autoMergeRequest,statusCheckRollup,url
37+
```
38+
39+
Classify PRs into four buckets:
40+
41+
1. **Merge candidates**: non-draft, `MERGEABLE`, `CLEAN`, no failing checks, not `CHANGES_REQUESTED`.
42+
2. **Review candidates**: clean but unapproved; inspect before approving.
43+
3. **Stack repair**: wrong base, conflicted, stale parent, or child branch blocked by a parent merge.
44+
4. **Leave alone**: draft, changes requested, branch owned by someone else, or unclear intent.
45+
46+
For a focused PR, inspect the exact relationship:
47+
48+
```sh
49+
gh pr view <n> --json number,title,author,baseRefName,headRefName,headRefOid,mergeable,mergeStateStatus,reviewDecision,autoMergeRequest,statusCheckRollup,url
50+
```
51+
52+
## Merge Or Queue Safely
53+
54+
Merge bottom-up. After each merge, re-read the next child because the base may have changed.
55+
56+
For intermediate stack branches:
57+
58+
```sh
59+
gh pr merge <n> --auto --squash --delete-branch=false
60+
```
61+
62+
For a main-branch PR with merge queue behavior:
63+
64+
```sh
65+
gh pr merge <n> --auto --delete-branch=false
66+
```
67+
68+
Verify immediately:
69+
70+
```sh
71+
gh pr view <n> --json number,state,mergedAt,mergedBy,mergeCommit,mergeStateStatus,autoMergeRequest,url,title
72+
```
73+
74+
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.
75+
76+
## Review Before Approval
77+
78+
For a clean but unapproved PR:
79+
80+
```sh
81+
gh pr diff <n> --name-only
82+
gh pr diff <n> --patch
83+
```
84+
85+
Run the smallest relevant check in a clean checkout or temporary worktree. Approve only after the diff and check match the intended change:
86+
87+
```sh
88+
gh pr review <n> --approve --body "Reviewed diff and validated with <command>."
89+
```
90+
91+
Then merge or queue it using the rules above.
92+
93+
## Repair A Conflicted Child
94+
95+
Prefer stack tooling when available:
96+
97+
```sh
98+
gh stack view
99+
gh stack sync
100+
gh stack submit
101+
```
102+
103+
If using plain Git, repair in a throwaway worktree:
104+
105+
```sh
106+
pr=123
107+
base_branch=parent-branch
108+
head_branch=child-branch
109+
git fetch origin "$base_branch" "$head_branch"
110+
tmp=$(mktemp -d "/tmp/gradient-pr${pr}.XXXXXX")
111+
git worktree add -B "fix-pr${pr}" "$tmp" "origin/$head_branch"
112+
cd "$tmp"
113+
git rebase "origin/$base_branch"
114+
```
115+
116+
Resolve conflicts, choosing the final intended content rather than mechanically taking either side:
117+
118+
```sh
119+
git status --short
120+
git add <file>
121+
git rebase --continue
122+
```
123+
124+
Run the relevant check. Push back with a lease:
125+
126+
```sh
127+
git push --force-with-lease origin "fix-pr${pr}:$head_branch"
128+
```
129+
130+
Re-read the PR. Merge only when it returns to `MERGEABLE` and `CLEAN`.
131+
132+
Clean temporary worktrees after use:
133+
134+
```sh
135+
git worktree remove --force "$tmp"
136+
```
137+
138+
## Retarget Wrong Bases
139+
140+
If the commits are correct but the PR targets the wrong parent:
141+
142+
```sh
143+
gh pr edit <n> --base <correct-base-branch>
144+
gh pr view <n> --json number,baseRefName,headRefName,mergeable,mergeStateStatus,url
145+
```
146+
147+
If retargeting introduces conflicts, repair the branch against the new base before merging.
148+
149+
## Done Criteria
150+
151+
- Every acted-on PR has fresh `gh pr view` evidence after the action.
152+
- Merged PRs show `state: MERGED`, `mergedAt`, and a merge commit.
153+
- Queued PRs show auto-merge or merge-queue state expected by the repository.
154+
- Rewritten branches were pushed with `--force-with-lease`.
155+
- Local temporary worktrees are removed.
156+
- Final report lists merged, queued, repaired, and intentionally skipped PRs separately.

0 commit comments

Comments
 (0)