git-cli-stack
v0.1.3
Published
Manage stacked pull requests with a git CLI and MCP server.
Readme
git-stack
git-stack is a stacked pull request workflow tool with two primary surfaces:
- a CLI for operating on stacked branches inside a git repository
- an MCP server for exposing stack metadata and stack operations to agents and other tooling
It is designed as a more ergonomic successor to pr-train, with explicit subcommands, managed PR navigation sections, cached repo-local stack state, and an MCP interface that mirrors the core workflows.
Why Use It
git-stack is for teams that split one feature into several reviewable pull requests but still want the whole chain to stay easy to manage.
Useful cases:
- You want to break a large feature into smaller PRs without manually rebasing and retargeting every branch yourself.
- You want each PR in a stack to point at the previous PR automatically, with a visible stack table in every description.
- You want a single command to sync branches, push them, and publish the full stack to GitHub.
- You want an MCP server so agents can inspect stacks, advance them, or help maintain them without scraping git output.
Typical workflow:
- Create a stack from your current branch with
git stack create ... - Keep it in sync with
git stack sync - Publish or refresh the whole PR chain with
git stack push - Advance the remaining work after merges with
git stack advance
Table Of Contents
Summary
What It Does
git-stack models an ordered stack of branches that should be merged or rebased in sequence. It can:
- resolve the current stack from the checked-out branch
- sync branch content down the stack
- create or update GitHub pull requests and keep bases aligned
- maintain a managed stack table of contents inside PR bodies
- advance a stack after leading branches merge
- expose stack metadata and mutating operations over MCP
Main Surfaces
CLI
The CLI entrypoint is src/cli.ts.
It is responsible for:
- defining subcommands and user-facing flags
- turning CLI args into structured operation calls
- printing human-readable summaries or JSON
The CLI delegates to:
- src/operations.ts for command orchestration
- src/train.ts for stack resolution and status assembly
- src/git.ts for git helpers
- src/github.ts for GitHub integration
MCP
The MCP server entrypoint is src/mcp.ts.
It is responsible for:
- exposing repo stack state as resources
- exposing stack workflows as tools
- returning structured JSON payloads suitable for agents
Config And State
Supporting modules:
- src/config.ts: YAML config loading and normalization
- src/state.ts: cached derived state in
.git/stack/state.json - src/toc.ts: managed PR TOC rendering and replacement
- templates/stack.yml: starter repo config
Requirements
- Node.js
>=20 pnpmgit- GitHub authentication via one of:
GITHUB_TOKENgh auth token~/.config/git-stack/config.yml
Quick Start Guide
Install
pnpm install
pnpm build
pnpm testInstalled binaries:
git-stackstack
Primary usage:
git stack <command>Basic Setup
- Create the global stacks config:
git stack init- Edit
~/.config/git-stack/stacks.yml. Minimal example:
defaults:
remote: origin
sync:
strategy: merge
stacks:
example-stack:
syncBase: main
prTarget: main
branches:
- feature-a
- feature-b
- name: integration
role: combined- Check the resolved stack:
git stack status- Open the config in your editor:
git stack config- Bootstrap a new stack from the current branch:
git stack create feature-a feature-b feature-c- Add the current branch onto an existing stack definition:
git stack add feature-a- Push the current stack and create stacked PRs:
git stack push
git stack push --draft- Get built-in guidance for a topic:
git stack help overview
git stack help create
git stack help mcpCommon Workflows
Sync The Stack
git stack sync
git stack sync --strategy rebase
git stack sync --pushCreate Or Update PRs
git stack prs ensure
git stack prs ensure --draft
git stack prs ensure --ready --print-urlsAdvance After Merge
git stack advance
git stack advance --push --force
git stack advance --close-merged-prs --comment-updated-prs "/retest"Run The MCP Server
git stack mcpInstall Into Supported Clients
git stack mcp install codex
git stack mcp install claude
git stack mcp install opencode
git stack mcp install piCLI Docs
Global CLI Flags
--json
Top-level flag that prints machine-readable JSON instead of the normal text summary for commands returning an OperationResult.
Example:
git stack --json statusCLI Commands
git stack init
Creates the global stacks file using the bundled template.
Behavior:
- fails if the global stacks file already exists
- requires the current directory to be inside a git repository
Arguments:
- none
git stack config
Opens the global stacks file in the configured editor.
Behavior:
- uses
EDITORfirst - falls back to
VISUAL - creates the global stacks file from the bundled template if it does not exist yet
- fails if neither
EDITORnorVISUALis set
Arguments:
- none
git stack create <branches...>
Creates a new stack from the current branch and writes it into the global stacks file.
Behavior:
- uses the current branch as both
syncBaseandprTarget - creates the first named branch from the current branch
- creates each later branch from the previous newly created branch
- writes a new stack named after the first branch argument
- checks out the first created branch when finished
- errors if any requested branch already exists
- errors if a stack with the first branch name already exists
Arguments:
<branches...>- ordered list of branch names to create as a stack
git stack add <stack>
Adds the current checked-out branch onto an existing stack.
Behavior:
- resolves the current branch from git
- appends the current branch to the named stack
- inserts the branch before the combined branch if the stack has one
- errors if the current branch is already present in any stack
- errors if the named stack does not exist
Arguments:
<stack>- existing stack name to update
git stack push
Pushes the current stack branches to the remote and creates or updates stacked PRs.
Behavior:
- syncs the stack in sequence
- pushes stack branches to the configured remote
- creates or updates PRs in order so each PR points at the previous branch in the stack
- ensures the managed stack TOC with all stack PR links is present in the PR descriptions
- supports draft/ready publishing
Arguments:
--stack <name>--strategy <merge|rebase>--force--include-merged--draft--ready--print-urls
git stack help [topic]
Shows built-in guidance about how git-stack works.
Behavior:
- without a topic, prints available help topics
- with a topic, prints focused guidance for that workflow or subsystem
- uses the same shared help registry exposed through the MCP server
Arguments:
[topic]- optional topic such as
overview,cli,mcp,create,sync,prs,advance, orconfig
- optional topic such as
git stack status
Shows the resolved stack status.
Behavior:
- resolves from the current branch if
--stackis omitted - includes branch order, active/merged flags, combined branch marker, PR metadata when available, and warnings
Arguments:
--stack <name>- resolve a specific stack explicitly
git stack validate
Validates repo/stack state.
Validation includes:
- stack resolution
- branch existence checks
- GitHub lookup warnings when PR metadata cannot be loaded
Arguments:
--stack <name>
git stack sync
Synchronizes the stack by applying each branch onto the next branch.
Behavior:
- creates the combined branch if configured and missing
- uses merge or rebase per command/config
- skips already-satisfied ancestry edges
- can optionally push updated branches
Arguments:
--stack <name>--strategy <merge|rebase>--push--force- push with
--force-with-lease
- push with
--include-merged- include branches already merged into the sync base
git stack prs ensure
Creates or updates GitHub PRs for active branches.
Behavior:
- derives normal PR title/body from the branch head commit
- uses
combinedTitleTemplatefor the combined branch title - retargets bases according to stack order
- updates only the managed PR body TOC section
- can post the configured update comment when PRs change
Arguments:
--stack <name>--draft--ready- force non-draft mode for this run
--print-urls
git stack advance
Advances the stack after one or more leading branches have merged.
Behavior:
- rebases the next active head onto
syncBase - rebases downstream active branches onto their new parent branches
- rebases the combined branch onto the new active tail when present
- can retarget remaining PR bases
- can comment on updated PRs
- can close merged PRs
Arguments:
--stack <name>--push--force--close-merged-prs--comment-updated-prs <body>
git stack checkout <selector>
Checks out a stack branch.
Supported selector forms:
- numeric index such as
0 - explicit branch name such as
feature-a - literal
combined
Arguments:
<selector>--stack <name>
git stack mcp
Starts the MCP server over stdio.
Arguments:
- none
git stack mcp install <target>
Installs the git-stack MCP server into a supported client.
Supported targets:
codexclaudeopencodepi
Behavior:
codex- runs the native
codex mcp addcommand using the builtdist/cli.js
- runs the native
claude- runs the native
claude mcp add --scope usercommand using the builtdist/cli.js
- runs the native
opencode- writes
~/.config/opencode/opencode.jsonwith a local MCP entry
- writes
pi- returns an unsupported result because the installed Pi agent explicitly documents that it does not support MCP
Arguments:
<target>- one of
codex,claude,opencode, orpi
- one of
MCP Docs
Transport
- stdio
Resources
stack://repo/current/state
Returns the cached stack state stored in .git/stack/state.json when present.
Payload fields:
versionupdatedAttrainNamecurrentBranchremotestrategycombinedBranchbranches[]
stack://repo/current/trains
Returns configured stack identifiers for the current repo.
Current payload shape:
operations- values like
stack:<name>
- values like
stack://repo/current/help
Returns built-in MCP help content.
Payload shape:
okmessagewarningsoperations
Tools
stack_help
Returns built-in help content for MCP consumers.
Arguments:
topic?: string
stack_list_trains
Lists configured stacks.
Arguments:
cwd?: string
stack_get_train
Returns computed stack status.
Arguments:
trainName?: stringcwd?: string
stack_validate
Runs validation logic equivalent to the CLI validate command.
Arguments:
trainName?: stringcwd?: string
stack_sync_train
Runs stack synchronization.
Arguments:
trainName?: stringcwd?: stringstrategy?: "merge" | "rebase"push?: booleanforce?: booleanincludeMerged?: booleandryRun?: boolean
stack_ensure_prs
Creates or updates PRs.
Arguments:
trainName?: stringcwd?: stringdraft?: booleanprintUrls?: booleandryRun?: boolean
stack_advance_train
Advances the lifecycle of a stack.
Arguments:
trainName?: stringcwd?: stringpush?: booleanforce?: booleancloseMergedPrs?: booleancommentUpdatedPrs?: string | nulldryRun?: boolean
stack_checkout_branch
Checks out a branch from the resolved stack.
Arguments:
selector: stringtrainName?: stringcwd?: string
stack_refresh_metadata
Refreshes derived metadata and returns current status.
Arguments:
trainName?: stringcwd?: string
Shared Result Shape
Most CLI JSON output and MCP tool responses serialize the same operation model:
ok: booleanmessage: stringwarnings: string[]operations?: string[]status?: TrainStatus
Config API
Optional global config:
~/.config/git-stack/config.yml~/.config/git-stack/stacks.yml
Repo Config Schema
defaults:
remote: origin
sync:
strategy: merge
github:
host: github.com
prs:
draft: false
printUrls: false
commentOnUpdate:
combinedTitleTemplate: "{{stack.name}}"
lifecycle:
keepMergedInToc: true
closeMergedPrs: false
stacks:
my-stack:
syncBase: main
prTarget: main
branches:
- feature-a
- feature-b
- name: integration
role: combinedConfig Fields
defaults.remote
Default git remote used for push and GitHub operations.
Type:
string
Default:
origin
defaults.sync.strategy
Default stack sync strategy.
Allowed values:
mergerebase
defaults.github.host
GitHub hostname used when parsing remotes.
Type:
string
Default:
github.com
defaults.prs.draft
Default draft setting for prs ensure.
Type:
boolean
defaults.prs.printUrls
Whether PR URLs should be included in emitted operations by default.
Type:
boolean
defaults.prs.commentOnUpdate
Optional PR comment body posted when PRs are updated by stack flows.
Type:
string | null
defaults.prs.combinedTitleTemplate
Template for combined branch PR titles.
Supported token:
{{stack.name}}
defaults.lifecycle.keepMergedInToc
Documents the intent to preserve merged history in rendered stack output.
Type:
boolean
defaults.lifecycle.closeMergedPrs
Whether merged PRs should be closed by default during advance.
Type:
boolean
stacks.<name>.syncBase
The branch used as the sync and advancement base.
Used for:
- ancestry checks
- merged detection
- rebasing the next active head during
advance
stacks.<name>.prTarget
The base branch for the first active PR and the combined PR.
stacks.<name>.branches
Ordered branch list defining stack flow.
Supported item forms:
String form:
- feature-aObject form:
- name: integration
role: combinedRules:
- order matters
- at most one combined branch is allowed
- the combined branch must be last
Global Config
Global config can provide shared defaults and token fallback.
Example:
defaults:
remote: upstream
github:
token: ghp_example
host: github.comAuth precedence:
GITHUB_TOKENgh auth token~/.config/git-stack/config.yml
Additional Info
Derived State
Cached derived state is written to:
.git/stack/state.json
Fields:
versionupdatedAttrainNamecurrentBranchremotestrategycombinedBranchbranches[]
Purpose:
- fast metadata access for MCP
- a persisted snapshot of the most recently resolved status
PR Body Management
Managed PR body markers:
<!-- git-stack:toc:start -->
<!-- git-stack:toc:end -->Behavior:
- replaces only the bounded managed section when markers already exist
- appends the section when the markers are absent
- renders active and merged branches separately when applicable
Development
Useful scripts:
pnpm buildpnpm cleanpnpm devpnpm mcppnpm testpnpm test:watch
Tests
Current tests cover:
- config parsing and validation rules
- TOC rendering and replacement
- active branch lifecycle helpers
- MCP module surface loading
Test files:
Limitations
- GitHub is the only supported forge
- multi-repo stacks are not implemented
- live GitHub integration is not covered by end-to-end tests yet
- some documented defaults are broader than the current test surface
Contribution
Development Setup
Install dependencies and verify the current tree:
pnpm install
pnpm build
pnpm testUseful scripts:
pnpm buildpnpm cleanpnpm devpnpm mcppnpm testpnpm test:watch
Local CLI Install
To install the CLI from this checkout so git stack resolves to your local build:
pnpm build
npm linkThat registers the package’s binaries globally for your user:
git-stackstack
After linking, verify the local checkout is being used:
git-stack --help
stack --helpIf your git installation is configured to discover git-* executables on your PATH, git stack should also work:
git stack --helpTo open the local stack config through your editor integration:
export EDITOR=nvim
git stack configWhen you change the source, rebuild before rerunning:
pnpm buildTo remove the local linked install later:
npm unlink -g git-stackRunning Without Linking
For local iteration without installing globally:
pnpm dev -- --help
pnpm dev -- status
pnpm mcpThis is useful when you want to exercise the CLI and MCP server directly from the repo without modifying your global environment.
Contributor Notes
- Keep the CLI and MCP docs aligned with the real command surface in src/cli.ts and src/mcp.ts.
- Prefer documenting config and argument behavior from implementation, not from intended future behavior.
- Run
pnpm testbefore committing docs that describe command or config semantics.
