Repository navigation
Releases: DomBlack/git-stack
Release list
v0.4.0
Fold, pop, undo and four more commands, so nothing needs gh stack modify any more
This one is mostly about changing a stack after you've built it. Until now a few of those jobs still sent you to gh stack modify and a manual restack; they're all git-stack commands now, and there's an undo for when one of them does something you didn't expect.
New
git stack foldmerges the current branch into the one below it, one branch and one PR.--keepkeeps the current branch's name and PR instead. Nothing needs restacking.git stack poptakes the current branch out of its stack and deletes it, leaving its changes staged on its parent (likegit reset --soft). The branches above are restacked without it.git stack undoreverses the last git-stack command that changed local state; run it again to step further back, up to 20 commands. It covers everything that rewrites branches (create, modify, absorb, restack, reorder, move, fold, pop, untrack, init, sync, a local rename) and never touches GitHub, so a submit or merge clears the history. It's per worktree, so an undo in your checkout won't reverse what an agent did in another one.--listshows what it would put back.git stack create --insertputs a new branch right above the current one instead of only at the top, and restacks the ones above onto it.git stack untrackstops tracking a branch and everything above it without touching the branches;--onlytakes just that one out and closes the gap.git stack renamerenames the current branch, here and on GitHub, keeping its PR attached.--localkeeps it to your machine.git stack propens the current branch's PR in your browser (or prints the URL when piped).git stack updatenow shows what's in every release you're skipping, and brings whatgit stack installset up (aliases, completion, the agent skills) up to date with the new binary.
Fold and pop close the PR they leave behind at your next submit, with a comment pointing at where the work went. Agents get all of these as MCP tools.
Fixes
- Absorbing a change that deletes lines no longer refuses with "this is a bug in stack_absorb".
- Stacks are kept in each worktree's own stack file, and submit works from whichever worktree has the stack checked out.
- Sync no longer restacks a merged branch it decided to keep.
After upgrading
If you set up aliases with git stack install, updating from v0.3.1 adds the new ones (git fold, git pop, git undo and the rest) for you. Anything older, run git stack install once.
What's Changed
New features
- Show what changed when there's an update by @DomBlack in #47
- Add git stack fold by @DomBlack in #52
- Add git stack pop by @DomBlack in #53
- Add git stack create --insert by @DomBlack in #54
- Add git stack pr by @DomBlack in #55
- Add git stack untrack by @DomBlack in #56
- Add git stack rename by @DomBlack in #57
- Add git stack undo by @DomBlack in #58
Fixes
- Don't restack a merged branch that sync kept by @DomBlack in #48
- Put a new stack in the worktree's own stack file by @DomBlack in #49
- Submit a stack from whichever worktree has it checked out by @DomBlack in #50
- Fix absorb refusing any change that deletes lines by @DomBlack in #60
Under the hood
Full Changelog: v0.3.1...v0.4.0
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.3.1
git stack update now keeps your install up to date too, and continuing a restack that stopped on a signing failure works again on git 2.56.
Before this, updating swapped the binary but left everything git stack install set up as it was, so the skill kept describing the old release, new aliases never showed up and the completion script went stale until you ran install again. Now once the new binary is in place, git stack update hands over to it to refresh whatever install set up before (aliases, completion, the MCP registration if the binary moved, and the skills) without asking. It only touches what you installed in the first place, leaves an alias you've pointed elsewhere alone, and only prints what it changed. The skill now installs for Codex as well as Claude Code, each only if you have that agent's config directory.
Also fixed: when a restack stopped because a commit couldn't be signed, git stack continue broke on git 2.56 (it'd go on to report a conflict that wasn't there). It now finishes the pick itself again, on 2.56 and on older versions.
After upgrading
The update that gets you to v0.3.1 is still run by the old binary, which doesn't know how to do the refresh. So run git stack install once after this update to pick up the Codex skill and anything else that's stale; from then on git stack update does it for you.
What's Changed
New features
Fixes
Full Changelog: v0.3.0...v0.3.1
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.3.0
This release adds absorb, reorder, move and init, so fixing a commit lower down or changing the shape of a stack no longer means dropping back to gh stack, plus submit --down for sending just the bottom of a stack for review.
New
git stack absorb
Fixing a review comment on the third PR down used to mean git down twice, git modify -p, git top, and getting the hunk selection right by hand. Now you stage the fixes and run git absorb (or git ab), and each run of changed lines goes into the commit in the stack that last changed those lines. That commit and everything above it gets rewritten (messages and authors kept), then the branches above are restacked. It doesn't push.
❯ git absorb
pkg/app/sync.go:120-125 into 7ac32ef Give up on a webhook after five attempts (billing-webhook-retries)
pkg/app/sync.go:300 into 4f21abc Version the billing webhook payload (billing-webhook-schema)
README.md:12 not absorbed; no commit in this stack changed those lines
? Absorb 2 hunks into 2 commits? [Y/n]
On a terminal you see the plan and get asked first; --dry-run just shows it and --force skips the question. It goes by lines, not meaning, so lines no commit in the stack touched (and new or deleted files) stay staged, and a run of changes spanning two commits' lines goes to the newer one rather than being split. The old tips are printed, and the README has the recipe for putting things back if it picked the wrong commit. Agents get it as stack_absorb.
git stack reorder
Changes the order of the branches in the stack you're on. On a terminal it shows the stack as a small list (j/k to move the cursor, J/K or shift with the arrows to move a branch, enter to apply); otherwise pass the new order as arguments, bottom to top. A conflict stops just like a restack, and git abort puts the old order back along with the branches.
GitHub can't reorder a stack in place, so if it already has PRs the next git ss dissolves it on GitHub and creates it again in the new order. The PRs stay the same, but the stack's number changes.
git stack move
Takes the current branch, and everything above it, out of its stack and puts it on top of another stack or onto a trunk as a new stack (which can be a different trunk, e.g. moving a stack from main to develop). --only moves just that branch and leaves the ones above behind. Without --onto you get the checkout picker, showing only the places it can actually go.
❯ git move --onto main --only
✔ Moved billing-webhook-alerts from billing-webhook-schema onto main (new stack)
billing-webhook-retries stays on billing-webhook-schema
Same as reorder, the next git ss sorts out the stacks on GitHub, and its notices say what it did with each one.
git stack init (alias track)
Tracks branches you already have (e.g. ones you made with plain git) as a new stack. It only records the stack; nothing is committed, rebased or checked out, so if a branch isn't sitting on the one below it you're told to run git restack. The alias is git track since git won't let an alias replace its own git init.
❯ git track search-index search-api search-ui
✔ Tracking search-index, search-api, search-ui on main
Reorder, move and init are stack_reorder, stack_move and stack_init for agents, so they can reshape a stack without shelling out.
git stack submit --down
Thanks to @StillAyo for this one. git stack submit --down submits the current branch and everything below it, and git stack submit <branch> does the same up to the named branch, leaving the branches above alone. Handy for getting the bottom of a stack reviewed while you keep working on the top.
gh stack can only submit a whole stack, so here git-stack pushes those branches itself (still with --force-with-lease, so it won't overwrite commits someone else pushed), creates any missing PRs and links them into the stack on GitHub. gh stack's editor isn't available on that path, so new PRs take their titles from their commits unless you pass --ai. Plain git ss is unchanged. Agents get it through down and branch on stack_submit.
After upgrading
The new aliases (git absorb, git ab, git reorder, git move and git track) are installed by git stack install, so run it once to pick them up.
What's Changed
New features
- Add git stack absorb and stack_absorb by @DomBlack in #37
- Add submit --down to submit only up to a branch by @StillAyo in #39
- Add git stack reorder, move and init by @DomBlack in #42
Under the hood
- Parse diffs and plan where each staged hunk belongs by @DomBlack in #35
- Rewrite a stack's commits from an absorb plan by @DomBlack in #36
- Teach the metadata adapter and restack engine about reshapes by @DomBlack in #40
- Add reorder, move and init use cases by @DomBlack in #41
New Contributors
Full Changelog: v0.2.3...v0.3.0
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.2.3
git stack sync brings your uncommitted changes along when it moves you off a merged branch, and cleans up worktrees whose directory you deleted.
If you were on a branch whose PR had merged with any uncommitted change at all, sync kept the branch and told you to commit or stash first, even when git would have carried the change across a switch fine. Sync now switches to trunk the way git switch does, brings along what git can carry (untracked files too) and tells you; it only keeps the branch when the switch would overwrite something, and names those files.
Sync also notices worktrees whose directory was deleted by hand, runs git worktree prune for them and says which it forgot, so their merged branches get cleaned up like any other instead of being kept forever. Locked worktrees are left alone, but you'll be told to git worktree unlock if the directory has gone.
What's Changed
New features
Fixes
Full Changelog: v0.2.2...v0.2.3
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.2.2
Commit signing failures no longer hang the MCP server, and create, modify and restack tell you which key to unlock instead of leaving things in a mess.
If you sign commits with an SSH key that isn't loaded into ssh-agent, an agent calling stack_create could hang forever, because ssh-keygen was asking for the passphrase on a terminal nobody could see. Without a terminal, git and anything it runs (ssh-keygen, gpg's pinentry, git's credential prompt) now fail straight away instead; the CLI in a terminal still prompts like before.
That failure now comes back as a signing_failed error from git stack create, git stack modify and git stack restack, with the ssh-add line for your key (or a gpg check for openpgp) and the option of turning signing off for the repo, rather than git's stderr under "unknown". A failed commit in git stack create (a signing failure or a pre-commit hook saying no) also undoes the branch it made, so your changes stay staged and you can just run create again. A restack stopped by signing is no longer reported as a conflict, and git stack continue gets past it once the key is loaded.
What's Changed
New features
Fixes
- Keep children of a TTY-less runner away from the terminal by @DomBlack in #27
- Undo the branch when create's commit fails by @DomBlack in #29
- Report a signing failure from restack's rebase and get past it by @DomBlack in #30
Under the hood
Full Changelog: v0.2.1...v0.2.2
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.2.1
git stack log shows a spinner while it fetches pull requests, so it no longer looks like it's hung.
When the PR cache has gone stale, git stack log asks GitHub for every PR before drawing anything, which in a big repo is a noticeable pause with nothing on screen. That fetch now gets its own "Fetching pull requests…" step with a spinner (only when the cache actually needs refreshing), and git stack submit gets the same when it checks which PRs already exist. Ctrl-C on it now stops log or submit there, rather than submit carrying on and pushing.
What's Changed
New features
Full Changelog: v0.2.0...v0.2.1
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.2.0
Merge now refuses while a stack's checks are failing or still running, git stack log shows what's actually on each branch, and the terminal gets links, titles and status.
Changed
git stack merge used to only check the PRs were open and ready, and left CI to GitHub's branch rules. Those only block on required checks, so in a repo without any a stack with a failing lint or a test still running would merge happily. Merge now looks at the checks on every PR it's about to merge and refuses if any have failed (listing each PR and its failing checks), or asks you to wait if some are still running. Nothing is merged in either case.
If you relied on merging with red or pending checks, fix them and git stack submit again, or pass -f / --force to merge anyway (GitHub's required checks still apply). If the checks can't be read at all, merge carries on with a notice rather than blocking you. For agents, stack_merge gets a force param and the refusal lists the checks so the agent can fix them or ask you first.
New
git stack logshows each PR's title, then the branch's own commits (newest ten, then a count of the rest), so you can tell which branch holds which work without opening the PR. It's all local, so it's still quick.stack_viewgets the commits too.- Every PR number and URL printed to a terminal is now a clickable link (underlined, keeping its usual colour), including in notices, errors, gh stack's output and the checkout picker. Under tmux you need its hyperlinks feature turned on; the README says how.
- The window title shows what git stack is doing while a step runs (e.g. "git stack: Updating main") and goes back to what it was when it's done. Terminals that support OSC 7501 also get a proper status, i.e. working, waiting on you for a prompt or conflict, done or failed. Set
GIT_STACK_NO_TERMINAL_STATUS=1to turn both off.
Fixes
git stack syncno longer says "Synced, nothing to do" when it couldn't move a branch. A briefly held git lock (a status script'sgit status, say) is now retried properly, and if a lock or anything else still stops a branch moving, sync finishes everything else and then tells you which branch wasn't updated and why (exit 1). A checked out trunk is fast forwarded even with uncommitted changes, likegit pull; if your changes are in the way it names the files and gives you the stash command to run.- When trunk has diverged from the remote, sync's "Reset it to the remote?" question no longer draws over a running spinner.
What's Changed
Breaking changes
New features
- Link every PR number and URL we print to a terminal by @DomBlack in #14
- Show what we're doing in the window title by @DomBlack in #15
- Report program status to the terminal with OSC 7501 by @DomBlack in #16
- Show PR titles and each branch's commits in git stack log by @DomBlack in #21
Fixes
- Ask about a diverged trunk between steps, not under one by @DomBlack in #17
- Stop sync claiming success when it couldn't move a branch by @DomBlack in #18
Documentation
Under the hood
- Run CI once per PR push, not twice by @DomBlack in #20
- Skip dot directories in the import rules test by @DomBlack in #22
Full Changelog: v0.1.6...v0.2.0
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.1.6
Rewritten docs and help ahead of the public launch, plus submit now refuses to push over someone else's commits.
Changed
git stack submit won't push over commits someone else pushed to one of your branches unless you pass --force (agents get a matching force on stack_submit). Your own restacks and amends still go straight through, including after a squash merge lower down the stack.
create --insert and submit --update-only are gone; they only ever printed "not supported". submit --stack is still accepted (and does nothing) so older git ss aliases keep working, and git stack install swaps that alias for plain stack submit. --no-verify now only shows up on create and modify, the commands that actually commit.
New
git stack shows "needs push" next to a branch that has moved on since it was last pushed.
Docs
The README and every command's --help have been rewritten in plain terms, with examples where flags combine, and they now cover the questions people ask straight away: does submit force push, what happens after a squash merge, and what it doesn't do.
What's Changed
Breaking changes
Documentation
Full Changelog: v0.1.5...v0.1.6
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.1.5
Adds git stack merge, makes git stack restack native with proper continue and abort, and opens new PRs ready for review by default.
New
git stack merge [branch] merges the stack's PRs up to and including that branch (the current one by default) into trunk in one go, then syncs so the merged branches are deleted and whatever is left gets restacked. Plain gh pr merge refuses a PR that's part of a stack, so this was the one step you still had to go to GitHub for. Pick how the commits land with --squash, --rebase or --merge, or set stack.merge.method; with neither, the repository's own setting applies. It checks every PR is there and ready for review before asking GitHub, and agents get a matching stack_merge tool.
git stack restack no longer goes through gh stack rebase, so nothing gets checked out, the bottom branch moves onto trunk too, and unrelated local edits are left alone. It takes --only and --branch and tells you which branches moved. When it hits a conflict you get normal conflict markers for that one branch; fix them and run git stack continue (or git continue, -a stages everything first) to carry on, or git stack abort to put every branch it moved back where it was. Agents get stack_continue and stack_abort.
git-stack also tells you when a newer release is out. The check runs in the background at most once a day and never slows a command down; it only shows on a terminal, and GIT_STACK_NO_UPDATE_CHECK=1 turns it off.
Changed
New PRs are now opened ready for review rather than as drafts, and submit no longer stops to ask. If you want drafts back, set stack.submit.default to draft (or ask for the prompt); -d and -p still override it per run. The MCP stack_submit tool now follows that setting too, and takes a draft input.
Fixes
- A branch merged into trunk by fast forward is now cleaned up by sync instead of hanging around in
git stack. This works from the first sync after the merge, so one that already landed before upgrading needs agit branch -dby hand. - Sync shows a "Checking pull requests" line instead of looking hung on a big repo, and asks GitHub for the PR list while the fetch runs, so most of that wait goes away.
git stackin a repo with no stacks yet shows the trunk rather than just a warning.
If you installed the Claude Code skill, rerun git stack install --skill so it picks up the ready for review wording.
What's Changed
Breaking changes
New features
- Tell people when a newer release is out by @DomBlack in #3
- Give the pull request list its own headline during sync by @DomBlack in #4
- Add git stack merge and the stack_merge tool by @DomBlack in #7
- Restack natively and add continue and abort by @DomBlack in #10
Fixes
- Show the trunk when there are no stacks yet by @DomBlack in #2
- Clean up branches that trunk was fast forwarded onto by @DomBlack in #5
Under the hood
Full Changelog: v0.1.4...v0.1.5
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
v0.1.4
git stack sync no longer goes through gh stack sync; it does the whole job itself now, which makes it a lot faster and means it tidies up after merged stacks.
New
The old sync checked out every stack in turn to rebase it, which was slow in a big repo, never moved trunk if no stack was checked out, and a single conflict stopped everything. Now git stack sync:
- fetches once and fast forwards each trunk, whether it's checked out or not (a trunk that has diverged is only reset with
-for a yes at the prompt) - deletes branches whose PRs merged or closed, forgets stacks that have fully landed, and cleans up branches left behind by a worktree that went away
- fast forwards any branch the remote moved on (i.e. a commit a reviewer added on GitHub, or something you pushed from another machine), so a later submit doesn't push over it
- restacks every stack without checking anything out, in parallel
A conflict now only stops its own stack at the branch that conflicts; everything else still syncs, and the notice points at git stack restack. Nothing is ever pushed.
It's careful about what it deletes. A branch is kept if it holds work its PR never saw, if its PR was merged into a parent branch rather than trunk, or if it's checked out in another worktree. It also won't restack over an untracked file that the new tree would overwrite, and a dirty checkout is left alone with a notice rather than touched.
Changed
- Sync takes
-f(approve deletions and a trunk reset) and-d(approve deletions), withstack.sync.prunedeciding otherwise.--allis gone, since every trunk gets synced anyway. - Commits whose changes already landed (after a squash merge or a cherry pick) are dropped on restack instead of turning into empty commits that submit then pushes.
Fixes
stack.branchPrefixset todom(without the slash) now gives youdom/my-branchrather thandommy-branch.- A sync no longer dies when
gh stackstill has a branch in its metadata that an earlier sync had already deleted.
Full Changelog: v0.1.3...v0.1.4
Upgrading
git stack update swaps the binary in place, after checking the archive against
checksums.txt. New to git-stack? Start with the install guide.
