# gtr: a worktree manager whose most important command is the one that deletes them

> This is a Bash script that wraps the version control system's built-in worktree feature, and its pitch is aimed squarely at running several coding agents on different branches at once. The design decisions worth reading are a floor of Bash 3.2 so it runs on a stock Mac, a porcelain output flag so an agent can parse it without a protocol server, and a cleanup command that deletes worktrees whose pull requests are already merged.

**coderabbitai/git-worktree-runner** — Bash-based Git worktree manager with editor and AI tool integration. Automates per-branch worktree creation, configuration copying, dependency installation, and workspace setup for efficient parallel development.

- Repository: https://github.com/coderabbitai/git-worktree-runner
- Stars: 1,780 · Forks: 105
- Language: Shell
- License: Apache-2.0
- Published: 2026-09-30 · Updated: 2026-09-30 · Language: en
- Canonical page: https://hysenlabs.com/projects/coderabbitai-git-worktree-runner

## The problem is stated in terms of agents, and the solution is a shell script

The readme opens by explaining worktrees in the simplest possible terms, which is the right register for a tool aimed at people who have heard of the feature and not used it. One branch per directory, so you can fix a bug while working on a feature without stashing.

Then it makes an unusual claim about the state of the art. The heading is that everyone is using worktrees wrong, or not at all, and the four complaints are all about interruption. Switching branches to run a test breaks your train of thought. Running anything against the main branch means copying things by hand. Reviewing somebody else's pull request means stopping what you were doing. And the fourth one is the reason the tool exists: running coding agents in parallel on different branches is described as close to impossible without worktrees.

That last item reframes the whole project. A worktree manager in 2024 was a convenience for people juggling long-lived feature branches. A worktree manager in 2026 is infrastructure for running four agents at once, each in its own checkout, and the screenshot at the top of the readme shows exactly that. The agent does not know about worktrees. The agent knows how to edit files and run commands in a directory. Give each one a directory and you have parallelism; give them the same directory and they will overwrite each other.

So the tool is a Bash script that wraps a version control command, and that is the correct amount of machinery. There is no daemon, no configuration language, no runtime to install. You put a script on your path, named so that the version control system dispatches to it as a subcommand, and you get shorter commands.

Installation is a tap and an install:

```bash
brew tap coderabbitai/tap
brew install git-gtr
```

The requirements section is two lines and both are floors rather than recommendations. The version control system needs a specific minimum, stated as being for the move and remove subcommands, and the shell needs a minimum chosen so that the tool runs on a stock Mac. Neither is negotiable in the way a requirement usually is, and the second one has shaped the code more than anything else in the repository.

## Two invocation forms appear in the same code block

The usage section is a single commented code block, and if you read it carefully you will notice that the commands are not all written the same way.

Most of them are prefixed. You configure the default editor and the default agent with a config subcommand, create a worktree with a new subcommand, open a pull request worktree with a pr subcommand followed by a number, and list everything with a list subcommand. All of those go through the version control system's own dispatch, which is why they are written as if the version control program were running them.

Then, without warning, the navigation commands drop the prefix. The create-and-change-directory form is written bare. The pull request form is written bare. The interactive directory picker is written bare. The cleanup command that removes worktrees for merged or closed pull requests is written bare.

Both forms appear in the same block, in the same style, separated by a comment. There is no note explaining the difference, and no statement of which one is canonical.

This matters more than a documentation nit usually does, because the installed name is the hyphenated one. A package manager installs a file called git-something, and the version control system finds it on the path and dispatches the rest of the command line to it. That mechanism is the entire reason for the hyphenated name, and it only works with the prefix present. A bare invocation requires a second entry on the path under the unhyphenated name, and the install instructions in the readme, whether they go through a package manager, an install script or a manual symbolic link, only ever create the hyphenated one.

So the commands a user is most likely to want for navigation and cleanup, the ones that make the tool pleasant enough to use daily, are written in a form that the documented installation does not produce. The fix is either a second symbolic link or a documented wrapper, and the fact that neither appears suggests the two forms came from different eras of the project and the earlier one was not retired.

The readme does mention that two of the affected commands require shell integration, and it offers a portable alternative for getting into a directory without it. That is good practice and it is unrelated to the prefix question.

## Running a command inside a worktree is what makes any of this usable

There is one command in this tool that deserves more attention than the rest of the list combined, and it is the shortest one.

The run subcommand takes a worktree identifier and a command, and executes that command inside it. In the readme's example it runs a test command in a named worktree.

Consider what that solves. A worktree is a fresh checkout of a branch, and a fresh checkout of most modern projects does not run. The dependencies are not installed. The environment file does not exist. The build has not been made. So the honest state of a new worktree is that you cannot run the test suite in it, which means every worktree you create is a worktree you cannot use for testing, which means you create fewer of them, which defeats the purpose.

The tool's answer to that has two parts, and this command is one of them. The other is a post-creation hook: a configurable command that runs automatically after a worktree is created, which in practice means an install step. The comparison table in the readme names both, listing manual copy and paste of configuration files against automatic copying of selected files, and manual install followed by build against an automatic post-create hook.

Those two features together are the difference between a worktree manager and a worktree generator. One produces directories. The other produces directories you can immediately run a test suite in, which is the precondition for running an agent in one, because an agent that cannot run the tests cannot tell whether it broke anything.

The selective copy deserves a note too, because the alternative is copying your entire configuration directory into every new worktree and then wondering why your local overrides are being committed. The setting takes a list of patterns, so you copy the environment template and the editor configuration and nothing else, and the files you never wanted to share stay out of the branch.

The hooks are described as running after creation and after removal, which is the right pair. A post-create hook that installs dependencies is the useful one. A post-remove hook is for cleanup of whatever the create hook left behind, such as a build directory that is not tracked and would otherwise be orphaned in the parent repository.

## Deleting worktrees is the feature almost nobody implements

There is a command that removes a single worktree by name, and there is a second command that removes all of the worktrees whose associated pull requests are done, and the second one is the reason to think this project will be used for more than a week.

Worktree usage decays for a boring reason. You create a worktree, you do the work, you merge the branch, and the directory stays. There is no cost to leaving it, so you leave it. Three months later you have nineteen directories, eleven of which contain branches that no longer exist remotely, and the parent directory of your project looks like a mess. At that point most people abandon worktrees entirely and go back to switching branches, and the tool's whole value proposition evaporates.

So the cleanup command takes two conditions, and the conditions are about the state of the work rather than the state of the directory. Merged, and closed. Both require asking a hosted forge, which is why the readme notes that a forge command line tool must be installed. The tool is going out to your pull request tracker, asking which of your branches have landed and which have been closed, and removing the matching worktrees.

That is the right design because it uses information you cannot get locally. A merged branch is still a branch, still checked out, and still perfectly valid as far as the version control system is concerned. Only the forge knows the work is finished. A local heuristic would either be wrong or would require you to remember to pass a flag.

The dependency on an external command line tool is a real cost and it is stated rather than hidden. It also means the command behaves differently depending on which forge you use, since it delegates to whichever of the two supported tools is present. For a team that standardises on one, that is invisible. For somebody who works across two, it is a small sharp edge.

The single removal command completes the lifecycle, and its existence alongside the automated one suggests the intended rhythm: clean up in bulk when you remember, remove individually when you are done with something before its pull request closes.

## Porcelain output instead of a protocol server, and a note about what launching means

The section aimed at coding agents contains a decision that is worth arguing about, and the author argues for it in two sentences.

The claim is that a separate protocol server is not required, because any agent capable of running a shell command can use the tool directly. What is offered instead is a flag that creates a worktree and prints its path in a stable, machine-readable form, chosen deliberately to echo the version control system's own convention for output intended for programs rather than for people.

That convention is a good one to borrow. Output designed for parsing is a contract, and a contract that is just text has properties a tool schema does not: it can be read by a human when something goes wrong, it can be piped into another program, it works in a shell script, and it does not require the agent to have a protocol client installed. An agent that can run a command already has everything it needs.

The alternative, wrapping the same two operations in a protocol server, would add a running process, a transport, a schema and a lifecycle, in exchange for structured arguments. For a tool whose surface is create-this-directory and tell-me-where-it-is, that is a poor trade. The readme also points to a separate document containing a policy you can paste into an agent instruction file, an explicit output contract, and lifecycle examples, which suggests the author thought about how an agent should be told to use this rather than leaving it to improvisation.

The second thing in that section is a phrase worth pausing on. Built-in adapters cover the popular tools, and there is also what the readme calls a safe fallback that works with any other agent command line found on the path. Adapters mean a known tool is launched in a known way. The fallback means an arbitrary executable on your path is launched on request.

That is genuinely useful, since new agent tools appear faster than anybody can write adapters. It is also the feature to think about before you use it, because what the tool does in the fallback case is run a program you named. That is what you asked for, and the argument is short, but the word safe in the readme is doing some work that a threat model should do explicitly. Whoever supplies the command supplies what it can do with your worktree.

## A shell floor chosen so it runs on a stock Mac

The requirements are Git at a specific minimum and Bash at a specific minimum, and the second one is the interesting one because of the reason given.

The stated floor is version 3.2, with a note that macOS ships 3.2 and that 4.0 or later is recommended for advanced features. Any developer who has worked across operating systems knows exactly what that sentence means. The default shell on every Mac is still the version that shipped with an operating system release from around 2007, because changing it would break scripts, so a tool that wants to run on a Mac without asking anybody to install a newer shell has to write to a language standard from the same era.

The cost is real and it is worth being concrete about. That generation of the language has no associative arrays, which is the data structure you would reach for to store per-worktree state in memory. It has no first-class way to read a file into an array, so scripts carry a loop for it. Its process substitution and here-string behaviour differ subtly across platforms, and its printf handling has sharp edges. Every one of those is a line of compatibility code that a tool written for a current shell would not have.

The benefit is reach. A tool that runs on a stock Mac, on whatever version of Linux a CI image happens to have, and under the Bash that ships with a Windows installation is a tool that nobody has to install a prerequisite for. For a utility whose entire job is to be typed a few times a day, that trade is almost always right, and it is a deliberate narrowing of the addressable audience in exchange for zero setup.

The recommendation of a newer version for advanced features is a slightly softer statement than it first appears, because if the floor is 3.2 then every feature has to work on 3.2 or be behind a guard. Either the advanced features are cosmetic, or they are conditionally enabled, and the readme does not say which. If you are the kind of person who would use them, that is a question worth asking.

The platform story is otherwise consistent. Windows support is qualified as running under a Windows Bash compatibility layer, and the shell completions are offered for the two Unix shells and one other, with no Windows equivalent. That is the right scope: the tool works where a POSIX shell exists, and it does not pretend otherwise.

## Repository-scoped config, and a digit that means the main checkout

Two small design choices in this tool are better than they look, and both are about reducing the number of things you have to remember.

The first is that configuration is repository-scoped and settings are namespaced under the tool's own prefix. The readme's setup step is two commands that name a default editor and a default agent, and then every later command is short because those defaults are already stored. The alternative, passing an editor flag every time you create a worktree, is one extra argument per invocation and one more thing to forget.

The scoping matters as much as the defaults. Settings that live with the repository rather than in a per-user file are inherited by everyone who clones it, so a team agrees on which editor and which agent to use without a wiki page. The namespace means the settings do not collide with anything else in the same configuration store, which is a real problem for tools that write into shared dotfiles. And the naming convention, a prefix followed by a dot followed by a section and a key, means the whole configuration is discoverable by looking at one place rather than by reading the source.

The features list calls this configuration over flags, and that phrase is doing more work than it appears. A tool that is invoked constantly, by people who are not thinking about it because they are thinking about their code, should have as few decisions per invocation as possible. Every flag you remove is a flag you cannot get wrong.

The second choice is a convention rather than a feature, and it is this: the commands accept a worktree identifier, and a single digit refers to the main checkout. So every command works on the main repository without needing a special case, and the same command works on any named branch. A command that has to branch internally on whether the argument looks like a branch name or a path is a command with a special case, and special cases accumulate.

Both of these are the kind of detail that a wrapper tool gets right when its author has actually used the underlying command enough to know where it hurts. The readme's own admission that the raw command is verbose, manual and error-prone is not a criticism of the version control system. It is an observation that its interface was designed for a person at a terminal, and that a person driving an agent needs a different one.

## Conclusion

gtr is worth installing if you work on more than one branch at a time, which in 2026 means if you run a coding agent in parallel with your own editing, because the feature that makes that possible is running commands inside a named worktree rather than reinstalling dependencies each time. It is a poor fit on Windows outside Git Bash, since the completions and the shell integration are POSIX-only, and a poor fit if you need a graphical tool, because it is a shell script with subcommands and no interface. Set the editor and agent defaults once per repository so your team inherits them, use the porcelain flag in any automation, and treat the AI launcher as running an arbitrary executable from your path rather than as a sandbox, then wire the cleanup command into your routine or your worktree directory will quietly fill with branches you finished months ago.

## FAQ

### What does gtr add on top of the built-in git worktree command?

It wraps worktree creation with per-repository defaults for an editor and a coding agent, selective copying of configuration and environment files into the new worktree, a hook that runs automatically after creation so dependencies are installed, a command to run any program inside a named worktree, and a cleanup command that removes worktrees whose pull requests are merged or closed.

### What are the requirements for gtr?

Git 2.17 or later, for the move and remove subcommands, and Bash 3.2 or later, which is the version macOS ships. A newer Bash is recommended for advanced features. Windows is supported through a Git Bash compatibility layer, and shell completions are provided for the Unix shells.

### How do coding agents use gtr without an MCP server?

The readme states that no separate protocol server is required, because an agent that can run a shell command can use the tool directly. A porcelain output flag creates a worktree and prints its path in a stable machine-readable form, and a separate document provides a policy you can paste into an agent instruction file along with an output contract and lifecycle examples.

### How does gtr clean up worktrees?

There is a command that removes all worktrees whose associated pull requests have been merged or closed. It requires a hosted forge command line tool to be installed, because the version control system alone cannot tell you that a branch's work is finished. A single-worktree removal command is also provided for finishing early.

### How is gtr configured for a team?

Settings are namespaced and stored per repository rather than per user, so setting a default editor and a default agent once in a repository means everyone who clones it inherits the same behaviour. The features list names this as configuration over flags, so the day-to-day commands stay short.

## Sources

- [coderabbitai/git-worktree-runner on GitHub](https://github.com/coderabbitai/git-worktree-runner)
- [Issues](https://github.com/coderabbitai/git-worktree-runner/issues)
- [License: Apache-2.0](https://github.com/coderabbitai/git-worktree-runner/blob/main/LICENSE)
- [README](https://github.com/coderabbitai/git-worktree-runner/blob/main/README.md)
- [Releases](https://github.com/coderabbitai/git-worktree-runner/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/coderabbitai-git-worktree-runner
