Open-source project
gitext-rs/git-stack avatar
gitext-rs/git-stack

git-stack: stacked branches without rewriting your workflow

Stacked branch management for Git

651 stars23 forksRustApache-2.0

At a glance

What is it?
git-stack is a Rust CLI that automates the mechanics of stacked branch workflows, rebase maintenance, per-commit command runs and push readiness, while keeping branches as the unit of work and review. It suits teams that already live in pull request reviews, and it will not resolve your rebase conflicts for you.
Who is it for?
git-stack fits a team that reviews through pull requests, already works in short-lived branches, and wants the rebase bookkeeping of a stack handled by a tool rather than by hand. It does not fit a team that wants its branches to be the deliverable, or one that needs conflict resolution automated, since the project states plainly that it gives up and leaves the merge to git rebase.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 19 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Branches as the unit of work, not stacked diffs

The project describes itself as another approach to bringing the Stacked Diff workflow to pull requests and branches, one that aims to be unintrusive to a project's workflow. The phrase that matters is in the About section: branches are the unit of work and review in git-stack.

Stacked diffs, the technique described in the linked article, treats a set of dependent changes as a single unit that gets reviewed together. git-stack takes a different route. You still create ordinary branches on top of each other, and the review still happens through pull requests, but the tool handles the mechanics that a stack creates: keeping each branch rebased on its parent, working out which remote branch a stack is rooted on, and pushing only the parts that are ready.

The stated benefit is intrusiveness. A tool that changes how your team reviews its work is a large adoption cost regardless of how good it is, and this one deliberately keeps git, branches and pull requests in the roles your team already knows.

The feature list makes the scope concrete: upstream parent branch auto-detection, maintaining branches relative to each other through rebase, deferring all permanent changes until the end, for example HEAD or re-targeting branches, always leaving you in a good state, separating out pull and push remotes for working from a fork, detecting which branches are ready on push, undo support that backs up branch state before rewriting history, and the ability to move through the stack and perform operations on it.

Defers permanent changes until the end

The deferral design is the core mechanism and it is described with a comparison to git revise: git-stack defers all permanent changes until the end, always leaving you in a good state.

What that means in practice is that git-stack does not leave your checkout on some temporary detached state while it works. It performs the rewrites it needs, and when it is done, your branch is where it should be with its history updated. The point of that design is that a tool which rewrites your history while you are mid-feature should never leave you stranded on the wrong branch or with the wrong commits checked out.

The undo support is the safety net underneath it. Before rewriting history, git-stack backs up branch state, and the documentation recommends installing the companion project git-branch-stash for easily undoing git stack operations, with the command to install it being a cargo install of git-branch-stash-cli. Uninstalling git-stack leaves a .git/branch-stash directory behind, and the documentation says removing this is safe and will have no effect.

This pairing of deferral and backup is what makes a history-rewriting tool acceptable in a working repository. A tool that rewrites without a backup is a tool people avoid; a tool that rewrites, defers its visible effects to the end and keeps a stash of the previous state is a tool people run daily.

git sync, git stack and git run in a working session

The example in the documentation shows a short session on a branch named jira-3423423: a git sync, a git stack, and a git run cargo test.

The three commands do different things. git sync auto-detects your parent remote branch, for example main, performs a git pull --rebase against that remote and parent, and then rebases your branch and any development branches on the stack onto that parent. git stack shows the stacked branches. git run walks each commit in the stack, running a command until it fails.

That last one is the most useful and the least obvious. The equivalent manual sequence, which the documentation spells out in full, is a series of git checkout commands to each commit in the stack followed by the test command at every step. For a stack of six commits that is a dozen commands, and doing it by hand every time is how stacks rot.

The manual comparison also shows the structure git-stack reasons about. The parent branch of jira-3423 is jira-3259, which sits on jira-3154, which sits on main. The rebase is expressed with HEAD~ and HEAD~~ offsets and --onto targets. That is the vocabulary of the tool: the stack is a chain of parent relationships, and syncing the stack means rebasing the bottom against the remote and each branch against the one below it.

Protected branches and the two-remote fork workflow

Two configuration ideas do most of the work. The first is protected branches, which are branches git-stack should not modify. The documentation says you usually mark shared or long-lived branches as protected, like main and v3. Note that git-stack will still rebase local protected branches against their remote counterparts, so protection means do not rewrite the branch itself, not do not touch it.

Configuration happens in the git config, and the team adoption path is described explicitly: when adopting git-stack as a team, you can move the protected branches from $REPO/.git/config to $REPO/.gitconfig and commit it. That is a small detail with a large effect, because it means the protected branch list becomes shared configuration that reviewers can see rather than a setting each person reinvents.

The second idea is the pull remote, for when you work from a fork where upstream is a different remote than origin. The setting is a git config --add stack.pull-remote entry. Separating pull and push remotes is what lets a fork-based contributor sync against the upstream repository while still pushing to their own fork.

Two commands help you verify the result. git-stack --protected -v tests the configuration and prints it verbosely, and git-stack --dump-config - dumps the config. Running the first of those after any config change is the cheapest way to avoid a surprise later.

Installing the binary and the alias trick

There are two documented install routes. A pre-built binary can be downloaded from the releases page and is installable via gh-install, or the tool can be installed from source with cargo:

bash
$ cargo install git-stack

The companion for undoing stack operations installs the same way:

bash
$ cargo install git-branch-stash-cli

The clever part of the setup is the alias mechanism. git-stack ships as a single binary, but it can help configure aliases by running git stack alias --register, so the command becomes git stack alias --register and afterwards git sync, git stack, git next, git prev, git reword, git amend and git run all work as plain git subcommands. You can then modify the aliases if you want to make some flags the default.

The reason for the alias approach rather than asking people to type git-stack sync is collision avoidance, since the project wants the commands brief without clashing with existing git subcommands. The registration is reversible: git stack alias --unregister removes them, and that is the first thing to run during uninstall.

The commands themselves cover the workflow: git stack alias, git stack, git sync, git next, git prev, git reword, git amend and git run. The full reference lives in docs/reference.md alongside configuration, design, comparison and a changelog.

A full session from git switch to git stack --push

The Getting Started section gives a complete session that is worth reading end to end, because it shows the order of operations the tool expects. You start by updating branches against upstream with git sync, then start a new branch with git switch -c feature1, commit work, and run git run cargo check to test each commit in the stack.

The middle of the session is the interesting part. git prev steps back in the stack, you amend a commit to fix problems, and git run cargo check again. The workflow assumes you will find problems while testing commit by commit and that the fix belongs in an earlier commit, which is the whole point of a stack.

At the end, the sequence is git sync to clean up in preparation for a push, git run cargo test to verify everything, and then git stack --push to push what is ready.

That last command is where the tool earns part of its keep. On push it detects which branches are ready, for example the root of the stack and no WIP. A branch that still has work in progress is held back, so you push a coherent slice rather than the top of a half-finished chain.

The test setup here is cargo, which suits a Rust project, but nothing in the design ties git-stack to a language. git run takes any command, and the example walks commits running that command until it fails.

Where git-stack is the wrong tool

The first limitation is stated in the project itself, in a section titled Non-features: conflict resolution. git-stack will give up and you will have to use git rebase yourself to resolve the conflict. That is an honest boundary, and it also means a stack that hits a conflict still costs you the manual work, at exactly the moment when you are least inclined to do it.

The second limitation is conceptual. The whole model assumes a stack of branches that are rebased onto each other, which means the history of every branch in the stack is rewritten whenever the branch below it changes. That is fine when a branch is a work in progress that nobody has based a commit on. It is a problem when someone has already pulled your branch, or when a review comment references a specific commit that moves. The deferral design mitigates the surprise, not the underlying constraint.

The third is the alternative worth naming. Instead of stacking branches, you can keep one branch per change and use a dependency tool that tracks ordering without rewriting history, or you can adopt a stacked diffs workflow where the review unit is the stack rather than the branch. The comparison document in the repository, docs/comparison.md, is where the project sets out the differences with other stacked git tools, and that is the file to read before choosing.

There is also a workflow where git-stack is simply unnecessary. If your team works in one long-lived branch, or if your pull requests are large and self-contained rather than small and dependent, there is no stack to maintain, and the tool adds an indirection between you and git for no gain.

Editorial conclusion

git-stack fits a team that reviews through pull requests, already works in short-lived branches, and wants the rebase bookkeeping of a stack handled by a tool rather than by hand. It does not fit a team that wants its branches to be the deliverable, or one that needs conflict resolution automated, since the project states plainly that it gives up and leaves the merge to git rebase. Before adopting it, mark your shared branches as protected and check the config with git-stack --protected -v, keep the git-branch-stash companion installed so a bad rewrite can be undone, and test the flow on a scratch repository before you point it at a branch with unreviewed commits.

Frequently asked questions

How do I install git-stack?

Download a pre-built binary from the releases page, which is installable via gh-install, or install it from source with cargo install git-stack. The documentation also recommends installing git-branch-stash-cli for undoing git stack operations.

What does git stack --push do?

On push, git-stack detects which branches are ready, for example the root of the stack and no WIP, and pushes those rather than the top of a half-finished chain.

Does git-stack resolve rebase conflicts?

No. The project lists conflict resolution as a non-feature: git-stack will give up and you will have to use git rebase yourself to resolve the conflict.

How do I mark branches as protected in git-stack?

Use git-stack --protect <glob> to protect a branch locally, and run git-stack --protected -v to test and print the config. When adopting it as a team you can move the protected branches from $REPO/.git/config to $REPO/.gitconfig and commit that file.

What is the git run command in git-stack?

git run walks each commit in the stack, running a command until it fails. The documentation compares it to manually checking out every commit in the stack and running the test command at each one.

Official sources

  1. gitext-rs/git-stack on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gitext-rs-git-stack.svg)](https://hysenlabs.com/projects/gitext-rs-git-stack)

Was this useful?