{"id":47638706,"url":"https://github.com/davedev42/git-worktree-manager","last_synced_at":"2026-05-17T11:02:30.983Z","repository":{"id":345266019,"uuid":"1185145401","full_name":"DaveDev42/git-worktree-manager","owner":"DaveDev42","description":"Rust rewrite of claude-worktree — CLI integrating git worktree with AI coding assistants","archived":false,"fork":false,"pushed_at":"2026-04-12T15:58:06.000Z","size":653,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-12T16:12:29.584Z","etag":null,"topics":["ai","cli","developer-tools","git","rust","terminal","worktree"],"latest_commit_sha":null,"homepage":"https://github.com/DaveDev42/git-worktree-manager","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DaveDev42.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-18T09:32:28.000Z","updated_at":"2026-04-12T15:54:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/DaveDev42/git-worktree-manager","commit_stats":null,"previous_names":["davedev42/git-worktree-manager"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/DaveDev42/git-worktree-manager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveDev42%2Fgit-worktree-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveDev42%2Fgit-worktree-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveDev42%2Fgit-worktree-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveDev42%2Fgit-worktree-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DaveDev42","download_url":"https://codeload.github.com/DaveDev42/git-worktree-manager/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DaveDev42%2Fgit-worktree-manager/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31757482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T13:27:56.013Z","status":"ssl_error","status_checked_at":"2026-04-13T13:21:23.512Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","cli","developer-tools","git","rust","terminal","worktree"],"created_at":"2026-04-02T00:31:40.583Z","updated_at":"2026-05-17T11:02:30.976Z","avatar_url":"https://github.com/DaveDev42.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git-worktree-manager (gw)\n\n[![crates.io](https://img.shields.io/crates/v/git-worktree-manager.svg)](https://crates.io/crates/git-worktree-manager)\n[![CI](https://github.com/DaveDev42/git-worktree-manager/actions/workflows/test.yml/badge.svg)](https://github.com/DaveDev42/git-worktree-manager/actions)\n[![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](LICENSE)\n\n`gw` is a lean git worktree manager. Inspired by [mr (myrepos)](https://myrepos.branchable.com/), it uses cwd-based scope discovery — no global registry, no cross-repo flags — so commands do exactly what you expect relative to where you run them. Target resolution is strict and consistent: worktree name → branch name → path.\n\nAI coding-assistant integration is built in: `gw new` creates a worktree and launches your AI tool of choice in it (use `-T skip` to skip the launch). Trailing positional args after the branch name are forwarded verbatim to the AI tool — `gw new feat-x -- --model opus` runs `claude --model opus` inside the new worktree. Future AI-assisted operations (e.g. `--ai` on merge / rebase) layer on top of the same worktree primitives.\n\nSingle static binary (~1.9MB), ~3ms startup. Supports macOS (ARM64/x86), Linux (ARM64/x86), and Windows (x86_64).\n\nSuccessor to [claude-worktree](https://github.com/DaveDev42/claude-worktree) (Python), rewritten in Rust.\n\n\u003e **Migration note:** the legacy `cw` binary alias and `cw-cd` shell function were removed in 1.0. Existing user data — `.cwshare`, `.cwconfig.json`, and `~/.config/claude-worktree/` — is still read transparently; only the binary/shell entry points changed. Update aliases or shell rc files that reference `cw` / `cw-cd` to use `gw` / `gw-cd`.\n\n## Install\n\n```bash\ncargo install git-worktree-manager\n```\n\nThis installs the `gw` binary.\n\n\u003cdetails\u003e\n\u003csummary\u003eOther installation methods\u003c/summary\u003e\n\n```bash\n# Homebrew (macOS/Linux)\nbrew tap DaveDev42/tap\nbrew install git-worktree-manager\n\n# cargo-binstall (pre-built binary, no compile)\ncargo binstall git-worktree-manager\n\n# Direct download\n# https://github.com/DaveDev42/git-worktree-manager/releases/latest\n```\n\n\u003c/details\u003e\n\nAfter installing, run `gw upgrade` at any time to update to the latest version (self-replacing binary). Pass `--yes` to skip the prompt — required in non-TTY environments (CI, nested processes). Homebrew users should use `brew upgrade git-worktree-manager` instead.\n\n## Quick Start\n\n```bash\n# Create a worktree (and launch your AI coding assistant in it)\ngw new fix-auth\n\n# Override the launcher for this invocation only (e.g., background WezTerm tab)\ngw new fix-auth -T w-t-b\n\n# Just the worktree, no AI tool (`-T noop` and `-T none` are aliases for `skip`)\ngw new fix-auth -T skip\n\n# Pass an initial prompt to the AI tool\ngw new fix-auth --prompt \"Fix the JWT token expiration bug in auth.rs\"\n\n# Read the prompt from stdin (Unix idiom — replaces the old --prompt-stdin flag)\nsome-cmd | gw new fix-auth --prompt -\n\n# Forward extra args to the AI tool (everything after the branch name, or after `--`)\ngw new fix-auth -- --model opus --resume\n\n# Or read the prompt from a file (recommended for multi-line / quoted content)\ngw new fix-auth --prompt-file /tmp/task.md\n\n# List all worktrees (rich human-readable output)\ngw list\n\n# Resume an AI session in an existing worktree\ngw resume fix-auth\n\n# Launch AI tool in the current worktree (or a named one)\ngw spawn\ngw spawn fix-auth\n\n# Remove a worktree (interactive multi-select, or by name)\ngw rm fix-auth\ngw rm -i\n\n# Run a command in every worktree in scope\ngw run -- cargo test\n\n# Run a command in one specific worktree\ngw exec fix-auth -- git status\n```\n\n## Forwarding args to the AI tool\n\n`gw new`, `gw resume`, and `gw spawn` accept all of gw's own options *before* the\npositional argument; everything after is forwarded verbatim to the underlying AI\ntool (claude / codex / gemini). Use `--` to disambiguate when forwarded args\nstart with a hyphen:\n\n```bash\ngw new feat-x --base main -- --model opus --append-system-prompt \"be terse\"\ngw resume feat-x -- --model haiku\ngw spawn  feat-x --prompt \"summarize the diff\" -- --print  # ERROR: --prompt + forward args\n```\n\n`--prompt` / `--prompt-file` and forward args are mutually exclusive — both end\nup setting the AI tool's prompt, so combining them would silently produce two\nprompts. Pick one.\n\n`gw resume` always re-injects the AI tool's resume flag (`--continue` for\nclaude, `--resume` for codex/gemini) even when forward args are present.\n\n### Environment variables\n\nBy default, gw snapshots `\u003cTOOL\u003e_*` env vars at invocation time (e.g.\n`CLAUDE_*` when the AI tool is claude) and re-injects them into the spawned\nprocess. This matters for launchers like wezterm/iterm/tmux/zellij that go\nthrough a daemon — without re-injection, the new tab inherits the daemon's env,\nnot the env of the shell that ran `gw`. Pass `--no-env-forward` to opt out.\n\n```bash\nCLAUDE_CONFIG_DIR=~/work-claude gw new feat-x\n```\n\nFor one-off non-`\u003cTOOL\u003e_*` vars, use the shell — `FOO=bar gw new feat-x` works\nfor the foreground / detached launchers that inherit the parent env directly.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `gw new \u003cname\u003e` | Create worktree (and launch AI tool, unless `-T skip`) |\n| `gw resume [target]` | Resume AI session in a worktree |\n| `gw spawn [target]` | Launch AI tool in an existing worktree (default: current) |\n| `gw rm [targets...]` | Remove one or more worktrees (`-i` interactive, `--dry-run`, `--force`) |\n| `gw list` | List all worktrees (rich, human-readable) |\n| `gw ls` | Print all worktrees as TSV (for scripts) |\n| `gw exec \u003ctarget\u003e -- \u003ccmd\u003e` | Run a command in one specific worktree |\n| `gw run -- \u003ccmd\u003e` | Run a command in every worktree in scope |\n| `gw guard` | Claude Code hook helper: allow or block inbound tool use |\n| `gw doctor` | Run diagnostics (5 health checks) |\n| `gw upgrade` | Check for updates / upgrade |\n| `gw setup-claude` | Install Claude Code skill for worktree task delegation |\n| `gw shell-setup` | Interactive shell integration setup |\n| `gw config \u003clist\\|get\\|set\\|edit\u003e` | View or edit gw config (global / `.cwconfig.json`) — see [Configuration](#configuration) |\n\n## Scope and Target Resolution\n\n### Scope discovery\n\n`gw run`, `gw list`, `gw ls`, and other scope-wide commands discover worktrees relative to the current working directory: it walks up first to find a `.cwconfig.json`-rooted scope, falling back to a downward walk from cwd if none is found. There is no global registry and no cross-repo flags.\n\n### Target resolution\n\nWhen a command accepts a `[target]` argument, resolution is strict and ordered:\n\n1. Exact worktree name\n2. Branch name\n3. Path\n\nNo ambiguity modes, no lookup-mode flags. The first match wins.\n\n## `gw run` and `gw exec`\n\n`gw run` executes a command in every worktree in scope. `gw exec` runs in exactly one.\n\n```bash\n# Run tests in all worktrees, 4 in parallel\ngw run -j 4 -- cargo test\n\n# Only worktrees whose name matches a glob\ngw run --only 'feat-*' -- npm install\n\n# Skip the main worktree\ngw run --no-main -- cargo clippy\n\n# Keep going even if some worktrees fail\ngw run --continue-on-error -- cargo build\n\n# Run in one specific worktree\ngw exec fix-auth -- git log --oneline -5\n```\n\n`gw ls` emits TSV columns (`worktree_id`, `branch`, `status`, `age`, `repo_root`, `path`) for scripting:\n\n```bash\ngw ls | awk -F'\\t' '{print $2, $6}'   # branch + path\n```\n\n## Terminal Launchers\n\nThe launcher used by `gw new` / `gw spawn` / `gw resume` is resolved from the highest-priority source available, in this order:\n\n| Priority | Source | Example |\n|----------|--------|---------|\n| 1 (highest) | `-T, --term \u003cMETHOD\u003e` CLI flag | `gw new fix-auth -T w-t-b` |\n| 2 | `CW_LAUNCH_METHOD` env var | `CW_LAUNCH_METHOD=iterm-tab gw new fix-auth` |\n| 3 | repo-local `.cwconfig.json` `launch.method` | `{ \"launch\": { \"method\": \"tmux\" } }` |\n| 4 | global `~/.config/git-worktree-manager/config.json` `launch.method` | (same JSON shape) |\n| 5 (default) | built-in default | `foreground` |\n\nUse `-T skip` (or its aliases `-T none` / `-T noop`) to skip the AI tool launch entirely. The `-T` value accepts any canonical method name or alias (see table below); for tmux/zellij, append `:\u003csession-name\u003e` to name the session (e.g., `-T tmux:mywork`).\n\n| Launcher | Variants |\n|----------|----------|\n| **Foreground** | `foreground` (default) |\n| **Detached** | `detach` |\n| **iTerm** | `iterm-window`, `iterm-tab`, `iterm-pane-h`, `iterm-pane-v` |\n| **tmux** | `tmux`, `tmux-window`, `tmux-pane-h`, `tmux-pane-v` |\n| **Zellij** | `zellij`, `zellij-tab`, `zellij-pane-h`, `zellij-pane-v` |\n| **WezTerm** | `wezterm-window`, `wezterm-tab`, `wezterm-tab-bg`, `wezterm-pane-h`, `wezterm-pane-v` |\n\nNew tabs/windows (`tmux-window`, `zellij-tab`, `wezterm-window`/`wezterm-tab`/`wezterm-tab-bg`) are named after the worktree directory so you can tell sessions apart at a glance.\n\n## Claude Code Integration\n\nInstall the gw plugin into your Claude Code setup:\n\n```bash\ngw setup-claude    # One-time: installs the gw plugin to ~/.claude/plugins/gw/\n```\n\nThe plugin bundles two skills:\n\n- **`delegate`** — invoked via `/gw \u003ctask description\u003e`. Spawns a new worktree and a Claude Code session inside it with the given task as the initial prompt. One-shot, fire-and-forget.\n- **`manage`** — auto-applies when you (or Claude) run worktree management commands. Encodes a worktree-health rulebook and a catalog of recommended Claude Code hooks. When relevant, Claude will *suggest* installing a hook into your project's `.claude/settings.json` and edit it on your consent — gw itself never modifies any settings file.\n\n## Shell Integration\n\n```bash\n# Interactive setup (recommended)\ngw shell-setup\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eManual setup\u003c/summary\u003e\n\n```bash\n# bash/zsh — add to your shell rc file\nsource \u003c(gw _shell-function bash)\n\n# fish\ngw _shell-function fish | source\n```\n\n\u003c/details\u003e\n\nThis enables:\n- **`gw-cd \u003ctarget\u003e`** — navigate to a worktree directory (interactive selector if no args)\n- **Tab completion** — worktree names and branch names from the current scope, plus options\n\nGenerate shell completions separately with `gw --generate-completion \u003cbash|zsh|fish|powershell|elvish\u003e`.\n\n## Configuration\n\nConfig is resolved in layers (later layers override earlier ones): built-in defaults → `~/.config/git-worktree-manager/config.json` → repo-local `.cwconfig.json`.\n\nAlso reads legacy `~/.config/claude-worktree/config.json` from the Python predecessor.\n\n### `gw config`\n\nA small surface for viewing and editing config without hand-rolling JSON:\n\n| Command | What it does |\n|---|---|\n| `gw config list` | Show every known key with its resolved value and the scope it came from (`[global]`, `[repo]`, `[override: repo]`, `[default]`). |\n| `gw config get \u003ckey\u003e` | Print the resolved value of a single key (script-friendly: one line, exits non-zero when nothing is set). |\n| `gw config set \u003ckey\u003e \u003cvalue\u003e` | Write to global config. Add `--repo` to write a repo-local override to `\u003crepo-root\u003e/.cwconfig.json`. |\n| `gw config edit` | Interactive TUI: scroll keys, `Tab` to swap between global and repo, `Enter` to edit, empty input to unset, `s` to save. |\n\nKeys mirror the JSON paths in dot/kebab form: `ai-tool.command`, `ai-tool.args`, `ai-tool.guard`, `launch.method`, `launch.tmux-session-prefix`, `launch.wezterm-ready-timeout`, `update.auto-check`, `hooks.post-new`, `hooks.pre-rm`. Tab completion enumerates them.\n\nExample `.cwconfig.json`:\n\n```json\n{\n  \"default_base\": \"main\",\n  \"ai_tool\": { \"command\": \"claude\", \"guard\": true },\n  \"launch\": { \"method\": \"tmux\" },\n  \"hooks\": {\n    \"post_new\": \"npm install\",\n    \"pre_rm\": \"cargo test --quiet\"\n  }\n}\n```\n\n`ai_tool.guard` (default `true`) injects a PreToolUse(Bash) hook into Claude sessions that gw launches, so any Bash tool call from a stale worktree (cwd no longer exists) is blocked with an instruction to stop and ask the user. The injection only affects sessions started by `gw new` / `gw spawn` / `gw resume`; user/project `~/.claude/settings.json` hooks are preserved and run alongside. Set `false` to disable.\n\n## Hooks\n\nTwo lifecycle hooks are available, configured in `.cwconfig.json` (or the global config):\n\n| Hook | Trigger |\n|------|---------|\n| `hooks.post_new` | After `gw new` creates a worktree |\n| `hooks.pre_rm` | Before `gw rm` removes a worktree |\n\nHooks run as `sh -c \u003ccmd\u003e` with the worktree directory as the working directory.\n\n- `pre_rm` non-zero exit aborts the remove (the worktree stays). This is independent of `--force` — `--force` bypasses busy detection, not user hooks.\n- `post_new` non-zero exit surfaces as a non-zero `gw new` exit code, but the worktree itself remains on disk because the hook runs after `git worktree add`. The AI tool launch is skipped.\n\nThere are no `gw hook` CRUD subcommands — set hooks in the config file directly.\n\n## Doctor\n\n`gw doctor` runs 5 lean health checks: git version, worktree accessibility, uncommitted changes, busy worktrees, and Claude Code integration. Pass `--session-start` for hook-friendly non-interactive mode (single-line summary, always exits 0).\n\n## `gw rm` Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| `0` | Full success, `--dry-run`, or `-i` with nothing selected / cancelled at selection UI |\n| `1` | User cancelled at the confirmation prompt |\n| `2` | Any target failed or was skipped (not found, busy, or remove error) |\n\nScripts should handle `!= 0` or specifically check for `2`.\n\n## License\n\nBSD-3-Clause\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavedev42%2Fgit-worktree-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavedev42%2Fgit-worktree-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavedev42%2Fgit-worktree-manager/lists"}