From 36f2e10fbfcb7980f3257e0b2d8d573b70c0d7a4 Mon Sep 17 00:00:00 2001 From: Hans Elizaga Date: Mon, 17 Nov 2025 13:59:41 -0800 Subject: [PATCH 1/7] Update documentation and rename commands to `git gtr` for clarity - Updated CLAUDE.md, CONTRIBUTING.md, and README.md to reflect the renaming of the command from `gtr` to `git gtr` to avoid conflicts with GNU coreutils. - Adjusted examples and command usage throughout the documentation to ensure consistency. - Enhanced shell completion scripts for Bash, Zsh, and Fish to support the new command structure. - Updated setup scripts and instructions to guide users on the new command format. --- .../instructions/completions.instructions.md | 26 +- CLAUDE.md | 20 +- CONTRIBUTING.md | 6 +- README.md | 264 +++++++++--------- bin/git-gtr | 15 +- bin/gtr | 76 ++--- completions/_gtr | 12 +- completions/gtr.bash | 23 +- completions/gtr.fish | 80 ++++-- templates/setup-example.sh | 8 +- 10 files changed, 285 insertions(+), 245 deletions(-) diff --git a/.github/instructions/completions.instructions.md b/.github/instructions/completions.instructions.md index f682181..a15ee7e 100644 --- a/.github/instructions/completions.instructions.md +++ b/.github/instructions/completions.instructions.md @@ -6,13 +6,13 @@ applyTo: completions/gtr.bash, completions/_gtr, completions/gtr.fish ## Overview -Shell completions provide tab-completion for `gtr` commands, flags, branches, and adapter names across Bash, Zsh, and Fish shells. +Shell completions provide tab-completion for `git gtr` commands, flags, branches, and adapter names across Bash, Zsh, and Fish shells. ## When to Update Completions **Always update all three completion files** when: -- Adding new commands (e.g., `gtr new-command`) +- Adding new commands (e.g., `git gtr new-command`) - Adding new flags to existing commands (e.g., `--new-flag`) - Adding editor or AI adapters (completion must list available adapters) - Changing command names or flag names @@ -29,7 +29,7 @@ Each completion file implements: 1. **Command completion** - Top-level commands (`new`, `rm`, `open`, `ai`, `list`, etc.) 2. **Flag completion** - Command-specific flags (e.g., `--from`, `--force`, `--editor`) -3. **Branch completion** - Dynamic completion of existing worktree branches (via `gtr list --porcelain`) +3. **Branch completion** - Dynamic completion of existing worktree branches (via `git gtr list --porcelain`) 4. **Adapter completion** - Editor names (`cursor`, `vscode`, `zed`) and AI tool names (`aider`, `claude`, `codex`) ## Testing Completions @@ -39,26 +39,26 @@ Each completion file implements: ```bash # Bash - source the completion file source completions/gtr.bash -gtr # Should show commands -gtr new # Should show flags -gtr open # Should show branches -gtr open --editor # Should show editor names +git gtr # Should show commands +git gtr new # Should show flags +git gtr open # Should show branches +git gtr open --editor # Should show editor names # Zsh - fpath must include completions directory fpath=(completions $fpath) autoload -U compinit && compinit -gtr +git gtr # Fish - symlink to ~/.config/fish/completions/ ln -s "$(pwd)/completions/gtr.fish" ~/.config/fish/completions/ -gtr +git gtr ``` ## Branch Completion Logic All three completions dynamically fetch current worktree branches: -- Parse output of `gtr list --porcelain` (tab-separated: `path\tbranch\tstatus`) +- Parse output of `git gtr list --porcelain` (tab-separated: `path\tbranch\tstatus`) - Extract branch column (second field) - Exclude the special ID `1` (main repo) if needed @@ -79,7 +79,7 @@ When adding an editor or AI adapter: **Fish** (`completions/gtr.fish`): - Update `complete -c gtr` lines for editor/AI flags -- List adapter names explicitly or parse from `gtr adapter` output +- List adapter names explicitly or parse from `git gtr adapter` output ## Keep in Sync @@ -92,7 +92,7 @@ The three completion files must stay synchronized: ## Examples -**Adding a new command `gtr status`**: +**Adding a new command `git gtr status`**: 1. Add `status` to main command list in all three files 2. Add flag completion if the command has flags @@ -104,7 +104,7 @@ The three completion files must stay synchronized: 2. Add `sublime` to editor list in all three completion files 3. Update help text in `bin/gtr` (`cmd_help` function) 4. Update README with installation instructions -5. Test `gtr open --editor s` completes to `sublime` +5. Test `git gtr open --editor s` completes to `sublime` ## Common Pitfalls diff --git a/CLAUDE.md b/CLAUDE.md index e34564b..7ae1130 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -`gtr` (Git Worktree Runner) is a cross-platform CLI tool written in Bash that simplifies git worktree management. It wraps `git worktree` with quality-of-life features like editor integration, AI tool support, file copying, and hooks. +`git gtr` (Git Worktree Runner) is a cross-platform CLI tool written in Bash that simplifies git worktree management. It wraps `git worktree` with quality-of-life features like editor integration, AI tool support, file copying, and hooks. It is installed as a git subcommand, so all commands are invoked as `git gtr `. ## Development Commands @@ -90,11 +90,11 @@ Test changes using this comprehensive checklist (from CONTRIBUTING.md): ./bin/gtr config unset gtr.editor.default # Test shell completions with tab completion -gtr new -gtr editor +git gtr new +git gtr editor # Expected: Shows available branches/worktrees -# Test gtr go for main repo and worktrees +# Test git gtr go for main repo and worktrees cd "$(./bin/gtr go 1)" # Expected: Navigates to repo root cd "$(./bin/gtr go test-feature)" @@ -142,7 +142,7 @@ echo "Debug: var=$var" >&2 # Verify git is available git --version -# Check gtr setup +# Check git gtr setup ./bin/gtr doctor # List available adapters @@ -171,7 +171,7 @@ git --version **Branch Name Mapping**: Branch names are sanitized to valid folder names (slashes and special chars → hyphens). For example, `feature/user-auth` becomes folder `feature-user-auth`. -**Special ID '1'**: The main repository is always accessible via ID `1` in commands (e.g., `gtr go 1`, `gtr editor 1`). +**Special ID '1'**: The main repository is always accessible via ID `1` in commands (e.g., `git gtr go 1`, `git gtr editor 1`). **Configuration Storage**: All configuration is stored via `git config` (local, global, or system). No custom config files. This makes settings portable and follows git conventions. @@ -191,7 +191,7 @@ Understanding how commands are dispatched through the system: 3. **Library Functions** (`lib/*.sh`): Command handlers call reusable functions from library modules 4. **Adapters** (`adapters/*`): Dynamically loaded when needed via `load_editor_adapter` or `load_ai_adapter` -**Example flow for `gtr new my-feature`:** +**Example flow for `git gtr new my-feature`:** ``` bin/gtr main() @@ -202,7 +202,7 @@ bin/gtr main() → run_hooks_in() [lib/hooks.sh] ``` -**Example flow for `gtr editor my-feature`:** +**Example flow for `git gtr editor my-feature`:** ``` bin/gtr main() @@ -234,7 +234,7 @@ When releasing a new version, update the version constant in `bin/gtr`: GTR_VERSION="1.0.0" # Update this ``` -The version is displayed with `gtr version` and `gtr --version`. +The version is displayed with `git gtr version` and `git gtr --version`. ### Adding a New Editor Adapter @@ -426,6 +426,6 @@ cd ~/gtr-test-repo git init git commit --allow-empty -m "Initial commit" -# Now test gtr commands +# Now test git gtr commands /path/to/git-worktree-runner/bin/gtr new test-feature ``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f896a66..1594849 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to gtr -Thank you for considering contributing to `gtr`! This document provides guidelines and instructions for contributing. +Thank you for considering contributing to `git gtr`! This document provides guidelines and instructions for contributing. ## How to Contribute @@ -178,8 +178,8 @@ Currently, testing is manual. Please test your changes on: - [ ] List worktrees - [ ] Test configuration commands - [ ] Test completions (tab completion works) -- [ ] Test `gtr go 1` for main repo -- [ ] Test `gtr go ` for worktrees +- [ ] Test `git gtr go 1` for main repo +- [ ] Test `git gtr go ` for worktrees ### Pull Request Process diff --git a/README.md b/README.md index 5a99a69..ae7c3c8 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ > A portable, cross-platform CLI for managing git worktrees with ease +> **⚠️ v2.0 Breaking Change:** As of v2.0.0, the command has been renamed from `gtr` to `git gtr` to avoid conflicts with GNU coreutils. Simply use `git gtr` instead of `gtr` for all commands. [See release notes for details](https://github.com/coderabbitai/git-worktree-runner/releases/tag/v2.0.0). + ![4 AI agents working in parallel across different worktrees](docs/assets/demo-parallel.png) ## What are git worktrees? @@ -26,38 +28,38 @@ ```bash git clone https://github.com/coderabbitai/git-worktree-runner.git cd git-worktree-runner -sudo ln -s "$(pwd)/bin/gtr" /usr/local/bin/gtr +sudo ln -s "$(pwd)/bin/git-gtr" /usr/local/bin/git-gtr ``` **Use it (3 commands):** ```bash cd ~/your-repo # Navigate to git repo -gtr config set gtr.editor.default cursor # One-time setup -gtr config set gtr.ai.default claude # One-time setup +git gtr config set gtr.editor.default cursor # One-time setup +git gtr config set gtr.ai.default claude # One-time setup # Daily workflow -gtr new my-feature # Create worktree -gtr editor my-feature # Open in editor -gtr ai my-feature # Start AI tool -gtr rm my-feature # Remove when done +git gtr new my-feature # Create worktree +git gtr editor my-feature # Open in editor +git gtr ai my-feature # Start AI tool +git gtr rm my-feature # Remove when done ``` ## Why gtr? -While `git worktree` is powerful, it's verbose and manual. `gtr` adds quality-of-life features for modern development: +While `git worktree` is powerful, it's verbose and manual. `git gtr` adds quality-of-life features for modern development: -| Task | With `git worktree` | With `gtr` | +| Task | With `git worktree` | With `git gtr` | | ----------------- | ------------------------------------------ | ------------------------------------ | -| Create worktree | `git worktree add ../repo-feature feature` | `gtr new feature` | -| Open in editor | `cd ../repo-feature && cursor .` | `gtr editor feature` | -| Start AI tool | `cd ../repo-feature && aider` | `gtr ai feature` | +| Create worktree | `git worktree add ../repo-feature feature` | `git gtr new feature` | +| Open in editor | `cd ../repo-feature && cursor .` | `git gtr editor feature` | +| Start AI tool | `cd ../repo-feature && aider` | `git gtr ai feature` | | Copy config files | Manual copy/paste | Auto-copy via `gtr.copy.include` | | Run build steps | Manual `npm install && npm run build` | Auto-run via `gtr.hook.postCreate` | -| List worktrees | `git worktree list` (shows paths) | `gtr list` (shows branches + status) | -| Clean up | `git worktree remove ../repo-feature` | `gtr rm feature` | +| List worktrees | `git worktree list` (shows paths) | `git gtr list` (shows branches + status) | +| Clean up | `git worktree remove ../repo-feature` | `git gtr rm feature` | -**TL;DR:** `gtr` wraps `git worktree` with quality-of-life features for modern development workflows (AI tools, editors, automation). +**TL;DR:** `git gtr` wraps `git worktree` with quality-of-life features for modern development workflows (AI tools, editors, automation). ## Features @@ -78,22 +80,22 @@ While `git worktree` is powerful, it's verbose and manual. `gtr` adds quality-of cd ~/GitHub/my-project # One-time setup (per repository) -gtr config set gtr.editor.default cursor -gtr config set gtr.ai.default claude +git gtr config set gtr.editor.default cursor +git gtr config set gtr.ai.default claude # Daily workflow -gtr new my-feature # Create worktree folder: my-feature -gtr editor my-feature # Open in cursor -gtr ai my-feature # Start claude +git gtr new my-feature # Create worktree folder: my-feature +git gtr editor my-feature # Open in cursor +git gtr ai my-feature # Start claude # Navigate to worktree -cd "$(gtr go my-feature)" +cd "$(git gtr go my-feature)" # List all worktrees -gtr list +git gtr list # Remove when done -gtr rm my-feature +git gtr rm my-feature ``` ## Requirements @@ -151,18 +153,18 @@ ln -s /path/to/git-worktree-runner/completions/gtr.fish ~/.config/fish/completio ## Commands Commands accept branch names to identify worktrees. Use `1` to reference the main repo. -Run `gtr help` for full documentation. +Run `git gtr help` for full documentation. -### `gtr new [options]` +### `git gtr new [options]` Create a new git worktree. Folder is named after the branch. ```bash -gtr new my-feature # Creates folder: my-feature -gtr new hotfix --from v1.2.3 # Create from specific ref -gtr new feature/auth # Creates folder: feature-auth -gtr new feature-auth --name backend --force # Same branch, custom name -gtr new my-feature --name descriptive-variant # Optional: custom name without --force +git gtr new my-feature # Creates folder: my-feature +git gtr new hotfix --from v1.2.3 # Create from specific ref +git gtr new feature/auth # Creates folder: feature-auth +git gtr new feature-auth --name backend --force # Same branch, custom name +git gtr new my-feature --name descriptive-variant # Optional: custom name without --force ``` **Options:** @@ -175,67 +177,67 @@ gtr new my-feature --name descriptive-variant # Optional: custom name without - `--name `: Custom folder name suffix (optional, required with --force) - `--yes`: Non-interactive mode -### `gtr editor [--editor ]` +### `git gtr editor [--editor ]` Open worktree in editor (uses `gtr.editor.default` or `--editor` flag). ```bash -gtr editor my-feature # Uses configured editor -gtr editor my-feature --editor vscode # Override with vscode +git gtr editor my-feature # Uses configured editor +git gtr editor my-feature --editor vscode # Override with vscode ``` -### `gtr ai [--ai ] [-- args...]` +### `git gtr ai [--ai ] [-- args...]` Start AI coding tool (uses `gtr.ai.default` or `--ai` flag). ```bash -gtr ai my-feature # Uses configured AI tool -gtr ai my-feature --ai aider # Override with aider -gtr ai my-feature -- --model gpt-4 # Pass arguments to tool -gtr ai 1 # Use AI in main repo +git gtr ai my-feature # Uses configured AI tool +git gtr ai my-feature --ai aider # Override with aider +git gtr ai my-feature -- --model gpt-4 # Pass arguments to tool +git gtr ai 1 # Use AI in main repo ``` -### `gtr go ` +### `git gtr go ` Print worktree path for shell navigation. ```bash -cd "$(gtr go my-feature)" # Navigate by branch name -cd "$(gtr go 1)" # Navigate to main repo +cd "$(git gtr go my-feature)" # Navigate by branch name +cd "$(git gtr go 1)" # Navigate to main repo ``` -### `gtr rm ... [options]` +### `git gtr rm ... [options]` Remove worktree(s) by branch name. ```bash -gtr rm my-feature # Remove one -gtr rm feature-a feature-b # Remove multiple -gtr rm my-feature --delete-branch --force # Delete branch and force +git gtr rm my-feature # Remove one +git gtr rm feature-a feature-b # Remove multiple +git gtr rm my-feature --delete-branch --force # Delete branch and force ``` **Options:** `--delete-branch`, `--force`, `--yes` -### `gtr list [--porcelain]` +### `git gtr list [--porcelain]` List all worktrees. Use `--porcelain` for machine-readable output. -### `gtr config {get|set|add|unset} [value] [--global]` +### `git gtr config {get|set|add|unset} [value] [--global]` Manage configuration via git config. ```bash -gtr config set gtr.editor.default cursor # Set locally -gtr config set gtr.ai.default claude --global # Set globally -gtr config get gtr.editor.default # Get value +git gtr config set gtr.editor.default cursor # Set locally +git gtr config set gtr.ai.default claude --global # Set globally +git gtr config get gtr.editor.default # Get value ``` ### Other Commands -- `gtr doctor` - Health check (verify git, editors, AI tools) -- `gtr adapter` - List available editor & AI adapters -- `gtr clean` - Remove stale worktrees -- `gtr version` - Show version +- `git gtr doctor` - Health check (verify git, editors, AI tools) +- `git gtr adapter` - List available editor & AI adapters +- `git gtr clean` - Remove stale worktrees +- `git gtr version` - Show version ## Configuration @@ -297,26 +299,26 @@ gtr.ai.default = none | Tool | Install | Use Case | Set as Default | | ------------------------------------------------- | ------------------------------------------------- | ------------------------------------ | ---------------------------------------- | -| **[Aider](https://aider.chat)** | `pip install aider-chat` | Pair programming, edit files with AI | `gtr config set gtr.ai.default aider` | -| **[Claude Code](https://claude.com/claude-code)** | Install from claude.com | Terminal-native coding agent | `gtr config set gtr.ai.default claude` | -| **[Codex CLI](https://github.com/openai/codex)** | `npm install -g @openai/codex` | OpenAI coding assistant | `gtr config set gtr.ai.default codex` | -| **[Cursor](https://cursor.com)** | Install from cursor.com | AI-powered editor with CLI agent | `gtr config set gtr.ai.default cursor` | -| **[Continue](https://continue.dev)** | See [docs](https://docs.continue.dev/cli/install) | Open-source coding agent | `gtr config set gtr.ai.default continue` | +| **[Aider](https://aider.chat)** | `pip install aider-chat` | Pair programming, edit files with AI | `git gtr config set gtr.ai.default aider` | +| **[Claude Code](https://claude.com/claude-code)** | Install from claude.com | Terminal-native coding agent | `git gtr config set gtr.ai.default claude` | +| **[Codex CLI](https://github.com/openai/codex)** | `npm install -g @openai/codex` | OpenAI coding assistant | `git gtr config set gtr.ai.default codex` | +| **[Cursor](https://cursor.com)** | Install from cursor.com | AI-powered editor with CLI agent | `git gtr config set gtr.ai.default cursor` | +| **[Continue](https://continue.dev)** | See [docs](https://docs.continue.dev/cli/install) | Open-source coding agent | `git gtr config set gtr.ai.default continue` | **Examples:** ```bash # Set default AI tool for this repo -gtr config set gtr.ai.default claude +git gtr config set gtr.ai.default claude # Or set globally for all repos -gtr config set gtr.ai.default claude --global +git gtr config set gtr.ai.default claude --global -# Then just use gtr ai -gtr ai my-feature +# Then just use git gtr ai +git gtr ai my-feature # Pass arguments to the tool -gtr ai my-feature -- --plan "refactor auth" +git gtr ai my-feature -- --plan "refactor auth" ``` ### File Copying @@ -325,13 +327,13 @@ Copy files to new worktrees using glob patterns: ```bash # Add patterns to copy (multi-valued) -gtr config add gtr.copy.include "**/.env.example" -gtr config add gtr.copy.include "**/CLAUDE.md" -gtr config add gtr.copy.include "*.config.js" +git gtr config add gtr.copy.include "**/.env.example" +git gtr config add gtr.copy.include "**/CLAUDE.md" +git gtr config add gtr.copy.include "*.config.js" # Exclude patterns (multi-valued) -gtr config add gtr.copy.exclude "**/.env" -gtr config add gtr.copy.exclude "**/secrets.*" +git gtr config add gtr.copy.exclude "**/.env" +git gtr config add gtr.copy.exclude "**/secrets.*" ``` #### Security Best Practices @@ -340,9 +342,9 @@ gtr config add gtr.copy.exclude "**/secrets.*" ```bash # Personal dev: copy what you need to run dev servers -gtr config add gtr.copy.include "**/.env.development" -gtr config add gtr.copy.include "**/.env.local" -gtr config add gtr.copy.exclude "**/.env.production" # Never copy production +git gtr config add gtr.copy.include "**/.env.development" +git gtr config add gtr.copy.include "**/.env.local" +git gtr config add gtr.copy.exclude "**/.env.production" # Never copy production ``` > [!TIP] @@ -354,11 +356,11 @@ Run custom commands after worktree operations: ```bash # Post-create hooks (multi-valued, run in order) -gtr config add gtr.hook.postCreate "npm install" -gtr config add gtr.hook.postCreate "npm run build" +git gtr config add gtr.hook.postCreate "npm install" +git gtr config add gtr.hook.postCreate "npm run build" # Post-remove hooks -gtr config add gtr.hook.postRemove "echo 'Cleaned up!'" +git gtr config add gtr.hook.postRemove "echo 'Cleaned up!'" ``` **Environment variables available in hooks:** @@ -371,19 +373,19 @@ gtr config add gtr.hook.postRemove "echo 'Cleaned up!'" ```bash # Node.js (npm) -gtr config add gtr.hook.postCreate "npm install" +git gtr config add gtr.hook.postCreate "npm install" # Node.js (pnpm) -gtr config add gtr.hook.postCreate "pnpm install" +git gtr config add gtr.hook.postCreate "pnpm install" # Python -gtr config add gtr.hook.postCreate "pip install -r requirements.txt" +git gtr config add gtr.hook.postCreate "pip install -r requirements.txt" # Ruby -gtr config add gtr.hook.postCreate "bundle install" +git gtr config add gtr.hook.postCreate "bundle install" # Rust -gtr config add gtr.hook.postCreate "cargo build" +git gtr config add gtr.hook.postCreate "cargo build" ``` ## Configuration Examples @@ -391,35 +393,35 @@ gtr config add gtr.hook.postCreate "cargo build" ### Minimal Setup (Just Basics) ```bash -gtr config set gtr.worktrees.prefix "wt-" -gtr config set gtr.defaultBranch "main" +git gtr config set gtr.worktrees.prefix "wt-" +git gtr config set gtr.defaultBranch "main" ``` ### Full-Featured Setup (Node.js Project) ```bash # Worktree settings -gtr config set gtr.worktrees.prefix "wt-" +git gtr config set gtr.worktrees.prefix "wt-" # Editor -gtr config set gtr.editor.default cursor +git gtr config set gtr.editor.default cursor # Copy environment templates -gtr config add gtr.copy.include "**/.env.example" -gtr config add gtr.copy.include "**/.env.development" -gtr config add gtr.copy.exclude "**/.env.local" +git gtr config add gtr.copy.include "**/.env.example" +git gtr config add gtr.copy.include "**/.env.development" +git gtr config add gtr.copy.exclude "**/.env.local" # Build hooks -gtr config add gtr.hook.postCreate "pnpm install" -gtr config add gtr.hook.postCreate "pnpm run build" +git gtr config add gtr.hook.postCreate "pnpm install" +git gtr config add gtr.hook.postCreate "pnpm run build" ``` ### Global Defaults ```bash # Set global preferences -gtr config set gtr.editor.default cursor --global -gtr config set gtr.ai.default claude --global +git gtr config set gtr.editor.default cursor --global +git gtr config set gtr.ai.default claude --global ``` ## Advanced Usage @@ -428,24 +430,24 @@ gtr config set gtr.ai.default claude --global **gtr is repository-scoped** - each git repository has its own independent set of worktrees: -- Run `gtr` commands from within any git repository +- Run `git gtr` commands from within any git repository - Worktree folders are named after their branch names - Each repo manages its own worktrees independently -- Switch repos with `cd`, then run `gtr` commands for that repo +- Switch repos with `cd`, then run `git gtr` commands for that repo ### Working with Multiple Branches ```bash # Terminal 1: Work on feature -gtr new feature-a -gtr editor feature-a +git gtr new feature-a +git gtr editor feature-a # Terminal 2: Review PR -gtr new pr/123 -gtr editor pr/123 +git gtr new pr/123 +git gtr editor pr/123 # Terminal 3: Navigate to main branch (repo root) -cd "$(gtr go 1)" # Special ID '1' = main repo +cd "$(git gtr go 1)" # Special ID '1' = main repo ``` ### Working with Multiple Repositories @@ -455,29 +457,29 @@ Each repository has its own independent set of worktrees. Switch repos with `cd` ```bash # Frontend repo cd ~/GitHub/frontend -gtr list +git gtr list # BRANCH PATH # main [main] ~/GitHub/frontend # auth-feature ~/GitHub/frontend-worktrees/auth-feature # nav-redesign ~/GitHub/frontend-worktrees/nav-redesign -gtr editor auth-feature # Open frontend auth work -gtr ai nav-redesign # AI on frontend nav work +git gtr editor auth-feature # Open frontend auth work +git gtr ai nav-redesign # AI on frontend nav work # Backend repo (separate worktrees) cd ~/GitHub/backend -gtr list +git gtr list # BRANCH PATH # main [main] ~/GitHub/backend # api-auth ~/GitHub/backend-worktrees/api-auth # websockets ~/GitHub/backend-worktrees/websockets -gtr editor api-auth # Open backend auth work -gtr ai websockets # AI on backend websockets +git gtr editor api-auth # Open backend auth work +git gtr ai websockets # AI on backend websockets # Switch back to frontend cd ~/GitHub/frontend -gtr editor auth-feature # Opens frontend auth +git gtr editor auth-feature # Opens frontend auth ``` **Key point:** Each repository has its own worktrees. Use branch names to identify worktrees. @@ -488,19 +490,19 @@ Create a `.gtr-setup.sh` in your repo: ```bash #!/bin/sh -# .gtr-setup.sh - Project-specific gtr configuration +# .gtr-setup.sh - Project-specific git gtr configuration -gtr config set gtr.worktrees.prefix "dev-" -gtr config set gtr.editor.default cursor +git gtr config set gtr.worktrees.prefix "dev-" +git gtr config set gtr.editor.default cursor # Copy configs -gtr config add gtr.copy.include ".env.example" -gtr config add gtr.copy.include "docker-compose.yml" +git gtr config add gtr.copy.include ".env.example" +git gtr config add gtr.copy.include "docker-compose.yml" # Setup hooks -gtr config add gtr.hook.postCreate "docker-compose up -d db" -gtr config add gtr.hook.postCreate "npm install" -gtr config add gtr.hook.postCreate "npm run db:migrate" +git gtr config add gtr.hook.postCreate "docker-compose up -d db" +git gtr config add gtr.hook.postCreate "npm install" +git gtr config add gtr.hook.postCreate "npm run db:migrate" ``` Then run: `sh .gtr-setup.sh` @@ -511,16 +513,16 @@ Perfect for CI/CD or scripts: ```bash # Create worktree without prompts -gtr new ci-test --yes --no-copy +git gtr new ci-test --yes --no-copy # Remove without confirmation -gtr rm ci-test --yes --delete-branch +git gtr rm ci-test --yes --delete-branch ``` ### Multiple Worktrees on Same Branch > [!TIP] -> Git normally prevents checking out the same branch in multiple worktrees to avoid conflicts. `gtr` supports bypassing this safety check with `--force` and `--name` flags. +> Git normally prevents checking out the same branch in multiple worktrees to avoid conflicts. `git gtr` supports bypassing this safety check with `--force` and `--name` flags. **Use cases:** @@ -539,10 +541,10 @@ gtr rm ci-test --yes --delete-branch ```bash # Create multiple worktrees for same branch with descriptive names -gtr new feature-auth # Main worktree: feature-auth/ -gtr new feature-auth --force --name backend # Creates: feature-auth-backend/ -gtr new feature-auth --force --name frontend # Creates: feature-auth-frontend/ -gtr new feature-auth --force --name tests # Creates: feature-auth-tests/ +git gtr new feature-auth # Main worktree: feature-auth/ +git gtr new feature-auth --force --name backend # Creates: feature-auth-backend/ +git gtr new feature-auth --force --name frontend # Creates: feature-auth-frontend/ +git gtr new feature-auth --force --name tests # Creates: feature-auth-tests/ # All worktrees are on the same 'feature-auth' branch # The --name flag is required with --force to distinguish worktrees @@ -552,16 +554,16 @@ gtr new feature-auth --force --name tests # Creates: feature-auth-tests/ ```bash # Terminal 1: Backend work -gtr new feature-auth --force --name backend -gtr ai feature-auth-backend -- --message "Implement API endpoints" +git gtr new feature-auth --force --name backend +git gtr ai feature-auth-backend -- --message "Implement API endpoints" # Terminal 2: Frontend work -gtr new feature-auth --force --name frontend -gtr ai feature-auth-frontend -- --message "Build UI components" +git gtr new feature-auth --force --name frontend +git gtr ai feature-auth-frontend -- --message "Build UI components" # Terminal 3: Tests -gtr new feature-auth --force --name tests -gtr ai feature-auth-tests -- --message "Write integration tests" +git gtr new feature-auth --force --name tests +git gtr ai feature-auth-tests -- --message "Write integration tests" # All agents commit to the same feature-auth branch ``` @@ -572,7 +574,7 @@ gtr ai feature-auth-tests -- --message "Write integration tests" - Only edit files in one worktree at a time - Commit/stash changes before switching worktrees - Ideal for parallel AI agents working on different parts of one feature -- Use `gtr list` to see all worktrees and their branches +- Use `git gtr list` to see all worktrees and their branches ## Troubleshooting @@ -586,7 +588,7 @@ git fetch origin git branch -a | grep your-branch # Manually specify tracking mode -gtr new test --track remote +git gtr new test --track remote ``` ### Editor Not Opening @@ -596,17 +598,17 @@ gtr new test --track remote command -v cursor # or: code, zed # Check configuration -gtr config get gtr.editor.default +git gtr config get gtr.editor.default # Try opening again -gtr editor 2 +git gtr editor 2 ``` ### File Copying Issues ```bash # Check your patterns -gtr config get gtr.copy.include +git gtr config get gtr.copy.include # Test patterns with find cd /path/to/repo diff --git a/bin/git-gtr b/bin/git-gtr index 73c25d7..4d7bf28 100755 --- a/bin/git-gtr +++ b/bin/git-gtr @@ -1,2 +1,15 @@ #!/usr/bin/env bash -exec gtr "$@" +# git-gtr - Git worktree runner (git subcommand wrapper) +# Allows running as: git gtr + +# Find this script's real location (resolve symlinks) +SRC="${BASH_SOURCE[0]}" +while [ -h "$SRC" ]; do + DIR="$(cd -P "$(dirname "$SRC")" && pwd)" + SRC="$(readlink "$SRC")" + [[ $SRC != /* ]] && SRC="$DIR/$SRC" +done +SCRIPT_DIR="$(cd -P "$(dirname "$SRC")" && pwd)" + +# Execute the main gtr script +exec "$SCRIPT_DIR/gtr" "$@" diff --git a/bin/gtr b/bin/gtr index 57a9ede..1113d01 100755 --- a/bin/gtr +++ b/bin/gtr @@ -5,7 +5,7 @@ set -e # Version -GTR_VERSION="1.0.0" +GTR_VERSION="2.0.0" # Find the script directory (resolve symlinks; allow env override) resolve_script_dir() { @@ -91,14 +91,14 @@ main() { cmd_config "$@" ;; version|--version|-v) - echo "gtr version $GTR_VERSION" + echo "git gtr version $GTR_VERSION" ;; help|--help|-h) cmd_help ;; *) log_error "Unknown command: $cmd" - echo "Use 'gtr help' for available commands" + echo "Use 'git gtr help' for available commands" exit 1 ;; esac @@ -164,9 +164,9 @@ cmd_create() { if [ "$force" -eq 1 ] && [ -z "$custom_name" ]; then log_error "--force requires --name to distinguish worktrees" if [ -n "$branch_name" ]; then - echo "Example: gtr new $branch_name --force --name backend" >&2 + echo "Example: git gtr new $branch_name --force --name backend" >&2 else - echo "Example: gtr new feature-auth --force --name backend" >&2 + echo "Example: git gtr new feature-auth --force --name backend" >&2 fi exit 1 fi @@ -275,7 +275,7 @@ cmd_remove() { done if [ -z "$identifiers" ]; then - log_error "Usage: gtr rm [...] [--delete-branch] [--force] [--yes]" + log_error "Usage: git gtr rm [...] [--delete-branch] [--force] [--yes]" exit 1 fi @@ -329,7 +329,7 @@ cmd_remove() { # Go command (navigate to worktree - prints path for shell integration) cmd_go() { if [ $# -ne 1 ]; then - log_error "Usage: gtr go " + log_error "Usage: git gtr go " exit 1 fi @@ -384,7 +384,7 @@ cmd_editor() { done if [ -z "$identifier" ]; then - log_error "Usage: gtr editor [--editor ]" + log_error "Usage: git gtr editor [--editor ]" exit 1 fi @@ -448,7 +448,7 @@ cmd_ai() { done if [ -z "$identifier" ]; then - log_error "Usage: gtr ai [--ai ] [-- args...]" + log_error "Usage: git gtr ai [--ai ] [-- args...]" exit 1 fi @@ -557,7 +557,7 @@ cmd_list() { echo "" echo "" - echo "Tip: Use 'gtr list --porcelain' for machine-readable output" + echo "Tip: Use 'git gtr list --porcelain' for machine-readable output" } # Clean command (remove prunable worktrees) @@ -788,14 +788,14 @@ cmd_config() { case "$action" in get) if [ -z "$key" ]; then - log_error "Usage: gtr config get [--global]" + log_error "Usage: git gtr config get [--global]" exit 1 fi cfg_get "$key" "$scope" ;; set) if [ -z "$key" ] || [ -z "$value" ]; then - log_error "Usage: gtr config set [--global]" + log_error "Usage: git gtr config set [--global]" exit 1 fi cfg_set "$key" "$value" "$scope" @@ -803,7 +803,7 @@ cmd_config() { ;; add) if [ -z "$key" ] || [ -z "$value" ]; then - log_error "Usage: gtr config add [--global]" + log_error "Usage: git gtr config add [--global]" exit 1 fi cfg_add "$key" "$value" "$scope" @@ -811,7 +811,7 @@ cmd_config() { ;; unset) if [ -z "$key" ]; then - log_error "Usage: gtr config unset [--global]" + log_error "Usage: git gtr config unset [--global]" exit 1 fi cfg_unset "$key" "$scope" @@ -819,7 +819,7 @@ cmd_config() { ;; *) log_error "Unknown config action: $action" - log_error "Usage: gtr config {get|set|add|unset} [value] [--global]" + log_error "Usage: git gtr config {get|set|add|unset} [value] [--global]" exit 1 ;; esac @@ -884,28 +884,28 @@ load_ai_adapter() { # Help command cmd_help() { cat <<'EOF' -gtr - Git worktree runner +git gtr - Git worktree runner PHILOSOPHY: Configuration over flags. Set defaults once, then use simple commands. ──────────────────────────────────────────────────────────────────────────────── QUICK START: - cd ~/your-repo # Navigate to git repo first - gtr config set gtr.editor.default cursor # One-time setup - gtr config set gtr.ai.default claude # One-time setup - gtr new my-feature # Creates worktree in folder "my-feature" - gtr editor my-feature # Opens in cursor - gtr ai my-feature # Starts claude - gtr rm my-feature # Remove when done + cd ~/your-repo # Navigate to git repo first + git gtr config set gtr.editor.default cursor # One-time setup + git gtr config set gtr.ai.default claude # One-time setup + git gtr new my-feature # Creates worktree in folder "my-feature" + git gtr editor my-feature # Opens in cursor + git gtr ai my-feature # Starts claude + git gtr rm my-feature # Remove when done ──────────────────────────────────────────────────────────────────────────────── KEY CONCEPTS: • Worktree folders are named after the branch name - • Main repo is accessible via special ID '1' (e.g., gtr go 1, gtr editor 1) + • Main repo is accessible via special ID '1' (e.g., git gtr go 1, git gtr editor 1) • Commands accept branch names to identify worktrees - Example: gtr editor my-feature, gtr go feature/user-auth + Example: git gtr editor my-feature, git gtr go feature/user-auth ──────────────────────────────────────────────────────────────────────────────── @@ -930,7 +930,7 @@ CORE COMMANDS (daily workflow): Special: use '1' to open repo root go - Navigate to worktree (prints path for: cd "$(gtr go my-feature)") + Navigate to worktree (prints path for: cd "$(git gtr go my-feature)") Special: use '1' for repo root list [--porcelain] @@ -973,30 +973,30 @@ WORKFLOW EXAMPLES: # One-time repo setup cd ~/GitHub/my-project - gtr config set gtr.editor.default cursor - gtr config set gtr.ai.default claude + git gtr config set gtr.editor.default cursor + git gtr config set gtr.ai.default claude # Daily workflow - gtr new feature/user-auth # Create worktree (folder: feature-user-auth) - gtr editor feature/user-auth # Open in editor - gtr ai feature/user-auth # Start AI tool + git gtr new feature/user-auth # Create worktree (folder: feature-user-auth) + git gtr editor feature/user-auth # Open in editor + git gtr ai feature/user-auth # Start AI tool # Navigate to worktree directory - cd "$(gtr go feature/user-auth)" + cd "$(git gtr go feature/user-auth)" # Override defaults with flags - gtr editor feature/user-auth --editor vscode - gtr ai feature/user-auth --ai aider + git gtr editor feature/user-auth --editor vscode + git gtr ai feature/user-auth --ai aider # Chain commands together - gtr new hotfix && gtr editor hotfix && gtr ai hotfix + git gtr new hotfix && git gtr editor hotfix && git gtr ai hotfix # When finished - gtr rm feature/user-auth --delete-branch + git gtr rm feature/user-auth --delete-branch # Check setup and available tools - gtr doctor - gtr adapter + git gtr doctor + git gtr adapter ──────────────────────────────────────────────────────────────────────────────── diff --git a/completions/_gtr b/completions/_gtr index 29c8f9f..ffd06f5 100644 --- a/completions/_gtr +++ b/completions/_gtr @@ -1,7 +1,7 @@ -#compdef gtr -# Zsh completion for gtr +#compdef git-gtr +# Zsh completion for git gtr -_gtr() { +_git-gtr() { local -a commands commands=( 'new:Create a new worktree' @@ -43,7 +43,7 @@ _gtr() { '--yes[Non-interactive mode]' ;; config) - _values 'config action' get set unset + _values 'config action' get set add unset ;; esac elif (( CURRENT >= 4 )); then @@ -56,7 +56,7 @@ _gtr() { ;; config) case "$words[3]" in - get|set|unset) + get|set|add|unset) _values 'config key' \ 'gtr.worktrees.dir' \ 'gtr.worktrees.prefix' \ @@ -74,4 +74,4 @@ _gtr() { fi } -_gtr "$@" +_git-gtr "$@" diff --git a/completions/gtr.bash b/completions/gtr.bash index 5b844a1..59e235a 100644 --- a/completions/gtr.bash +++ b/completions/gtr.bash @@ -1,22 +1,25 @@ #!/bin/bash -# Bash completion for gtr +# Bash completion for git gtr -_gtr_completion() { +_git_gtr() { local cur prev words cword _init_completion || return - local cmd="${words[1]}" + # words array for git subcommand: [git, gtr, , ...] + # cword is the index of current word being completed - # Complete commands on first argument - if [ "$cword" -eq 1 ]; then + # If we're completing the first argument after 'git gtr' + if [ "$cword" -eq 2 ]; then COMPREPLY=($(compgen -W "new go editor ai rm ls list clean doctor adapter config help version" -- "$cur")) return 0 fi + local cmd="${words[2]}" + # Commands that take branch names or '1' for main repo case "$cmd" in go|editor|ai|rm) - if [ "$cword" -eq 2 ]; then + if [ "$cword" -eq 3 ]; then # Complete with branch names and special ID '1' for main repo local branches all_options branches=$(git branch --format='%(refname:short)' 2>/dev/null || true) @@ -39,13 +42,11 @@ _gtr_completion() { fi ;; config) - if [ "$cword" -eq 2 ]; then - COMPREPLY=($(compgen -W "get set unset" -- "$cur")) - elif [ "$cword" -eq 3 ]; then + if [ "$cword" -eq 3 ]; then + COMPREPLY=($(compgen -W "get set add unset" -- "$cur")) + elif [ "$cword" -eq 4 ]; then COMPREPLY=($(compgen -W "gtr.worktrees.dir gtr.worktrees.prefix gtr.defaultBranch gtr.editor.default gtr.ai.default gtr.copy.include gtr.copy.exclude gtr.hook.postCreate gtr.hook.postRemove" -- "$cur")) fi ;; esac } - -complete -F _gtr_completion gtr diff --git a/completions/gtr.fish b/completions/gtr.fish index a7d1df0..b00750e 100644 --- a/completions/gtr.fish +++ b/completions/gtr.fish @@ -1,37 +1,58 @@ -# Fish completion for gtr +# Fish completion for git gtr + +# Helper function to check if we're in 'git gtr' context +function __fish_git_gtr_needs_command + set -l cmd (commandline -opc) + if [ (count $cmd) -eq 2 -a "$cmd[1]" = "git" -a "$cmd[2]" = "gtr" ] + return 0 + end + return 1 +end + +function __fish_git_gtr_using_command + set -l cmd (commandline -opc) + if [ (count $cmd) -ge 3 -a "$cmd[1]" = "git" -a "$cmd[2]" = "gtr" ] + for i in $argv + if [ "$cmd[3]" = "$i" ] + return 0 + end + end + end + return 1 +end # Commands -complete -c gtr -f -n "__fish_use_subcommand" -a "new" -d "Create a new worktree" -complete -c gtr -f -n "__fish_use_subcommand" -a "go" -d "Navigate to worktree" -complete -c gtr -f -n "__fish_use_subcommand" -a "rm" -d "Remove worktree(s)" -complete -c gtr -f -n "__fish_use_subcommand" -a "editor" -d "Open worktree in editor" -complete -c gtr -f -n "__fish_use_subcommand" -a "ai" -d "Start AI coding tool" -complete -c gtr -f -n "__fish_use_subcommand" -a "ls" -d "List all worktrees" -complete -c gtr -f -n "__fish_use_subcommand" -a "list" -d "List all worktrees" -complete -c gtr -f -n "__fish_use_subcommand" -a "clean" -d "Remove stale worktrees" -complete -c gtr -f -n "__fish_use_subcommand" -a "doctor" -d "Health check" -complete -c gtr -f -n "__fish_use_subcommand" -a "adapter" -d "List available adapters" -complete -c gtr -f -n "__fish_use_subcommand" -a "config" -d "Manage configuration" -complete -c gtr -f -n "__fish_use_subcommand" -a "version" -d "Show version" -complete -c gtr -f -n "__fish_use_subcommand" -a "help" -d "Show help" +complete -f -c git -n '__fish_git_gtr_needs_command' -a new -d 'Create a new worktree' +complete -f -c git -n '__fish_git_gtr_needs_command' -a go -d 'Navigate to worktree' +complete -f -c git -n '__fish_git_gtr_needs_command' -a rm -d 'Remove worktree(s)' +complete -f -c git -n '__fish_git_gtr_needs_command' -a editor -d 'Open worktree in editor' +complete -f -c git -n '__fish_git_gtr_needs_command' -a ai -d 'Start AI coding tool' +complete -f -c git -n '__fish_git_gtr_needs_command' -a ls -d 'List all worktrees' +complete -f -c git -n '__fish_git_gtr_needs_command' -a list -d 'List all worktrees' +complete -f -c git -n '__fish_git_gtr_needs_command' -a clean -d 'Remove stale worktrees' +complete -f -c git -n '__fish_git_gtr_needs_command' -a doctor -d 'Health check' +complete -f -c git -n '__fish_git_gtr_needs_command' -a adapter -d 'List available adapters' +complete -f -c git -n '__fish_git_gtr_needs_command' -a config -d 'Manage configuration' +complete -f -c git -n '__fish_git_gtr_needs_command' -a version -d 'Show version' +complete -f -c git -n '__fish_git_gtr_needs_command' -a help -d 'Show help' # New command options -complete -c gtr -n "__fish_seen_subcommand_from new" -l from -d "Base ref" -r -complete -c gtr -n "__fish_seen_subcommand_from new" -l track -d "Track mode" -r -a "auto remote local none" -complete -c gtr -n "__fish_seen_subcommand_from new" -l no-copy -d "Skip file copying" -complete -c gtr -n "__fish_seen_subcommand_from new" -l no-fetch -d "Skip git fetch" -complete -c gtr -n "__fish_seen_subcommand_from new" -l force -d "Allow same branch in multiple worktrees" -complete -c gtr -n "__fish_seen_subcommand_from new" -l name -d "Custom folder name suffix" -r -complete -c gtr -n "__fish_seen_subcommand_from new" -l yes -d "Non-interactive mode" +complete -c git -n '__fish_git_gtr_using_command new' -l from -d 'Base ref' -r +complete -c git -n '__fish_git_gtr_using_command new' -l track -d 'Track mode' -r -a 'auto remote local none' +complete -c git -n '__fish_git_gtr_using_command new' -l no-copy -d 'Skip file copying' +complete -c git -n '__fish_git_gtr_using_command new' -l no-fetch -d 'Skip git fetch' +complete -c git -n '__fish_git_gtr_using_command new' -l force -d 'Allow same branch in multiple worktrees' +complete -c git -n '__fish_git_gtr_using_command new' -l name -d 'Custom folder name suffix' -r +complete -c git -n '__fish_git_gtr_using_command new' -l yes -d 'Non-interactive mode' # Remove command options -complete -c gtr -n "__fish_seen_subcommand_from rm" -l delete-branch -d "Delete branch" -complete -c gtr -n "__fish_seen_subcommand_from rm" -l force -d "Force removal even if dirty" -complete -c gtr -n "__fish_seen_subcommand_from rm" -l yes -d "Non-interactive mode" +complete -c git -n '__fish_git_gtr_using_command rm' -l delete-branch -d 'Delete branch' +complete -c git -n '__fish_git_gtr_using_command rm' -l force -d 'Force removal even if dirty' +complete -c git -n '__fish_git_gtr_using_command rm' -l yes -d 'Non-interactive mode' # Config command -complete -c gtr -n "__fish_seen_subcommand_from config" -f -a "get set unset" -complete -c gtr -n "__fish_seen_subcommand_from config; and __fish_seen_subcommand_from get set unset" -f -a "\ +complete -f -c git -n '__fish_git_gtr_using_command config' -a 'get set add unset' +complete -f -c git -n '__fish_git_gtr_using_command config' -a " gtr.worktrees.dir\t'Worktrees base directory' gtr.worktrees.prefix\t'Worktree folder prefix' gtr.defaultBranch\t'Default branch' @@ -46,10 +67,13 @@ complete -c gtr -n "__fish_seen_subcommand_from config; and __fish_seen_subcomma # Helper function to get branch names and special '1' for main repo function __gtr_worktree_branches # Special ID for main repo - echo "1" + echo '1' # Get branch names git branch --format='%(refname:short)' 2>/dev/null end # Complete branch names for commands that need them -complete -c gtr -n "__fish_seen_subcommand_from go editor ai rm" -f -a "(__gtr_worktree_branches)" +complete -f -c git -n '__fish_git_gtr_using_command go' -a '(__gtr_worktree_branches)' +complete -f -c git -n '__fish_git_gtr_using_command editor' -a '(__gtr_worktree_branches)' +complete -f -c git -n '__fish_git_gtr_using_command ai' -a '(__gtr_worktree_branches)' +complete -f -c git -n '__fish_git_gtr_using_command rm' -a '(__gtr_worktree_branches)' diff --git a/templates/setup-example.sh b/templates/setup-example.sh index fe4d754..d85221a 100755 --- a/templates/setup-example.sh +++ b/templates/setup-example.sh @@ -1,10 +1,10 @@ #!/bin/sh -# Example setup script for gtr configuration +# Example setup script for git gtr configuration # Customize this for your project set -e -echo "🔧 Configuring gtr for this repository..." +echo "🔧 Configuring git gtr for this repository..." # Worktree settings git config --local gtr.worktrees.prefix "" @@ -29,7 +29,7 @@ git config --local gtr.defaultBranch "auto" # git config --local --add gtr.hook.postCreate "bundle install" # git config --local --add gtr.hook.postCreate "cargo build" -echo "✅ gtr configured!" +echo "✅ git gtr configured!" echo "" echo "View config with: git config --local --list | grep gtr" -echo "Create a worktree with: gtr new my-feature" +echo "Create a worktree with: git gtr new my-feature" From 2332755ba248f22d6f935e481f0af9e3bbcb7a7f Mon Sep 17 00:00:00 2001 From: Hans Elizaga Date: Mon, 17 Nov 2025 14:46:44 -0800 Subject: [PATCH 2/7] Update README and gtr script to use `git gtr` command for consistency --- README.md | 2 +- bin/gtr | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ae7c3c8..5bdebd0 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,7 @@ cd git-worktree-runner # Add to PATH (choose one) # Option 1: Symlink to /usr/local/bin -sudo ln -s "$(pwd)/bin/gtr" /usr/local/bin/gtr +sudo ln -s "$(pwd)/bin/git-gtr" /usr/local/bin/git-gtr # Option 2: Add to your shell profile echo 'export PATH="$PATH:'$(pwd)'/bin"' >> ~/.zshrc # or ~/.bashrc diff --git a/bin/gtr b/bin/gtr index 1113d01..e8f4906 100755 --- a/bin/gtr +++ b/bin/gtr @@ -236,9 +236,9 @@ cmd_create() { log_info "Worktree created: $worktree_path" echo "" echo "Next steps:" - echo " gtr editor $branch_name # Open in editor" - echo " gtr ai $branch_name # Start AI tool" - echo " cd \"\$(gtr go $branch_name)\" # Navigate to worktree" + echo " git gtr editor $branch_name # Open in editor" + echo " git gtr ai $branch_name # Start AI tool" + echo " cd \"\$(git gtr go $branch_name)\" # Navigate to worktree" } # Remove command @@ -460,7 +460,7 @@ cmd_ai() { # Check if AI tool is configured if [ "$ai_tool" = "none" ]; then log_error "No AI tool configured" - log_info "Set default: gtr config set gtr.ai.default claude" + log_info "Set default: git gtr config set gtr.ai.default claude" exit 1 fi @@ -606,7 +606,7 @@ EOF # Doctor command (health check) cmd_doctor() { - echo "Running gtr health check..." + echo "Running git gtr health check..." echo "" local issues=0 @@ -747,8 +747,8 @@ cmd_adapter() { echo "" echo "" echo "Tip: Set defaults with:" - echo " gtr config set gtr.editor.default " - echo " gtr config set gtr.ai.default " + echo " git gtr config set gtr.editor.default " + echo " git gtr config set gtr.ai.default " } # Config command From b028a8d6c300d1dbfb4df113675e4ff56496c279 Mon Sep 17 00:00:00 2001 From: Hans Elizaga Date: Mon, 17 Nov 2025 14:53:00 -0800 Subject: [PATCH 3/7] Update README and completion instructions --- .github/instructions/completions.instructions.md | 6 +++--- README.md | 14 ++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/instructions/completions.instructions.md b/.github/instructions/completions.instructions.md index a15ee7e..158e985 100644 --- a/.github/instructions/completions.instructions.md +++ b/.github/instructions/completions.instructions.md @@ -78,7 +78,7 @@ When adding an editor or AI adapter: **Fish** (`completions/gtr.fish`): -- Update `complete -c gtr` lines for editor/AI flags +- Update `complete -c git` lines for editor/AI flags - List adapter names explicitly or parse from `git gtr adapter` output ## Keep in Sync @@ -128,6 +128,6 @@ The three completion files must stay synchronized: ## Fish-Specific Notes -- Uses declarative `complete -c gtr` syntax -- Conditions can check previous arguments with `__fish_seen_subcommand_from` +- Uses `complete -c git` with custom predicates (`__fish_git_gtr_needs_command`, `__fish_git_gtr_using_command`) to handle git subcommand context +- Conditions can check previous arguments with custom functions to detect `git gtr` usage - Can call external commands for dynamic completion diff --git a/README.md b/README.md index 5bdebd0..c494e22 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,12 @@ git gtr rm my-feature # Remove when done While `git worktree` is powerful, it's verbose and manual. `git gtr` adds quality-of-life features for modern development: | Task | With `git worktree` | With `git gtr` | -| ----------------- | ------------------------------------------ | ------------------------------------ | +| ----------------- | ------------------------------------------ | ---------------------------------------- | | Create worktree | `git worktree add ../repo-feature feature` | `git gtr new feature` | | Open in editor | `cd ../repo-feature && cursor .` | `git gtr editor feature` | | Start AI tool | `cd ../repo-feature && aider` | `git gtr ai feature` | -| Copy config files | Manual copy/paste | Auto-copy via `gtr.copy.include` | -| Run build steps | Manual `npm install && npm run build` | Auto-run via `gtr.hook.postCreate` | +| Copy config files | Manual copy/paste | Auto-copy via `gtr.copy.include` | +| Run build steps | Manual `npm install && npm run build` | Auto-run via `gtr.hook.postCreate` | | List worktrees | `git worktree list` (shows paths) | `git gtr list` (shows branches + status) | | Clean up | `git worktree remove ../repo-feature` | `git gtr rm feature` | @@ -297,8 +297,8 @@ gtr.ai.default = none **Supported AI Tools:** -| Tool | Install | Use Case | Set as Default | -| ------------------------------------------------- | ------------------------------------------------- | ------------------------------------ | ---------------------------------------- | +| Tool | Install | Use Case | Set as Default | +| ------------------------------------------------- | ------------------------------------------------- | ------------------------------------ | -------------------------------------------- | | **[Aider](https://aider.chat)** | `pip install aider-chat` | Pair programming, edit files with AI | `git gtr config set gtr.ai.default aider` | | **[Claude Code](https://claude.com/claude-code)** | Install from claude.com | Terminal-native coding agent | `git gtr config set gtr.ai.default claude` | | **[Codex CLI](https://github.com/openai/codex)** | `npm install -g @openai/codex` | OpenAI coding assistant | `git gtr config set gtr.ai.default codex` | @@ -631,7 +631,9 @@ find . -path "**/.env.example" ```log git-worktree-runner/ -├── bin/gtr # Main executable +├── bin/ +│ ├── git-gtr # Git subcommand entry point (wrapper) +│ └── gtr # Core implementation (1000+ lines) ├── lib/ # Core libraries │ ├── core.sh # Git worktree operations │ ├── config.sh # Configuration management From b080e3eddb3ef6e474c5186f04c6a975734a31c5 Mon Sep 17 00:00:00 2001 From: Hans Elizaga Date: Mon, 17 Nov 2025 15:01:30 -0800 Subject: [PATCH 4/7] Enhance CLAUDE.md with v2.0.0 command structure and environment variable details --- CLAUDE.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 7ae1130..0e6844e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,6 +6,19 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co `git gtr` (Git Worktree Runner) is a cross-platform CLI tool written in Bash that simplifies git worktree management. It wraps `git worktree` with quality-of-life features like editor integration, AI tool support, file copying, and hooks. It is installed as a git subcommand, so all commands are invoked as `git gtr `. +## Important: v2.0.0 Command Structure + +**As of v2.0.0**, the tool is invoked as `git gtr` (git subcommand) to avoid conflicts with GNU coreutils: + +- **Production use**: `git gtr ` (git subcommand) +- **Development/testing**: `./bin/gtr ` (direct script execution) + +**Binary structure**: +- `bin/git-gtr`: Thin wrapper (16 lines) that allows git subcommand invocation (`git gtr`) +- `bin/gtr`: Main script containing all logic (900+ lines) + +When testing changes locally, you use `./bin/gtr` directly. When documenting user-facing features or writing help text, always reference `git gtr`. + ## Development Commands ### Testing Changes Locally @@ -182,6 +195,13 @@ git --version - Return code 0 indicates success/availability; non-zero indicates failure - See "Adapter Contract" in Important Implementation Details for full specifications +**Generic Adapter Fallback**: In addition to specific adapter files, gtr supports generic adapters via environment variables: + +- `GTR_EDITOR_CMD`: Custom editor command (e.g., `GTR_EDITOR_CMD="emacs"`) +- `GTR_AI_CMD`: Custom AI tool command (e.g., `GTR_AI_CMD="copilot"`) + +These generic functions in `bin/gtr:34-55` provide a fallback when no specific adapter file exists. This allows users to configure custom tools without creating adapter files. The generic adapter functions check if the command exists using `command -v` and execute it using `eval` to handle multi-word commands properly (e.g., `code --wait`, `bunx @github/copilot@latest`). + ### Command Flow Understanding how commands are dispatched through the system: @@ -227,11 +247,11 @@ When making changes, follow these core principles (from CONTRIBUTING.md): ### Updating the Version Number -When releasing a new version, update the version constant in `bin/gtr`: +When releasing a new version, update the version constant in `bin/gtr` (the main script, not the `bin/git-gtr` wrapper): ```bash # bin/gtr line 8 -GTR_VERSION="1.0.0" # Update this +GTR_VERSION="2.0.0" # Update this ``` The version is displayed with `git gtr version` and `git gtr --version`. @@ -350,6 +370,23 @@ All config keys use `gtr.*` prefix and are managed via `git config`: - `gtr.hook.postCreate`: Multi-valued commands to run after creating worktree - `gtr.hook.postRemove`: Multi-valued commands to run after removing worktree +## Environment Variables + +**System environment variables**: + +- `GTR_DIR`: Override script directory location (default: auto-detected via symlink resolution in `bin/gtr:11-21`) +- `GTR_WORKTREES_DIR`: Override base worktrees directory (fallback if `gtr.worktrees.dir` not set) +- `GTR_EDITOR_CMD`: Generic editor command for custom editors without adapter files +- `GTR_EDITOR_CMD_NAME`: First word of `GTR_EDITOR_CMD` used for availability checks +- `GTR_AI_CMD`: Generic AI tool command for custom tools without adapter files +- `GTR_AI_CMD_NAME`: First word of `GTR_AI_CMD` used for availability checks + +**Hook environment variables** (available in `gtr.hook.postCreate` and `gtr.hook.postRemove` scripts): + +- `REPO_ROOT`: Repository root path +- `WORKTREE_PATH`: New worktree path +- `BRANCH`: Branch name + ## Important Implementation Details **Worktree Path Resolution**: The `resolve_target` function in `lib/core.sh:193-242` handles both branch names and the special ID '1'. It checks in order: special ID, current branch in main repo, sanitized path match, full directory scan. Returns tab-separated format: `is_main\tpath\tbranch`. @@ -394,8 +431,14 @@ ls -la /usr/local/bin # Create it if needed (macOS/Linux) sudo mkdir -p /usr/local/bin -# Verify symlink -ls -la /usr/local/bin/gtr +# Verify symlink (v2.0.0+: symlink to git-gtr, not gtr) +ls -la /usr/local/bin/git-gtr + +# Create symlink for v2.0.0+ +sudo ln -s "$(pwd)/bin/git-gtr" /usr/local/bin/git-gtr + +# Verify it works +git gtr version ``` ### Adapter Not Found From 67fe7140efe54ea8ea095560d8815103e6ffee4d Mon Sep 17 00:00:00 2001 From: Hans Elizaga Date: Mon, 17 Nov 2025 15:33:33 -0800 Subject: [PATCH 5/7] Add pull request template for consistent contributions --- .github/PULL_REQUEST_TEMPLATE.md | 92 ++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..34b1910 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,92 @@ +# Pull Request + +## Description + + + +## Motivation + + + +Fixes # (issue) + +## Type of Change + + + +- [ ] Bug fix (non-breaking change that fixes an issue) +- [ ] New feature (non-breaking change that adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Code refactoring (no functional changes) +- [ ] Other (please describe): + +## Testing + + + +### Manual Testing Checklist + +**Tested on:** + +- [ ] macOS +- [ ] Linux (specify distro: **\*\***\_**\*\***) +- [ ] Windows (Git Bash) + +**Core functionality tested:** + +- [ ] `git gtr new ` - Create worktree +- [ ] `git gtr go ` - Navigate to worktree +- [ ] `git gtr editor ` - Open in editor (if applicable) +- [ ] `git gtr ai ` - Start AI tool (if applicable) +- [ ] `git gtr rm ` - Remove worktree +- [ ] `git gtr list` - List worktrees +- [ ] `git gtr config` - Configuration commands (if applicable) +- [ ] Other commands affected by this change: **\*\***\_\_**\*\*** + +### Test Steps + + + +1. +2. +3. + +**Expected behavior:** + +**Actual behavior:** + +## Breaking Changes + + + + + + +- [ ] This PR introduces breaking changes +- [ ] I have discussed this in an issue first +- [ ] Migration guide is included in documentation + +## Checklist + +Before submitting this PR, please check: + +- [ ] I have read [CONTRIBUTING.md](../CONTRIBUTING.md) +- [ ] My code follows the project's style guidelines +- [ ] I have performed manual testing on at least one platform +- [ ] I have updated documentation (README.md, CLAUDE.md, etc.) if needed +- [ ] My changes work on multiple platforms (or I've noted platform-specific behavior) +- [ ] I have added/updated shell completions (if adding new commands or flags) +- [ ] I have tested with both `git gtr` (production) and `./bin/gtr` (development) +- [ ] No new external dependencies are introduced (Bash + git only) +- [ ] All existing functionality still works + +## Additional Context + + + +--- + +## License Acknowledgment + +By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache License 2.0](../LICENSE.txt). From 707f2c4c62391dd482ffad6729f0ff04152e826d Mon Sep 17 00:00:00 2001 From: Hans Elizaga Date: Mon, 17 Nov 2025 16:18:42 -0800 Subject: [PATCH 6/7] Enhance shell completion documentation and scripts for `git gtr` - Updated README.md to clarify prerequisites for Bash and Zsh completions, including the need for git's completion system. - Improved completion instructions in completions.instructions.md to reflect changes in command structure and added details for testing completions. - Modified completion scripts for Bash, Zsh, and Fish to integrate better with their respective completion systems and added instructions for installation and usage. --- .../instructions/completions.instructions.md | 41 ++++++++++++------- README.md | 18 ++++++-- completions/_gtr | 24 +++++++---- completions/gtr.bash | 12 ++++++ completions/gtr.fish | 9 ++++ 5 files changed, 79 insertions(+), 25 deletions(-) diff --git a/.github/instructions/completions.instructions.md b/.github/instructions/completions.instructions.md index 158e985..86b9308 100644 --- a/.github/instructions/completions.instructions.md +++ b/.github/instructions/completions.instructions.md @@ -27,9 +27,9 @@ Shell completions provide tab-completion for `git gtr` commands, flags, branches Each completion file implements: -1. **Command completion** - Top-level commands (`new`, `rm`, `open`, `ai`, `list`, etc.) +1. **Command completion** - Top-level commands (`new`, `rm`, `editor`, `ai`, `list`, etc.) 2. **Flag completion** - Command-specific flags (e.g., `--from`, `--force`, `--editor`) -3. **Branch completion** - Dynamic completion of existing worktree branches (via `git gtr list --porcelain`) +3. **Branch completion** - Dynamic completion of git branches plus special ID `1` (via `git branch`) 4. **Adapter completion** - Editor names (`cursor`, `vscode`, `zed`) and AI tool names (`aider`, `claude`, `codex`) ## Testing Completions @@ -37,30 +37,41 @@ Each completion file implements: **Manual testing** (no automated tests): ```bash -# Bash - source the completion file +# Bash - source the completion file (requires git's bash completion to be loaded) source completions/gtr.bash git gtr # Should show commands git gtr new # Should show flags -git gtr open # Should show branches -git gtr open --editor # Should show editor names - -# Zsh - fpath must include completions directory -fpath=(completions $fpath) -autoload -U compinit && compinit -git gtr +git gtr go # Should show branches + '1' +git gtr editor # Should show branches + '1' +git gtr editor --editor # Should show editor names + +# Zsh - copy to fpath directory and reload (requires git's zsh completion) +mkdir -p ~/.zsh/completions +cp completions/_gtr ~/.zsh/completions/ +# Add to ~/.zshrc: fpath=(~/.zsh/completions $fpath) +# Add to ~/.zshrc: autoload -Uz compinit && compinit +exec zsh # Reload shell +git gtr # Should show commands +git gtr new # Should show flags +git gtr go # Should show branches + '1' # Fish - symlink to ~/.config/fish/completions/ ln -s "$(pwd)/completions/gtr.fish" ~/.config/fish/completions/ -git gtr +exec fish # Reload shell +git gtr # Should show commands +git gtr new # Should show flags +git gtr go # Should show branches + '1' ``` +**Important**: All shell completions require git's own completion system to be enabled for the `git` command. The completions integrate with git's subcommand completion framework. + ## Branch Completion Logic -All three completions dynamically fetch current worktree branches: +All three completions dynamically fetch current git branches: -- Parse output of `git gtr list --porcelain` (tab-separated: `path\tbranch\tstatus`) -- Extract branch column (second field) -- Exclude the special ID `1` (main repo) if needed +- Use `git branch --format='%(refname:short)'` to get branch names +- Add special ID `1` for main repo (allows `git gtr go 1`, `git gtr editor 1`, etc.) +- Return combined list of branches + `1` for commands that accept branch arguments (go, editor, ai, rm) ## Adapter Name Updates diff --git a/README.md b/README.md index c494e22..6f902dd 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ source ~/.zshrc ### Shell Completions (Optional) -**Bash** (requires `bash-completion` v2): +**Bash** (requires `bash-completion` v2 and git completions): ```bash # Install bash-completion first (if not already installed) @@ -133,15 +133,27 @@ brew install bash-completion@2 # Ubuntu/Debian: sudo apt install bash-completion +# Ensure git's bash completion is enabled (usually installed with git) # Then enable gtr completions: echo 'source /path/to/git-worktree-runner/completions/gtr.bash' >> ~/.bashrc source ~/.bashrc ``` -**Zsh:** +**Zsh** (requires git's zsh completion): ```bash -echo 'source /path/to/git-worktree-runner/completions/_gtr' >> ~/.zshrc +# Add completion directory to fpath and enable +mkdir -p ~/.zsh/completions +cp /path/to/git-worktree-runner/completions/_gtr ~/.zsh/completions/ + +# Add to ~/.zshrc (if not already there): +cat >> ~/.zshrc <<'EOF' +# Enable completions +fpath=(~/.zsh/completions $fpath) +autoload -Uz compinit && compinit +EOF + +source ~/.zshrc ``` **Fish:** diff --git a/completions/_gtr b/completions/_gtr index ffd06f5..f6a7004 100644 --- a/completions/_gtr +++ b/completions/_gtr @@ -1,7 +1,14 @@ -#compdef git-gtr +#compdef _git-gtr git-gtr + +# Register gtr as a git subcommand for completion +zstyle ':completion:*:*:git:*' user-commands gtr:'Git worktree management' + # Zsh completion for git gtr _git-gtr() { + # Note: When called via 'git gtr', the words array is [git, gtr, , ...] + # This matches how git's completion system passes context to subcommand completions + local -a commands commands=( 'new:Create a new worktree' @@ -25,10 +32,12 @@ _git-gtr() { # Add special ID '1' for main repo all_options=("1" "${branches[@]}") - if (( CURRENT == 2 )); then + # Complete the gtr subcommand (new, go, editor, etc.) + if (( CURRENT == 3 )); then _describe 'commands' commands - elif (( CURRENT == 3 )); then - case "$words[2]" in + # Complete arguments to the subcommand + elif (( CURRENT == 4 )); then + case "$words[3]" in go|editor|ai|rm) _describe 'branch names' all_options ;; @@ -46,8 +55,9 @@ _git-gtr() { _values 'config action' get set add unset ;; esac - elif (( CURRENT >= 4 )); then - case "$words[2]" in + # Complete subsequent arguments + elif (( CURRENT >= 5 )); then + case "$words[3]" in rm) _arguments \ '--delete-branch[Delete branch]' \ @@ -55,7 +65,7 @@ _git-gtr() { '--yes[Non-interactive mode]' ;; config) - case "$words[3]" in + case "$words[4]" in get|set|add|unset) _values 'config key' \ 'gtr.worktrees.dir' \ diff --git a/completions/gtr.bash b/completions/gtr.bash index 59e235a..69e08ed 100644 --- a/completions/gtr.bash +++ b/completions/gtr.bash @@ -1,5 +1,17 @@ #!/bin/bash # Bash completion for git gtr +# +# Prerequisites: +# - bash-completion v2+ must be installed +# - Git's bash completion must be enabled +# +# This completion integrates with git's completion system by defining a _git_ +# function, which git's completion framework automatically discovers and calls when +# completing "git gtr ..." commands. +# +# Installation: +# Add to your ~/.bashrc: +# source /path/to/git-worktree-runner/completions/gtr.bash _git_gtr() { local cur prev words cword diff --git a/completions/gtr.fish b/completions/gtr.fish index b00750e..4f41b4d 100644 --- a/completions/gtr.fish +++ b/completions/gtr.fish @@ -1,4 +1,13 @@ # Fish completion for git gtr +# +# This completion integrates with fish's completion system by registering completions +# for the "git" command with custom predicates that detect "git gtr" usage. +# +# Installation: +# Symlink to fish's completions directory: +# ln -s /path/to/git-worktree-runner/completions/gtr.fish ~/.config/fish/completions/ +# Then reload fish: +# exec fish # Helper function to check if we're in 'git gtr' context function __fish_git_gtr_needs_command From a6beb6921420fb76602ef9cc29005c01a0f0b023 Mon Sep 17 00:00:00 2001 From: Hans Elizaga Date: Mon, 17 Nov 2025 17:11:09 -0800 Subject: [PATCH 7/7] Update Zsh completion file naming and documentation for `git gtr` - Renamed Zsh completion file from `_gtr` to `_git-gtr` for consistency with command structure. - Updated references in README.md, completions.instructions.md, and editor.instructions.md to reflect the new file name. - Added the new `_git-gtr` completion script to enhance Zsh support for `git gtr` commands. --- .../instructions/completions.instructions.md | 8 +++--- .github/instructions/editor.instructions.md | 2 +- CLAUDE.md | 2 +- README.md | 2 +- completions/{_gtr => _git-gtr} | 26 ++++++++----------- 5 files changed, 18 insertions(+), 22 deletions(-) rename completions/{_gtr => _git-gtr} (79%) diff --git a/.github/instructions/completions.instructions.md b/.github/instructions/completions.instructions.md index 86b9308..877a95c 100644 --- a/.github/instructions/completions.instructions.md +++ b/.github/instructions/completions.instructions.md @@ -1,5 +1,5 @@ --- -applyTo: completions/gtr.bash, completions/_gtr, completions/gtr.fish +applyTo: completions/gtr.bash, completions/_git-gtr, completions/gtr.fish --- # Completions Instructions @@ -20,7 +20,7 @@ Shell completions provide tab-completion for `git gtr` commands, flags, branches ## File Responsibilities - **`completions/gtr.bash`** - Bash completion (requires bash-completion v2+) -- **`completions/_gtr`** - Zsh completion (uses Zsh completion system) +- **`completions/_git-gtr`** - Zsh completion (uses Zsh completion system) - **`completions/gtr.fish`** - Fish shell completion ## Implementation Pattern @@ -47,7 +47,7 @@ git gtr editor --editor # Should show editor names # Zsh - copy to fpath directory and reload (requires git's zsh completion) mkdir -p ~/.zsh/completions -cp completions/_gtr ~/.zsh/completions/ +cp completions/_git-gtr ~/.zsh/completions/ # Add to ~/.zshrc: fpath=(~/.zsh/completions $fpath) # Add to ~/.zshrc: autoload -Uz compinit && compinit exec zsh # Reload shell @@ -82,7 +82,7 @@ When adding an editor or AI adapter: - Update `_gtr_editors` array or case statement - Update flag completion for `--editor` in `open` command -**Zsh** (`completions/_gtr`): +**Zsh** (`completions/_git-gtr`): - Update `_arguments` completion specs for `--editor` or `--ai` - Use `_values` or `_alternative` for adapter names diff --git a/.github/instructions/editor.instructions.md b/.github/instructions/editor.instructions.md index 228ba86..6bd84ba 100644 --- a/.github/instructions/editor.instructions.md +++ b/.github/instructions/editor.instructions.md @@ -29,7 +29,7 @@ editor_open() { **Also update**: - README.md (setup instructions) -- All three completion files: `completions/gtr.bash`, `completions/_gtr`, `completions/gtr.fish` +- All three completion files: `completions/gtr.bash`, `completions/_git-gtr`, `completions/gtr.fish` - Help text in `bin/gtr` (`cmd_help` function) ## Contract & Guidelines diff --git a/CLAUDE.md b/CLAUDE.md index 0e6844e..0af6758 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -334,7 +334,7 @@ When changing `lib/*.sh` files: When adding new commands or flags, update all three completion files: - `completions/gtr.bash` (Bash) -- `completions/_gtr` (Zsh) +- `completions/_git-gtr` (Zsh) - `completions/gtr.fish` (Fish) ### Git Version Compatibility diff --git a/README.md b/README.md index 6f902dd..5ef100a 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ source ~/.bashrc ```bash # Add completion directory to fpath and enable mkdir -p ~/.zsh/completions -cp /path/to/git-worktree-runner/completions/_gtr ~/.zsh/completions/ +cp /path/to/git-worktree-runner/completions/_git-gtr ~/.zsh/completions/ # Add to ~/.zshrc (if not already there): cat >> ~/.zshrc <<'EOF' diff --git a/completions/_gtr b/completions/_git-gtr similarity index 79% rename from completions/_gtr rename to completions/_git-gtr index f6a7004..01eccba 100644 --- a/completions/_gtr +++ b/completions/_git-gtr @@ -1,13 +1,9 @@ -#compdef _git-gtr git-gtr - -# Register gtr as a git subcommand for completion -zstyle ':completion:*:*:git:*' user-commands gtr:'Git worktree management' - +#compdef git-gtr # Zsh completion for git gtr -_git-gtr() { - # Note: When called via 'git gtr', the words array is [git, gtr, , ...] - # This matches how git's completion system passes context to subcommand completions +_git_gtr() { + # Note: When called via 'git gtr', the words array is [git-gtr, , ...] + # Git's completion system invokes this function automatically local -a commands commands=( @@ -33,11 +29,11 @@ _git-gtr() { all_options=("1" "${branches[@]}") # Complete the gtr subcommand (new, go, editor, etc.) - if (( CURRENT == 3 )); then + if (( CURRENT == 2 )); then _describe 'commands' commands # Complete arguments to the subcommand - elif (( CURRENT == 4 )); then - case "$words[3]" in + elif (( CURRENT == 3 )); then + case "$words[2]" in go|editor|ai|rm) _describe 'branch names' all_options ;; @@ -56,8 +52,8 @@ _git-gtr() { ;; esac # Complete subsequent arguments - elif (( CURRENT >= 5 )); then - case "$words[3]" in + elif (( CURRENT >= 4 )); then + case "$words[2]" in rm) _arguments \ '--delete-branch[Delete branch]' \ @@ -65,7 +61,7 @@ _git-gtr() { '--yes[Non-interactive mode]' ;; config) - case "$words[4]" in + case "$words[3]" in get|set|add|unset) _values 'config key' \ 'gtr.worktrees.dir' \ @@ -84,4 +80,4 @@ _git-gtr() { fi } -_git-gtr "$@" +# Function is auto-discovered by git's completion system - do not call it here