A command-line tool for managing stacked git branches. Develop features on top of one another, keep history clean, and sync with GitHub.
cargo install --git https://github.com/wbbradley/git-stack --lockedgit stack # show your stack
git stack sync # sync local state with GitHub (push + pull)
git stack checkout feature # create branch "feature" as child of current branch
# ...make changes, commit...
git stack restack # restack the current branch onto its parent
git stack diff # diff against parent branch
git stack pr create # create GitHub PR with correct base branchgit stack # show the stack tree (alias: git stack status)git stack checkout feature # create "feature" stacked on current branchgit stack restack # restack current branch onto its parent
git stack restack -afp # fetch, recursively restack from trunk, push on successThe -afp flags:
-a/--ancestors: recursively restack all ancestors from trunk up to current branch-f/--fetch: fetch updates from remote first-p/--push: push branch updates to remote on success
git stack diff # diff against parent branchgit stack pr create # create GitHub PR with correct base branchgit stack mount <parent> # stack current branch on a different parentThis only updates git-stack metadata, not git history. Use restack afterward to keep this branch
in sync with its parent.
git stack delete <branch> # remove a branch from the stackNote that git stack sync will automatically prune local branches that are duplicates of the remote
branch, or have already been merged.
Commands that talk to GitHub (sync, pr create) need a token. Set one up with:
git stack auth login # interactive OAuth device flow (recommended)
git stack auth login --pat # paste a personal access token instead
git stack auth status # show the active auth method
git stack auth logout # clear git-stack's stored tokensgit-stack resolves a token from the first source that provides one, in order:
GITHUB_TOKENenvironment variableGH_TOKENenvironment variablegit config --get github.token- Config file (
~/.config/git-stack/github.yaml): host-specific token, then PAT, then OAuth token - The
ghCLI: if none of the above resolve and you've rungh auth login, git-stack borrowsgh's token automatically (viagh auth token). Usegh auth logoutto sign out ofgh.
By default, git stack status and the interactive TUI filter the tree to your own GitHub
login — branches whose PR was authored by someone else are hidden, so a shared repo shows just
your stacks. The current branch, its ancestor chain up to trunk, the trunk itself, and any branch
whose author can't be determined (e.g. local work with no PR yet) always stay visible.
The same effective filter also governs two non-display behaviors, so they stay consistent with
what status shows:
git stack cleanupprunes out-of-scope branches from the stack tree (it prompts for confirmation before saving, and refuses to prune on a non-interactive terminal).git stack syncskips injecting remote-only PR branches authored by others.git stack syncalso discovers the filtered authors' open PRs and auto-mounts them, so running it from a trunk-only tree reconstructs and mounts your stacks (skipped under--pushand whenauthors_filter: []is set).
Override the default with an authors_filter key in ~/.config/git-stack/github.yaml:
# Filter to specific authors (yourself and a collaborator):
authors_filter: [octocat, hubber]
# Show everyone's branches (filtering off):
authors_filter: []- Key absent (the default) → filter to your own login.
authors_filter: []→ show everyone.authors_filter: [a, b]→ show exactly those authors (plus the always-visible protected branches above).
To show everything for a single invocation without editing config, pass --show-all.
Deriving the default requires knowing your GitHub login. git-stack looks it up once via GET /user
and caches it (keyed by host) in its local state, refreshing it on git stack auth login and
git stack sync. If the filter is unset and there's no cached login and git-stack can't
fetch one right now (offline and token-less), status prints an actionable error rather than
guessing — set a token (git stack auth login, or GITHUB_TOKEN/GH_TOKEN), set authors_filter
explicitly, or use authors_filter: [] / --show-all to show everyone.
# Start on main
git stack checkout auth # create auth branch
# ...implement auth, commit...
git stack checkout login # create login branch (child of auth)
# ...implement login, commit...
git stack # see your stack tree
git stack restack -afp # sync everything and push
git stack pr create # create PR for current branchStack state is stored per-repo in ~/.local/state/git-stack/state.yaml.
If git stack reports issues:
- Ensure your working tree is clean (
git status) - On a conflict, restack pauses and records a recovery point. Resolve the conflict
(
git mergetool),git addthe resolved files, then rungit stack restack --continueto finish the branch and resume the rest of the stack, orgit stack restack --abortto restore the conflicting branch to its original state. This works for every stack method, and--abortrecovers even if you already ran a baregit am --abort/git rebase --abort.