name: git-town-merge-stack description: Merge stacked GitHub pull requests to main/master in order using Git Town as the default local workflow and GitHub CLI for remote merges. Use when a repository uses stacked branches, PRs must be merged in parent-to-child sequence, and you need safe recovery for rebase-only repos, merge conflicts, or downstream PRs that auto-close during stack merges.
Git Town Stack Merge
Execute remote stack merges safely and predictably.
Inputs
Collect before starting:
- Ordered branch stack from parent to leaf
- Target base branch (
mainormaster) - Preferred merge mode (
rebaseorsquash) based on repo settings
Workflow
- Map branch names to PRs and confirm order.
gh pr list --state all --head <branch> --json number,url,baseRefName,headRefName,state
- Verify each PR is open and in expected base/head relationship.
gh pr view <pr> --json number,state,isDraft,baseRefName,headRefName,mergeable,mergeStateStatus,url
- Sync/update the current stack locally before merging.
git town sync --stack
- Inspect branch hierarchy locally to confirm parent-to-child sequencing.
git town branch
- Read repository merge policy and select merge method that is allowed.
gh repo view <owner/repo> \
--json rebaseMergeAllowed,squashMergeAllowed,mergeCommitAllowed
- Merge remotely in strict order (parent to leaf) with
gh pr merge.
- Use
--rebaseonly when branch history is rebase-compatible. - Use
--squashwhen rebase is blocked or policy allows squash. - Avoid
--delete-branchon intermediate stack PRs.
gh pr merge <pr> --squash
# or
gh pr merge <pr> --rebase
- After each merge, run
git town sync --stackand re-check downstream PR base/mergeability before continuing.
git town sync --stack
gh pr view <next-pr> --json state,baseRefName,headRefName,mergeable,mergeStateStatus,url
Recovery Playbooks
Rebase-only error: This branch can't be rebased
- Check whether squash is enabled.
- If squash is enabled, merge with
--squash. - If squash is not enabled, linearize branch history (remove merge commits), force-push, and retry
--rebase.
Downstream PR closed during stack merge
Common trigger: merging parent PR with --delete-branch while child PR still targets that branch.
- Confirm child branch still exists on remote.
- Create replacement PR from child head to
main/master. - Continue stack using replacement PR number.
gh pr create --base main --head <child-branch> --title "<title>" --body "Replacement for #<old-pr>."
Downstream PR becomes conflicting
- Switch to the child branch via Git Town and run
git town sync --stackto apply stack/base updates. - If sync reports conflicts, resolve them, commit, then run
git town sync --stackagain. - Re-check PR mergeability and merge.
git town switch
# select <child-branch> in the interactive list
git town sync --stack
# resolve conflicts
git add <files>
git commit --no-edit
git town sync --stack
Completion Checks
- Verify final state of all original/replacement PRs.
gh pr view <pr> --json number,state,mergedAt,url
- Run repository-required validation gates after final merge.
- Follow local AGENTS.md or repo policy exactly.
- Example:
npm test
- Clean up obsolete local branches with Git Town.
git town branch
git town delete <obsolete-branch>
Output Format
Report:
- Final PR sequence actually merged (including replacement PRs)
- Any PRs closed/replaced and why
- Validation gate results