merging-pr-stack

Use when merging a stack of stacked PRs with jj. Triggered by phrases like "merge the PR stack", "merge the stacked PRs", "land these PRs", or "merge the stack into main".

7 stars

Best use case

merging-pr-stack is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when merging a stack of stacked PRs with jj. Triggered by phrases like "merge the PR stack", "merge the stacked PRs", "land these PRs", or "merge the stack into main".

Teams using merging-pr-stack should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/merging-pr-stack/SKILL.md --create-dirs "https://raw.githubusercontent.com/jack-michaud/faire/main/jack-software/skills/merging-pr-stack/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/merging-pr-stack/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How merging-pr-stack Compares

Feature / Agentmerging-pr-stackStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when merging a stack of stacked PRs with jj. Triggered by phrases like "merge the PR stack", "merge the stacked PRs", "land these PRs", or "merge the stack into main".

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

You are a staff engineer merging a stack of stacked jj branches into main via GitHub's merge queue.

## Process

### Phase 1: Pre-merge checks

1. **List the PR stack** from base to tip. If not provided, infer from `jj log` and `gh pr list`:
   ```bash
   jj log --revisions 'ancestors(@, 10) & bookmarks()' --no-graph
   gh pr list --state open
   ```
   Order them base-first (the PR closest to `main` merges first).

2. **Check CI on the base PR**:
   ```bash
   gh pr checks <base-pr-number>
   ```
   - If all checks pass: proceed to Phase 2.
   - If checks are failing: stop and report which checks failed. Do not proceed until CI is green.

### Phase 2: Merge the base PR

3. **Add the base PR to the merge queue** (preferred) or merge directly:
   ```bash
   gh pr merge <base-pr-number> --merge --auto
   ```
   - If the repo uses a merge queue, `--auto` will queue it automatically.
   - If merge queue is not configured, this merges immediately.

4. **Poll merge queue status** via GraphQL until the entry is merged or errored:
   ```bash
   gh api graphql -f query='
     query($owner: String!, $repo: String!, $number: Int!) {
       repository(owner: $owner, name: $repo) {
         pullRequest(number: $number) {
           mergeQueueEntry {
             state
             position
             estimatedTimeToMerge
           }
         }
       }
     }
   ' -f owner=<owner> -f repo=<repo> -F number=<base-pr-number>
   ```
   - `state` values: `QUEUED`, `AWAITING_CHECKS`, `MERGEABLE`, `MERGED`, `FAILED`, `LOCKED`
   - If `state` is `MERGED`: proceed to Phase 3.
   - If `state` is `FAILED` or `LOCKED`: stop and report the failure. Do not proceed with the rest of the stack.
   - If `state` is `QUEUED` or `AWAITING_CHECKS`: wait ~30s and poll again. Repeat until terminal state.
   - If no `mergeQueueEntry` (not using merge queue): check `gh pr view <number> --json state` — if `state` is `MERGED`, proceed.

### Phase 3: Rebase remaining stack onto main

5. **Fetch the updated remote**:
   ```bash
   jj git fetch
   ```

6. **Rebase remaining stack branches onto `main@origin`**:
   ```bash
   jj rebase -s <next-branch-bookmark> -d main@origin
   ```
   - Repeat for each remaining branch in the stack, base-first.
   - Alternatively, if the entire remaining stack is contiguous:
     ```bash
     jj rebase -s <next-branch-bookmark> -d main@origin
     ```
     jj will automatically carry descendants along.

7. **Resolve conflicts** if any appear (`jj log` shows `!` markers):
   - For each conflicted revision:
     1. `jj new <conflicted-rev-id>` — create resolution on top
     2. Edit conflicted files to resolve `<<<`/`===`/`>>>` markers
     3. `jj squash` — fold the resolution into the conflicted revision
   - Repeat until `jj log` shows no `!` markers.

8. **Verify base retargeting** — the next PR's base should now target `main`:
   ```bash
   gh pr view <next-pr-number> --json baseRefName
   ```
   - If `baseRefName` is still the old merged branch: update it:
     ```bash
     gh pr edit <next-pr-number> --base main
     ```

9. **Push the rebased branches**:
   ```bash
   jj git push --bookmark <next-branch> --bookmark <branch-after-that> ...
   ```
   Push all remaining stack branches in one command.

### Phase 4: Repeat for each remaining PR

10. **Return to Phase 1** for the new base PR (previously the second PR in the stack). Repeat Phases 1–3 until all PRs in the stack are merged.

## Completion Criteria

- All PRs in the stack are merged into `main`
- `jj git fetch` shows no pending stack branches diverging from `main@origin`
- All merge queue entries finished with `MERGED` state
- No `!` conflict markers remain in `jj log`

Related Skills

stacked-pr-review

7
from jack-michaud/faire

Use when addressing PR review comments on stacked jj branches. Triggered by phrases like "address review comments", "fix PR feedback", "respond to review on stacked branch", or "update the PR with reviewer suggestions".

Ticket Workflow

7
from jack-michaud/faire

Autonomous ticket-to-production lifecycle with promptlet-driven phases. Use when executing /ticket commands or working on ticket-driven development.

setup-sprite

7
from jack-michaud/faire

Set up a reproducible remote dev environment using sprites with credential-free git sync. Use when user asks to "set up a sprite", "create a remote dev environment", "use sprites", or mentions wanting a reproducible remote environment for a project.

Writing python services

7
from jack-michaud/faire

Writing a class with encapsulated logic that interfaces with an external system. Logging, APIs, etc.

Python Code Style

7
from jack-michaud/faire

Use when writing python code. Can be used for code review.

Plan

7
from jack-michaud/faire

My planning skill that has additional instructions. Always use when entering plan mode.

Modal

7
from jack-michaud/faire

No description provided.

Creating Slash Commands

7
from jack-michaud/faire

Build custom slash commands in Claude Code with YAML frontmatter, permissions, and best practices. Use when creating automation workflows, project-specific commands, or standardizing repetitive tasks.

Creating Hooks

7
from jack-michaud/faire

Build event-driven hooks in Claude Code for validation, setup, and automation. Use when you need to validate inputs, check environment state, or automate tasks at specific lifecycle events.

Create Claude Channel

7
from jack-michaud/faire

Step-by-step procedure for building a Claude Code channel integration. Use when creating a new channel plugin that connects Claude Code to external systems via MCP, named pipes, webhooks, or chat platforms.

Committing

7
from jack-michaud/faire

Any time committing, pushing, or creating new revisions is mentioned, use this commit flow.

SOLID Principles Code Review

7
from jack-michaud/faire

Review Python code for adherence to SOLID principles (SRP, OCP, LSP, ISP, DIP). Use when reviewing Python code for maintainability, testability, and design quality.