| name | github-merge-stack |
| description | Merge stacked feature branches from Ralph into main, preserving full feature history. Handles PR base updates, sequential squash merges, and branch cleanup. |
| argument-hint | [--dry-run] [--no-cleanup] |
| allowed-tools | Bash, Read |
Purpose
After Ralph completes with RALPH_CREATE_PR=true, merge all stacked PRs into main while preserving visibility of when and why each feature was implemented.
Arguments
--dry-run โ Show what would be merged without making changes
--no-cleanup โ Skip local branch cleanup after merging
Prerequisites
gh CLI authenticated (gh auth status)
- On a branch in the repo with open PRs
- PRs created by Ralph with stacked branches
Template
The merge logic is implemented in templates/merge-stack.sh. This script can be:
- Run directly from the skill's templates folder
- Copied to a project's
scripts/ directory for convenience
Workflow
1. Copy Script to Project (Optional)
cp /path/to/skills/shared/github-merge-stack/templates/github-merge-stack.sh scripts/
chmod +x scripts/github-merge-stack.sh
2. Run the Script
./scripts/github-merge-stack.sh --dry-run
./scripts/github-merge-stack.sh
./scripts/github-merge-stack.sh --no-cleanup
What the Script Does
- Checks prerequisites โ Verifies
gh CLI is authenticated
- Lists open PRs โ Sorted by number (oldest first = merge order)
- Dry run (if
--dry-run) โ Shows plan without executing
- Merges PRs sequentially โ For each PR:
- Updates base to
main (previous base may be deleted)
- Squash merges with
gh pr merge --squash --delete-branch
- Syncs local โ Pulls main, prunes remote refs
- Cleans up (unless
--no-cleanup) โ Deletes local feat/* branches
- Reports results โ Shows merged commits and any remaining branches
Understanding the Stack
Ralph creates stacked branches where each PR's base is the previous feature branch:
main
โโโ feat/story-001 โ PR #1 (base: main)
โโโ feat/story-002 โ PR #2 (base: feat/story-001)
โโโ feat/story-003 โ PR #3 (base: feat/story-002)
Why Squash Merge
- One commit per feature โ Clean main history
- Full context preserved โ Ralph's detailed commit messages (description, acceptance criteria, files) become the squash commit body
- Traceability โ
git blame traces to originating story, git log --grep finds features
Output
The script reports:
- Number of PRs merged
- Commits now in main (with hashes and titles)
- Branches cleaned up
- Any failed PRs (conflicts to resolve manually)
- Commands for viewing history
Viewing History Later
git log --oneline
git show <commit-hash>
git log --grep="story-003"
git blame path/to/file.ts
Error Handling
- PR has conflicts: Skipped, reported at end for manual resolution
- gh not authenticated: Exits with instructions to run
gh auth login
- No open PRs: Reports nothing to merge
- Branch delete fails: Continues, reports at end
Reference
See reference/github-merge-stack-reference.md for troubleshooting and manual procedures.