Skip to main content
AI/MLathola

stack-push

Pushes all branches in a stack and opens or updates one dependent PR per slice. Use after stack-create to publish the stack or after adding commits to a slice.

Stars
294
Source
athola/claude-night-market
Updated
2026-05-30
Slug
athola--claude-night-market--stack-push
View on GitHubRaw SKILL.md

// install — copy + paste into any project

mkdir -p .claude/skills && curl -fsSL https://raw.githubusercontent.com/athola/claude-night-market/HEAD/plugins/sanctum/skills/stack-push/SKILL.md -o .claude/skills/stack-push.md

Drops the SKILL.md into .claude/skills/stack-push.md. Works with Claude Code, Cursor, and any agent that loads SKILL.md files from .claude/skills/.

Stack Push

Push all branches in a stack and open (or update) one PR per slice, with each PR targeting its parent branch as base.

When to Use

Run stack-push after stack-create has initialized the branch topology and at least one commit exists on each slice branch. Also run it after adding commits to any slice to update open PRs.

Prerequisites

  • stack-create completed: branches exist with commits
  • gh CLI authenticated (gh auth status)
  • Each slice branch has at least one commit beyond its base

Required Progress Tracking

Create TodoWrite items before starting:

  1. stack-push:branches-listed
  2. stack-push:branches-pushed
  3. stack-push:prs-opened
  4. stack-push:stack-summary-posted

Step 1: List Stack Branches (branches-listed)

Identify all branches in the stack. By convention they share a stack/<feature-name>/ prefix:

STACK=stack/my-feature
BASE=master

git branch --list "${STACK}/*" | sed 's/^[* ]*//'

Verify each branch has commits beyond the base:

for branch in $(git branch --list "${STACK}/*" \
    | sed 's/^[* ]*//'); do
  count=$(git rev-list --count \
    "$(git merge-base ${BASE} ${branch})..${branch}")
  echo "${branch}: ${count} commit(s)"
done

Any branch showing 0 commits must have work added before pushing.

Step 2: Push Branches (branches-pushed)

Push every slice branch to the remote in stack order (base slice first):

for branch in $(git branch --list "${STACK}/*" \
    | sed 's/^[* ]*//' | sort); do
  git push --set-upstream origin "${branch}"
  echo "pushed: ${branch}"
done

jj Accelerator (if available)

jj git push --all

Step 3: Open or Update PRs (prs-opened)

Create one PR per slice, targeting its parent branch. For the first slice the parent is master; for subsequent slices the parent is the previous slice's branch.

PREV_BASE=master

for branch in $(git branch --list "${STACK}/*" \
    | sed 's/^[* ]*//' | sort); do

  # Check if a PR already exists for this branch
  existing=$(gh pr list \
    --head "${branch}" \
    --json number \
    --jq '.[0].number' 2>/dev/null)

  if [ -n "${existing}" ]; then
    echo "PR #${existing} already open for ${branch} -- skipping"
  else
    gh pr create \
      --base "${PREV_BASE}" \
      --head "${branch}" \
      --title "[$(echo ${branch} | sed 's|.*/||')] <title>" \
      --body "Part of stack \`${STACK}\`." \
      --draft
    echo "opened PR for ${branch} (base: ${PREV_BASE})"
  fi

  PREV_BASE="${branch}"
done

Fill in the actual PR titles and bodies before removing the --draft flag. Run Skill(sanctum:pr-prep) on each slice to generate quality-gated descriptions.

Step 4: Post Stack Summary (stack-summary-posted)

After all PRs are open, post a summary comment on the first PR (the root of the stack) listing the full chain:

ROOT_PR=$(gh pr list \
  --head "${STACK}/$(git branch --list \
    "${STACK}/*" | sed 's/^[* ]*//' | sort | head -1 \
    | sed 's|.*/||')" \
  --json number --jq '.[0].number')

# Build the stack table
BODY="## Stack\n\n| # | Branch | PR |\n|---|--------|----|\n"
N=1
for branch in $(git branch --list "${STACK}/*" \
    | sed 's/^[* ]*//' | sort); do
  pr_num=$(gh pr list --head "${branch}" \
    --json number --jq '.[0].number')
  BODY="${BODY}| ${N} | \`${branch}\` | #${pr_num} |\n"
  N=$((N+1))
done

gh pr comment "${ROOT_PR}" --body "$(printf "${BODY}")"

Notes

  • Always push in stack order so GitHub sees the parent branch before the child PR is opened
  • Use --draft by default; promote slices to ready individually as they pass review
  • After any git rebase --update-refs run, re-push with git push --force-with-lease (never --force)
  • When a base PR merges, run Skill(sanctum:stack-rebase) to cascade the rebase before updating the next PR's base