From ead3767b5e2873b9cd8b6dbc995211b131d75d56 Mon Sep 17 00:00:00 2001 From: Tom Elizaga Date: Mon, 14 Sep 2026 08:59:45 -0700 Subject: [PATCH 1/5] docs: refresh guides for v2.9-v2.11 features and fix stale references AGENTS.md and CLAUDE.md were last updated before the pr and trust commands, clean --closed, sparse-checkout inheritance, --porcelain, and postCd hooks landed. AGENTS.md also pointed at a nonexistent adapters/ai/Codex.sh left over from a global rename. - AGENTS.md/CLAUDE.md: add pr/trust to the dispatch table, describe cd handling, list the current 29 BATS files, fix the lib/commands count, document pr, --porcelain, sparse inheritance, clean --closed, postCd, gtr.defaultBranch/defaultRemote/provider, GTR_DEBUG, and link docs/agent-usage.md and docs/troubleshooting.md - README: add --sparse/--no-sparse to git gtr new, add Maintainers to the table of contents - docs/agent-usage.md: document --no-hooks/--no-copy/--no-fetch for minimal-side-effect automation worktrees - docs/configuration.md: add GTR_WORKTREES_PREFIX, GTR_DEFAULT_BRANCH, GTR_EDITOR_DEFAULT, GTR_AI_DEFAULT and note env vars are fallbacks - docs/troubleshooting.md: replace the non-working `bash -x git gtr` advice with GTR_DEBUG=1 and a direct-script trace - CHANGELOG: record the docs changes under Unreleased --- AGENTS.md | 38 ++++++++++++++++++++++++++------------ CHANGELOG.md | 11 +++++++++++ CLAUDE.md | 32 +++++++++++++++++++++++--------- README.md | 3 +++ docs/agent-usage.md | 18 ++++++++++++++++++ docs/configuration.md | 30 ++++++++++++++++++------------ docs/troubleshooting.md | 5 +++-- 7 files changed, 102 insertions(+), 35 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 21a73a8..8895cf7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS.md -This file provides guidance to Codex (Codex.ai/code) when working with code in this repository. +This file provides guidance to AI coding agents (Codex, Copilot, and similar tools) when working with code in this repository. ## Project Overview @@ -32,7 +32,7 @@ This project uses **BATS tests** for core functions and **manual smoke tests** f For exhaustive manual testing (hooks, copy patterns, adapters, `--force`, `--from-current`, etc.), see the full checklist in CONTRIBUTING.md or `.github/instructions/testing.instructions.md`. -**Test files**: `adapters`, `config`, `copy_safety`, `integration_lifecycle`, `parse_args`, `provider`, `resolve_base_dir`, `sanitize_branch_name` (all in `tests/`). Shared fixtures in `tests/test_helper.bash`. +**Test files** (all in `tests/`): one `cmd_*.bats` file per command (`cmd_clean`, `cmd_config`, `cmd_copy`, `cmd_create_integration`, `cmd_go`, `cmd_help`, `cmd_list`, `cmd_pr`, `cmd_remove`, `cmd_rename`, `cmd_run`, `cmd_trust`), library tests (`adapters`, `completion`, `config`, `copy_safety`, `core_create_worktree`, `core_resolve_target`, `hooks`, `init`, `launch`, `parse_args`, `platform`, `provider`, `resolve_base_dir`, `sanitize_branch_name`, `sparse`, `ui_color`), and `integration_lifecycle` for end-to-end flows. Shared fixtures in `tests/test_helper.bash`. **Tip**: Use a disposable repo for testing to avoid polluting your working tree: @@ -58,11 +58,11 @@ mkdir -p /tmp/gtr-test && cd /tmp/gtr-test && git init && git commit --allow-emp | `lib/platform.sh` | OS detection, GUI helpers | | `lib/core.sh` | Worktree CRUD: `create_worktree`, `remove_worktree`, `list_worktrees`, `resolve_target`, `resolve_base_dir` | | `lib/copy.sh` | File/directory copying with glob patterns: `copy_patterns`, `copy_directories` | -| `lib/hooks.sh` | Hook execution: `run_hooks_in` for postCreate/preRemove/postRemove | -| `lib/provider.sh` | Remote hosting detection (GitHub/GitLab) and CLI integration for `clean --merged` | +| `lib/hooks.sh` | Hook execution: `run_hooks_in` for postCreate/preRemove/postRemove/postCd | +| `lib/provider.sh` | Remote hosting detection (GitHub/GitLab) and CLI integration for `clean --merged/--closed` | | `lib/adapters.sh` | Adapter registry, builder functions, generic fallbacks, loader functions | | `lib/launch.sh` | Editor/AI launch orchestration: `_open_editor`, `_auto_launch_editor`, `_auto_launch_ai` | -| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, etc. (16 files) | +| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, `cmd_pr`, `cmd_trust`, etc. (18 files) | Libraries are sourced in the order listed above (ui → args → config → ... → launch → commands/\*.sh glob). @@ -72,17 +72,17 @@ Most adapters are defined declaratively in the **adapter registry** (`lib/adapte **Registry-defined adapters**: antigravity, atom, cursor, emacs, idea, nvim, pycharm, sublime, vim, vscode, webstorm, zed (editors) and aider, auggie, codex, continue, copilot, gemini, opencode (AI). -**Custom adapter files**: `adapters/editor/nano.sh`, `adapters/ai/Codex.sh`, `adapters/ai/cursor.sh` — these implement `editor_can_open()`/`editor_open()` or `ai_can_start()`/`ai_start()` directly. +**Custom adapter files**: `adapters/editor/nano.sh`, `adapters/ai/claude.sh`, `adapters/ai/cursor.sh` — these implement `editor_can_open()`/`editor_open()` or `ai_can_start()`/`ai_start()` directly. **Loading order**: file override → registry → generic PATH fallback. `GTR_EDITOR_CMD` / `GTR_AI_CMD` env vars allow custom tools without adapters. ### Command Flow ``` -bin/gtr main() → case statement → cmd_*() handler → lib/*.sh functions → adapters (if needed) +bin/git-gtr main() → case statement → cmd_*() handler → lib/*.sh functions → adapters (if needed) ``` -Key dispatch: `new`→`cmd_create`, `rm`→`cmd_remove`, `mv|rename`→`cmd_rename`, `go`→`cmd_go`, `run`→`cmd_run`, `editor`→`cmd_editor`, `ai`→`cmd_ai`, `copy`→`cmd_copy`, `ls|list`→`cmd_list`, `clean`→`cmd_clean`, `init`→`cmd_init`, `config`→`cmd_config`, `completion`→`cmd_completion`, `doctor`→`cmd_doctor`, `adapter`→`cmd_adapter`. +Key dispatch: `new`→`cmd_create`, `pr`→`cmd_pr`, `rm`→`cmd_remove`, `mv|rename`→`cmd_rename`, `go`→`cmd_go`, `run`→`cmd_run`, `editor`→`cmd_editor`, `ai`→`cmd_ai`, `copy`→`cmd_copy`, `ls|list`→`cmd_list`, `clean`→`cmd_clean`, `init`→`cmd_init`, `config`→`cmd_config`, `completion`→`cmd_completion`, `doctor`→`cmd_doctor`, `adapter|adapters`→`cmd_adapter`, `trust`→`cmd_trust`. `cd` has no `cmd_*` handler: the dispatcher prints shell-integration instructions because `gtr cd` is implemented by the shell function that `init` generates. **Example: `git gtr new my-feature`** @@ -114,14 +114,20 @@ cmd_editor() → resolve_target() → load_editor_adapter() → editor_open() **`init` command**: Outputs shell functions for `gtr cd ` navigation. Output is cached to `~/.cache/gtr/` and auto-invalidates on version change. Users source the cache file directly in their shell rc for fast startup (see `git gtr help init`). -**`clean --merged`**: Removes worktrees whose PRs/MRs are merged. Auto-detects GitHub (`gh`) or GitLab (`glab`) from the `origin` remote URL. Override with `gtr.provider` config for self-hosted instances. +**`clean --merged` / `clean --closed`**: Removes worktrees whose PRs/MRs are merged or closed and deletes their branches. Auto-detects GitHub (`gh`) or GitLab (`glab`) from the `origin` remote URL. Override with `gtr.provider` config for self-hosted instances. `clean` also unlocks and prunes locked registry entries whose directories no longer exist. + +**`pr `** (lib/commands/pr.sh): Creates a worktree from a GitHub pull request via `gh`. Uses `gh pr checkout --worktree` when the installed `gh` supports it, otherwise fetches `refs/pull//head` through a compatibility path. + +**`new --porcelain`**: Emits exactly three `keyvalue` records (`path`, `branch`, `hook_status`) on stdout with everything else on stderr. Contract documented in `docs/agent-usage.md`; keep it stable. + +**Sparse-checkout inheritance** (`gtr.sparse.inherit`, default on): On Git 2.36+, `new` copies the base worktree's sparse-checkout patterns instead of materializing a full tree. `--sparse`/`--no-sparse` override per invocation. ## Common Development Tasks ### Adding a New Command 1. Create `lib/commands/.sh` with `cmd_()` function -2. Add case entry in `main()` dispatcher in `bin/gtr` +2. Add case entry in `main()` dispatcher in `bin/git-gtr` 3. Add help text in `lib/commands/help.sh` 4. Update all three completion files: `completions/gtr.bash`, `completions/_git-gtr`, `completions/git-gtr.fish` 5. Update README.md @@ -130,7 +136,7 @@ cmd_editor() → resolve_target() → load_editor_adapter() → editor_open() **Standard adapters** (just a command name + error message): Add an entry to `_EDITOR_REGISTRY` or `_AI_REGISTRY` in `lib/adapters.sh`. Then update: help text in `lib/commands/help.sh`, all three completions, README.md. -**Custom adapters** (special logic needed): Create `adapters/{editor,ai}/.sh` implementing the two required functions (see `adapters/ai/Codex.sh` for an example). File-based adapters take priority over registry entries. +**Custom adapters** (special logic needed): Create `adapters/{editor,ai}/.sh` implementing the two required functions (see `adapters/ai/claude.sh` for an example). File-based adapters take priority over registry entries. ### Updating the Version @@ -171,10 +177,15 @@ All config uses `gtr.*` prefix via `git config`. Key settings: - `gtr.worktrees.dir` — Base directory (default: `-worktrees` sibling) - `gtr.worktrees.prefix` — Folder prefix (default: `""`) +- `gtr.defaultBranch` / `gtr.defaultRemote` — Base branch (default: auto-detect) and remote (default: `origin`) for new worktrees +- `gtr.sparse.inherit` — Inherit sparse-checkout from the base worktree on Git 2.36+ (default: `true`) +- `gtr.provider` — Force `github` or `gitlab` for `clean --merged/--closed` (default: detect from `origin` URL) - `gtr.editor.default` / `gtr.ai.default` — Default editor/AI tool - `gtr.copy.include` / `gtr.copy.exclude` — File glob patterns (multi-valued, use `--add`) - `gtr.copy.includeDirs` / `gtr.copy.excludeDirs` — Directory patterns (multi-valued) -- `gtr.hook.postCreate` / `gtr.hook.preRemove` / `gtr.hook.postRemove` — Hook commands (multi-valued) +- `gtr.hook.postCreate` / `gtr.hook.preRemove` / `gtr.hook.postRemove` / `gtr.hook.postCd` — Hook commands (multi-valued; `postCd` runs in the current shell after `gtr cd`, `gtr new --cd`, or `gtr pr --cd`) + +Every `cfg_default` key also has an environment-variable fallback (for example `GTR_WORKTREES_DIR`, `GTR_DEFAULT_BRANCH`); the full table is in `docs/configuration.md`. Hook env vars: `REPO_ROOT`, `WORKTREE_PATH`, `BRANCH`. preRemove hooks run with cwd in worktree; failure aborts removal unless `--force`. @@ -182,6 +193,7 @@ Hook env vars: `REPO_ROOT`, `WORKTREE_PATH`, `BRANCH`. preRemove hooks run with ```bash bash -x ./bin/gtr # Full trace +GTR_DEBUG=1 ./bin/gtr # Print file:line:function on set -e failures declare -f function_name # Check function definition echo "Debug: var=$var" >&2 # Inspect variable ./bin/gtr doctor # Health check @@ -195,3 +207,5 @@ echo "Debug: var=$var" >&2 # Inspect variable - `.github/instructions/*.instructions.md` — File-pattern-specific guidance (testing, shell conventions, lib modifications, adapter contracts, completions) - `docs/configuration.md` — Complete configuration reference - `docs/advanced-usage.md` — Advanced workflows +- `docs/agent-usage.md` — `--porcelain` output contract and safety boundaries for coding agents +- `docs/troubleshooting.md` — Common failures and fixes diff --git a/CHANGELOG.md b/CHANGELOG.md index 08c4d93..a77ebf2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this ## [Unreleased] +### Changed + +- The README documents `--sparse`/`--no-sparse` under `git gtr new` and lists the Maintainers section in its table of contents. +- `docs/agent-usage.md` explains how to suppress hooks, file copying, and fetching for bare automation worktrees. +- `docs/configuration.md` lists the remaining `GTR_*` fallback variables, and `docs/troubleshooting.md` describes `GTR_DEBUG`. +- `AGENTS.md` and `CLAUDE.md` now cover the `pr` and `trust` commands, `clean --closed`, sparse-checkout inheritance, `postCd` hooks, and the current test suite layout. + +### Fixed + +- `AGENTS.md` referenced a nonexistent `adapters/ai/Codex.sh`; it now points at `adapters/ai/claude.sh`. + ## [2.11.0] - 2026-08-19 ### Added diff --git a/CLAUDE.md b/CLAUDE.md index aabea71..5e93c3b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,7 +32,7 @@ This project uses **BATS tests** for core functions and **manual smoke tests** f For exhaustive manual testing (hooks, copy patterns, adapters, `--force`, `--from-current`, etc.), see the full checklist in CONTRIBUTING.md or `.github/instructions/testing.instructions.md`. -**Test files**: `adapters`, `config`, `copy_safety`, `integration_lifecycle`, `parse_args`, `provider`, `resolve_base_dir`, `sanitize_branch_name` (all in `tests/`). Shared fixtures in `tests/test_helper.bash`. +**Test files** (all in `tests/`): one `cmd_*.bats` file per command (`cmd_clean`, `cmd_config`, `cmd_copy`, `cmd_create_integration`, `cmd_go`, `cmd_help`, `cmd_list`, `cmd_pr`, `cmd_remove`, `cmd_rename`, `cmd_run`, `cmd_trust`), library tests (`adapters`, `completion`, `config`, `copy_safety`, `core_create_worktree`, `core_resolve_target`, `hooks`, `init`, `launch`, `parse_args`, `platform`, `provider`, `resolve_base_dir`, `sanitize_branch_name`, `sparse`, `ui_color`), and `integration_lifecycle` for end-to-end flows. Shared fixtures in `tests/test_helper.bash`. **Tip**: Use a disposable repo for testing to avoid polluting your working tree: @@ -58,11 +58,11 @@ mkdir -p /tmp/gtr-test && cd /tmp/gtr-test && git init && git commit --allow-emp | `lib/platform.sh` | OS detection, GUI helpers | | `lib/core.sh` | Worktree CRUD: `create_worktree`, `remove_worktree`, `list_worktrees`, `resolve_target`, `resolve_base_dir` | | `lib/copy.sh` | File/directory copying with glob patterns: `copy_patterns`, `copy_directories` | -| `lib/hooks.sh` | Hook execution: `run_hooks_in` for postCreate/preRemove/postRemove | -| `lib/provider.sh` | Remote hosting detection (GitHub/GitLab) and CLI integration for `clean --merged` | +| `lib/hooks.sh` | Hook execution: `run_hooks_in` for postCreate/preRemove/postRemove/postCd | +| `lib/provider.sh` | Remote hosting detection (GitHub/GitLab) and CLI integration for `clean --merged/--closed` | | `lib/adapters.sh` | Adapter registry, builder functions, generic fallbacks, loader functions | | `lib/launch.sh` | Editor/AI launch orchestration: `_open_editor`, `_auto_launch_editor`, `_auto_launch_ai` | -| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, etc. (16 files) | +| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, `cmd_pr`, `cmd_trust`, etc. (18 files) | Libraries are sourced in the order listed above (ui → args → config → ... → launch → commands/\*.sh glob). @@ -79,10 +79,10 @@ Most adapters are defined declaratively in the **adapter registry** (`lib/adapte ### Command Flow ``` -bin/gtr main() → case statement → cmd_*() handler → lib/*.sh functions → adapters (if needed) +bin/git-gtr main() → case statement → cmd_*() handler → lib/*.sh functions → adapters (if needed) ``` -Key dispatch: `new`→`cmd_create`, `rm`→`cmd_remove`, `mv|rename`→`cmd_rename`, `go`→`cmd_go`, `run`→`cmd_run`, `editor`→`cmd_editor`, `ai`→`cmd_ai`, `copy`→`cmd_copy`, `ls|list`→`cmd_list`, `clean`→`cmd_clean`, `init`→`cmd_init`, `config`→`cmd_config`, `completion`→`cmd_completion`, `doctor`→`cmd_doctor`, `adapter`→`cmd_adapter`. +Key dispatch: `new`→`cmd_create`, `pr`→`cmd_pr`, `rm`→`cmd_remove`, `mv|rename`→`cmd_rename`, `go`→`cmd_go`, `run`→`cmd_run`, `editor`→`cmd_editor`, `ai`→`cmd_ai`, `copy`→`cmd_copy`, `ls|list`→`cmd_list`, `clean`→`cmd_clean`, `init`→`cmd_init`, `config`→`cmd_config`, `completion`→`cmd_completion`, `doctor`→`cmd_doctor`, `adapter|adapters`→`cmd_adapter`, `trust`→`cmd_trust`. `cd` has no `cmd_*` handler: the dispatcher prints shell-integration instructions because `gtr cd` is implemented by the shell function that `init` generates. **Example: `git gtr new my-feature`** @@ -114,14 +114,20 @@ cmd_editor() → resolve_target() → load_editor_adapter() → editor_open() **`init` command**: Outputs shell functions for `gtr cd ` navigation. Output is cached to `~/.cache/gtr/` and auto-invalidates on version change. Users source the cache file directly in their shell rc for fast startup (see `git gtr help init`). -**`clean --merged`**: Removes worktrees whose PRs/MRs are merged. Auto-detects GitHub (`gh`) or GitLab (`glab`) from the `origin` remote URL. Override with `gtr.provider` config for self-hosted instances. +**`clean --merged` / `clean --closed`**: Removes worktrees whose PRs/MRs are merged or closed and deletes their branches. Auto-detects GitHub (`gh`) or GitLab (`glab`) from the `origin` remote URL. Override with `gtr.provider` config for self-hosted instances. `clean` also unlocks and prunes locked registry entries whose directories no longer exist. + +**`pr `** (lib/commands/pr.sh): Creates a worktree from a GitHub pull request via `gh`. Uses `gh pr checkout --worktree` when the installed `gh` supports it, otherwise fetches `refs/pull//head` through a compatibility path. + +**`new --porcelain`**: Emits exactly three `keyvalue` records (`path`, `branch`, `hook_status`) on stdout with everything else on stderr. Contract documented in `docs/agent-usage.md`; keep it stable. + +**Sparse-checkout inheritance** (`gtr.sparse.inherit`, default on): On Git 2.36+, `new` copies the base worktree's sparse-checkout patterns instead of materializing a full tree. `--sparse`/`--no-sparse` override per invocation. ## Common Development Tasks ### Adding a New Command 1. Create `lib/commands/.sh` with `cmd_()` function -2. Add case entry in `main()` dispatcher in `bin/gtr` +2. Add case entry in `main()` dispatcher in `bin/git-gtr` 3. Add help text in `lib/commands/help.sh` 4. Update all three completion files: `completions/gtr.bash`, `completions/_git-gtr`, `completions/git-gtr.fish` 5. Update README.md @@ -171,10 +177,15 @@ All config uses `gtr.*` prefix via `git config`. Key settings: - `gtr.worktrees.dir` — Base directory (default: `-worktrees` sibling) - `gtr.worktrees.prefix` — Folder prefix (default: `""`) +- `gtr.defaultBranch` / `gtr.defaultRemote` — Base branch (default: auto-detect) and remote (default: `origin`) for new worktrees +- `gtr.sparse.inherit` — Inherit sparse-checkout from the base worktree on Git 2.36+ (default: `true`) +- `gtr.provider` — Force `github` or `gitlab` for `clean --merged/--closed` (default: detect from `origin` URL) - `gtr.editor.default` / `gtr.ai.default` — Default editor/AI tool - `gtr.copy.include` / `gtr.copy.exclude` — File glob patterns (multi-valued, use `--add`) - `gtr.copy.includeDirs` / `gtr.copy.excludeDirs` — Directory patterns (multi-valued) -- `gtr.hook.postCreate` / `gtr.hook.preRemove` / `gtr.hook.postRemove` — Hook commands (multi-valued) +- `gtr.hook.postCreate` / `gtr.hook.preRemove` / `gtr.hook.postRemove` / `gtr.hook.postCd` — Hook commands (multi-valued; `postCd` runs in the current shell after `gtr cd`, `gtr new --cd`, or `gtr pr --cd`) + +Every `cfg_default` key also has an environment-variable fallback (for example `GTR_WORKTREES_DIR`, `GTR_DEFAULT_BRANCH`); the full table is in `docs/configuration.md`. Hook env vars: `REPO_ROOT`, `WORKTREE_PATH`, `BRANCH`. preRemove hooks run with cwd in worktree; failure aborts removal unless `--force`. @@ -182,6 +193,7 @@ Hook env vars: `REPO_ROOT`, `WORKTREE_PATH`, `BRANCH`. preRemove hooks run with ```bash bash -x ./bin/gtr # Full trace +GTR_DEBUG=1 ./bin/gtr # Print file:line:function on set -e failures declare -f function_name # Check function definition echo "Debug: var=$var" >&2 # Inspect variable ./bin/gtr doctor # Health check @@ -195,3 +207,5 @@ echo "Debug: var=$var" >&2 # Inspect variable - `.github/instructions/*.instructions.md` — File-pattern-specific guidance (testing, shell conventions, lib modifications, adapter contracts, completions) - `docs/configuration.md` — Complete configuration reference - `docs/advanced-usage.md` — Advanced workflows +- `docs/agent-usage.md` — `--porcelain` output contract and safety boundaries for coding agents +- `docs/troubleshooting.md` — Common failures and fixes diff --git a/README.md b/README.md index 0d28408..c7b88f8 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ - [Shell Completions](#shell-completions-optional) - [Platform Support](#platform-support) - [Contributing](#contributing) +- [Maintainers](#maintainers) - [License](#license) --- @@ -193,6 +194,8 @@ git gtr new agent-task --porcelain - `--no-copy`: Skip file copying - `--no-fetch`: Skip git fetch - `--no-hooks`: Skip post-create hooks +- `--sparse`: Inherit sparse-checkout from the base worktree (Git 2.36+; overrides `gtr.sparse.inherit = false`) +- `--no-sparse`: Force a full checkout even when `gtr.sparse.inherit` is on - `--force`: Allow same branch in multiple worktrees (**requires --name or --folder**) - `--name `: Custom folder name suffix (optional, required with --force) - `--folder `: Custom folder name (replaces default, useful for long branch names) diff --git a/docs/agent-usage.md b/docs/agent-usage.md index 3ecc36c..89a7705 100644 --- a/docs/agent-usage.md +++ b/docs/agent-usage.md @@ -36,6 +36,24 @@ Progress messages, warnings, and hook output go to stderr. `--porcelain` implies A non-zero exit means creation or a post-create hook failed. No success records are emitted in that case. +## Restricting side effects + +`--porcelain` only changes output and prompting. Repository setup still runs: +configured file copying (`gtr.copy.*`), trusted post-create hooks, and a +`git fetch` before creation. Automation that wants a bare worktree can disable +each of these explicitly: + +```bash +# No hooks, no file copying +git gtr new agent/my-task --porcelain --no-hooks --no-copy + +# Also skip the network round-trip +git gtr new agent/my-task --porcelain --no-hooks --no-copy --no-fetch +``` + +With `--no-hooks`, `hook_status` is always `disabled`. The trust model still +applies without it: `.gtrconfig` hooks the user has not approved never run. + ## Recommended agent lifecycle 1. Inspect existing worktrees with `git gtr list --porcelain`. diff --git a/docs/configuration.md b/docs/configuration.md index 3af9a44..48f71af 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -499,18 +499,24 @@ git gtr config set gtr.defaultRemote upstream --global ## Environment Variables -| Variable | Description | Default | -| --------------------- | -------------------------------------------------------------------- | -------------------------- | -| `GTR_DIR` | Override script directory location | Auto-detected | -| `GTR_WORKTREES_DIR` | Override base worktrees directory | `gtr.worktrees.dir` config | -| `GTR_EDITOR_CMD` | Custom editor command (e.g., `emacs`) | None | -| `GTR_EDITOR_CMD_NAME` | First word of `GTR_EDITOR_CMD` for availability checks | None | -| `GTR_AI_CMD` | Custom AI tool command (e.g., `copilot`) | None | -| `GTR_AI_CMD_NAME` | First word of `GTR_AI_CMD` for availability checks | None | -| `GTR_DEFAULT_REMOTE` | Remote used for default base refs and tracking | `origin` | -| `GTR_COLOR` | Override color output (`always`, `never`, `auto`) | `auto` | -| `GTR_PROVIDER` | Override hosting provider (`github` or `gitlab`) | Auto-detected from URL | -| `NO_COLOR` | Disable color output when set ([no-color.org](https://no-color.org)) | Unset | +Environment variables sit below every `git config` and `.gtrconfig` source in the precedence order, so they act as fallbacks when no matching `gtr.*` key is set. + +| Variable | Description | Default | +| ---------------------- | -------------------------------------------------------------------- | ---------------------------------------- | +| `GTR_DIR` | Override script directory location | Auto-detected | +| `GTR_WORKTREES_DIR` | Override base worktrees directory | `gtr.worktrees.dir` config | +| `GTR_WORKTREES_PREFIX` | Folder name prefix for new worktrees | `gtr.worktrees.prefix` config | +| `GTR_DEFAULT_BRANCH` | Base branch for new worktrees | `gtr.defaultBranch` config (auto-detect) | +| `GTR_EDITOR_DEFAULT` | Default editor adapter | `gtr.editor.default` config | +| `GTR_AI_DEFAULT` | Default AI tool adapter | `gtr.ai.default` config | +| `GTR_EDITOR_CMD` | Custom editor command (e.g., `emacs`) | None | +| `GTR_EDITOR_CMD_NAME` | First word of `GTR_EDITOR_CMD` for availability checks | None | +| `GTR_AI_CMD` | Custom AI tool command (e.g., `copilot`) | None | +| `GTR_AI_CMD_NAME` | First word of `GTR_AI_CMD` for availability checks | None | +| `GTR_DEFAULT_REMOTE` | Remote used for default base refs and tracking | `origin` | +| `GTR_COLOR` | Override color output (`always`, `never`, `auto`) | `auto` | +| `GTR_PROVIDER` | Override hosting provider (`github` or `gitlab`) | Auto-detected from URL | +| `NO_COLOR` | Disable color output when set ([no-color.org](https://no-color.org)) | Unset | **Hook environment variables** (available in hook scripts): diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index fccf237..21a6553 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -231,8 +231,9 @@ git-worktree-runner/ If you're still having issues: 1. Run `git gtr doctor` to check your setup -2. Enable debug mode: `bash -x git gtr ` -3. [Open an issue](https://github.com/coderabbitai/git-worktree-runner/issues) with: +2. Locate the failure: `GTR_DEBUG=1 git gtr ` prints `file:line:function` when an internal command fails +3. For a full trace, run the script directly: `bash -x "$(command -v git-gtr)" ` +4. [Open an issue](https://github.com/coderabbitai/git-worktree-runner/issues) with: - Your OS and version - Git version (`git --version`) - Bash version (`bash --version`) From 925df4ebb423eb249eb0f1c49c77361dbe12f213 Mon Sep 17 00:00:00 2001 From: Tom Elizaga Date: Mon, 14 Sep 2026 09:24:12 -0700 Subject: [PATCH 2/5] docs: describe completion files as generated in AGENTS.md and CLAUDE.md The completion files under completions/ are produced by scripts/generate-completions.sh and carry DO NOT EDIT headers; CI runs --check on them. Both guides still told contributors to hand-edit all three files when adding commands, flags, or adapters. --- AGENTS.md | 10 +++------- CHANGELOG.md | 2 +- CLAUDE.md | 10 +++------- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 8895cf7..c7565c5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -129,12 +129,12 @@ cmd_editor() → resolve_target() → load_editor_adapter() → editor_open() 1. Create `lib/commands/.sh` with `cmd_()` function 2. Add case entry in `main()` dispatcher in `bin/git-gtr` 3. Add help text in `lib/commands/help.sh` -4. Update all three completion files: `completions/gtr.bash`, `completions/_git-gtr`, `completions/git-gtr.fish` +4. Add the command and its flags to the `generate_bash`, `generate_zsh`, and `generate_fish` templates in `scripts/generate-completions.sh`, then run `./scripts/generate-completions.sh` (the files under `completions/` are generated; CI runs `--check`) 5. Update README.md ### Adding an Adapter -**Standard adapters** (just a command name + error message): Add an entry to `_EDITOR_REGISTRY` or `_AI_REGISTRY` in `lib/adapters.sh`. Then update: help text in `lib/commands/help.sh`, all three completions, README.md. +**Standard adapters** (just a command name + error message): Add an entry to `_EDITOR_REGISTRY` or `_AI_REGISTRY` in `lib/adapters.sh`. Then update help text in `lib/commands/help.sh` and README.md, and run `./scripts/generate-completions.sh` (registry names feed the completions automatically). **Custom adapters** (special logic needed): Create `adapters/{editor,ai}/.sh` implementing the two required functions (see `adapters/ai/claude.sh` for an example). File-based adapters take priority over registry entries. @@ -144,11 +144,7 @@ Update `GTR_VERSION` in `bin/git-gtr`. ### Shell Completion Updates -When adding commands or flags, update all three files: - -- `completions/gtr.bash` (Bash) -- `completions/_git-gtr` (Zsh) -- `completions/git-gtr.fish` (Fish) +`completions/gtr.bash`, `completions/_git-gtr`, and `completions/git-gtr.fish` are generated by `scripts/generate-completions.sh` and carry a `DO NOT EDIT MANUALLY` header. Adapter names come from `_EDITOR_REGISTRY` / `_AI_REGISTRY`, config keys from `_CFG_KEY_MAP`, and commands and flags from the three `generate_*` templates inside the script. After changing any of those, run `./scripts/generate-completions.sh` and commit the result; CI fails when `--check` finds a difference. ## Critical Gotcha: `set -e` diff --git a/CHANGELOG.md b/CHANGELOG.md index a77ebf2..7b74e09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this - The README documents `--sparse`/`--no-sparse` under `git gtr new` and lists the Maintainers section in its table of contents. - `docs/agent-usage.md` explains how to suppress hooks, file copying, and fetching for bare automation worktrees. - `docs/configuration.md` lists the remaining `GTR_*` fallback variables, and `docs/troubleshooting.md` describes `GTR_DEBUG`. -- `AGENTS.md` and `CLAUDE.md` now cover the `pr` and `trust` commands, `clean --closed`, sparse-checkout inheritance, `postCd` hooks, and the current test suite layout. +- `AGENTS.md` and `CLAUDE.md` now cover the `pr` and `trust` commands, `clean --closed`, sparse-checkout inheritance, `postCd` hooks, and the current test suite layout, and describe the completion files as generated by `scripts/generate-completions.sh`. ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md index 5e93c3b..96ee048 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -129,12 +129,12 @@ cmd_editor() → resolve_target() → load_editor_adapter() → editor_open() 1. Create `lib/commands/.sh` with `cmd_()` function 2. Add case entry in `main()` dispatcher in `bin/git-gtr` 3. Add help text in `lib/commands/help.sh` -4. Update all three completion files: `completions/gtr.bash`, `completions/_git-gtr`, `completions/git-gtr.fish` +4. Add the command and its flags to the `generate_bash`, `generate_zsh`, and `generate_fish` templates in `scripts/generate-completions.sh`, then run `./scripts/generate-completions.sh` (the files under `completions/` are generated; CI runs `--check`) 5. Update README.md ### Adding an Adapter -**Standard adapters** (just a command name + error message): Add an entry to `_EDITOR_REGISTRY` or `_AI_REGISTRY` in `lib/adapters.sh`. Then update: help text in `lib/commands/help.sh`, all three completions, README.md. +**Standard adapters** (just a command name + error message): Add an entry to `_EDITOR_REGISTRY` or `_AI_REGISTRY` in `lib/adapters.sh`. Then update help text in `lib/commands/help.sh` and README.md, and run `./scripts/generate-completions.sh` (registry names feed the completions automatically). **Custom adapters** (special logic needed): Create `adapters/{editor,ai}/.sh` implementing the two required functions (see `adapters/ai/claude.sh` for an example). File-based adapters take priority over registry entries. @@ -144,11 +144,7 @@ Update `GTR_VERSION` in `bin/git-gtr`. ### Shell Completion Updates -When adding commands or flags, update all three files: - -- `completions/gtr.bash` (Bash) -- `completions/_git-gtr` (Zsh) -- `completions/git-gtr.fish` (Fish) +`completions/gtr.bash`, `completions/_git-gtr`, and `completions/git-gtr.fish` are generated by `scripts/generate-completions.sh` and carry a `DO NOT EDIT MANUALLY` header. Adapter names come from `_EDITOR_REGISTRY` / `_AI_REGISTRY`, config keys from `_CFG_KEY_MAP`, and commands and flags from the three `generate_*` templates inside the script. After changing any of those, run `./scripts/generate-completions.sh` and commit the result; CI fails when `--check` finds a difference. ## Critical Gotcha: `set -e` From 8e550cb826899b62233d706af0790e0ecf004f3c Mon Sep 17 00:00:00 2001 From: Tom Elizaga Date: Mon, 14 Sep 2026 11:06:34 -0700 Subject: [PATCH 3/5] Address PR review: postCd dispatch, env precedence, example branches, entry-point diagram - AGENTS.md/CLAUDE.md: postCd hooks run through run_hooks_export (from lib/launch.sh and lib/commands/ai.sh) and the init-generated shell functions, not run_hooks_in; postRemove uses run_hooks - docs/configuration.md: limit the fallback-precedence statement to the cfg_default-backed variables; GTR_DIR, GTR_EDITOR_CMD, GTR_AI_CMD, GTR_COLOR and NO_COLOR are read directly - docs/agent-usage.md: side-effect examples use distinct branch names so they can be run in sequence - docs/troubleshooting.md: bin/git-gtr is the entry point and bin/gtr the wrapper; list the remaining lib modules in the architecture diagram --- AGENTS.md | 28 +++++++++++++++------------- CLAUDE.md | 28 +++++++++++++++------------- docs/agent-usage.md | 8 ++++---- docs/configuration.md | 2 +- docs/troubleshooting.md | 11 ++++++++--- 5 files changed, 43 insertions(+), 34 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c7565c5..4f1b79c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -50,22 +50,24 @@ mkdir -p /tmp/gtr-test && cd /tmp/gtr-test && git init && git commit --allow-emp ### Module Structure -| File | Purpose | -| ------------------- | ----------------------------------------------------------------------------------------------------------- | -| `lib/ui.sh` | Logging (`log_error`, `log_info`, `log_warn`), prompts, formatting | -| `lib/args.sh` | Shared argument parser: flag specs (`--flag`, `--flag: val`, aliases), populates `_arg_*` vars | -| `lib/config.sh` | Git config wrapper with precedence: `cfg_get`, `cfg_default`, `cfg_get_all` | -| `lib/platform.sh` | OS detection, GUI helpers | -| `lib/core.sh` | Worktree CRUD: `create_worktree`, `remove_worktree`, `list_worktrees`, `resolve_target`, `resolve_base_dir` | -| `lib/copy.sh` | File/directory copying with glob patterns: `copy_patterns`, `copy_directories` | -| `lib/hooks.sh` | Hook execution: `run_hooks_in` for postCreate/preRemove/postRemove/postCd | -| `lib/provider.sh` | Remote hosting detection (GitHub/GitLab) and CLI integration for `clean --merged/--closed` | -| `lib/adapters.sh` | Adapter registry, builder functions, generic fallbacks, loader functions | -| `lib/launch.sh` | Editor/AI launch orchestration: `_open_editor`, `_auto_launch_editor`, `_auto_launch_ai` | -| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, `cmd_pr`, `cmd_trust`, etc. (18 files) | +| File | Purpose | +| ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `lib/ui.sh` | Logging (`log_error`, `log_info`, `log_warn`), prompts, formatting | +| `lib/args.sh` | Shared argument parser: flag specs (`--flag`, `--flag: val`, aliases), populates `_arg_*` vars | +| `lib/config.sh` | Git config wrapper with precedence: `cfg_get`, `cfg_default`, `cfg_get_all` | +| `lib/platform.sh` | OS detection, GUI helpers | +| `lib/core.sh` | Worktree CRUD: `create_worktree`, `remove_worktree`, `list_worktrees`, `resolve_target`, `resolve_base_dir` | +| `lib/copy.sh` | File/directory copying with glob patterns: `copy_patterns`, `copy_directories` | +| `lib/hooks.sh` | Hook execution: `run_hooks_in`/`run_hooks` for postCreate, preRemove, postRemove; `run_hooks_export` for postCd (see below) | +| `lib/provider.sh` | Remote hosting detection (GitHub/GitLab) and CLI integration for `clean --merged/--closed` | +| `lib/adapters.sh` | Adapter registry, builder functions, generic fallbacks, loader functions | +| `lib/launch.sh` | Editor/AI launch orchestration: `_open_editor`, `_auto_launch_editor`, `_auto_launch_ai` | +| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, `cmd_pr`, `cmd_trust`, etc. (18 files) | Libraries are sourced in the order listed above (ui → args → config → ... → launch → commands/\*.sh glob). +`postCd` hooks have two dispatch paths, neither of which is `run_hooks_in`: `run_hooks_export`, called inside a subshell from `lib/launch.sh` and `lib/commands/ai.sh` so that environment changes made by the hooks reach the launched editor or AI tool, and the `gtr cd` shell functions generated by `init`, which read `gtr.hook.postCd` (plus `.gtrconfig` `hooks.postCd`) and `eval` each hook directly in the user's shell. + ### Adapters Most adapters are defined declaratively in the **adapter registry** (`lib/adapters.sh`) using pipe-delimited entries. Custom adapters that need special logic remain as override files in `adapters/editor/` and `adapters/ai/`. diff --git a/CLAUDE.md b/CLAUDE.md index 96ee048..16b11e8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -50,22 +50,24 @@ mkdir -p /tmp/gtr-test && cd /tmp/gtr-test && git init && git commit --allow-emp ### Module Structure -| File | Purpose | -| ------------------- | ----------------------------------------------------------------------------------------------------------- | -| `lib/ui.sh` | Logging (`log_error`, `log_info`, `log_warn`), prompts, formatting | -| `lib/args.sh` | Shared argument parser: flag specs (`--flag`, `--flag: val`, aliases), populates `_arg_*` vars | -| `lib/config.sh` | Git config wrapper with precedence: `cfg_get`, `cfg_default`, `cfg_get_all` | -| `lib/platform.sh` | OS detection, GUI helpers | -| `lib/core.sh` | Worktree CRUD: `create_worktree`, `remove_worktree`, `list_worktrees`, `resolve_target`, `resolve_base_dir` | -| `lib/copy.sh` | File/directory copying with glob patterns: `copy_patterns`, `copy_directories` | -| `lib/hooks.sh` | Hook execution: `run_hooks_in` for postCreate/preRemove/postRemove/postCd | -| `lib/provider.sh` | Remote hosting detection (GitHub/GitLab) and CLI integration for `clean --merged/--closed` | -| `lib/adapters.sh` | Adapter registry, builder functions, generic fallbacks, loader functions | -| `lib/launch.sh` | Editor/AI launch orchestration: `_open_editor`, `_auto_launch_editor`, `_auto_launch_ai` | -| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, `cmd_pr`, `cmd_trust`, etc. (18 files) | +| File | Purpose | +| ------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `lib/ui.sh` | Logging (`log_error`, `log_info`, `log_warn`), prompts, formatting | +| `lib/args.sh` | Shared argument parser: flag specs (`--flag`, `--flag: val`, aliases), populates `_arg_*` vars | +| `lib/config.sh` | Git config wrapper with precedence: `cfg_get`, `cfg_default`, `cfg_get_all` | +| `lib/platform.sh` | OS detection, GUI helpers | +| `lib/core.sh` | Worktree CRUD: `create_worktree`, `remove_worktree`, `list_worktrees`, `resolve_target`, `resolve_base_dir` | +| `lib/copy.sh` | File/directory copying with glob patterns: `copy_patterns`, `copy_directories` | +| `lib/hooks.sh` | Hook execution: `run_hooks_in`/`run_hooks` for postCreate, preRemove, postRemove; `run_hooks_export` for postCd (see below) | +| `lib/provider.sh` | Remote hosting detection (GitHub/GitLab) and CLI integration for `clean --merged/--closed` | +| `lib/adapters.sh` | Adapter registry, builder functions, generic fallbacks, loader functions | +| `lib/launch.sh` | Editor/AI launch orchestration: `_open_editor`, `_auto_launch_editor`, `_auto_launch_ai` | +| `lib/commands/*.sh` | One file per subcommand: `cmd_create`, `cmd_remove`, `cmd_pr`, `cmd_trust`, etc. (18 files) | Libraries are sourced in the order listed above (ui → args → config → ... → launch → commands/\*.sh glob). +`postCd` hooks have two dispatch paths, neither of which is `run_hooks_in`: `run_hooks_export`, called inside a subshell from `lib/launch.sh` and `lib/commands/ai.sh` so that environment changes made by the hooks reach the launched editor or AI tool, and the `gtr cd` shell functions generated by `init`, which read `gtr.hook.postCd` (plus `.gtrconfig` `hooks.postCd`) and `eval` each hook directly in the user's shell. + ### Adapters Most adapters are defined declaratively in the **adapter registry** (`lib/adapters.sh`) using pipe-delimited entries. Custom adapters that need special logic remain as override files in `adapters/editor/` and `adapters/ai/`. diff --git a/docs/agent-usage.md b/docs/agent-usage.md index 89a7705..3e43f29 100644 --- a/docs/agent-usage.md +++ b/docs/agent-usage.md @@ -44,11 +44,11 @@ configured file copying (`gtr.copy.*`), trusted post-create hooks, and a each of these explicitly: ```bash -# No hooks, no file copying -git gtr new agent/my-task --porcelain --no-hooks --no-copy +# Option 1: no hooks, no file copying +git gtr new agent/bare-task --porcelain --no-hooks --no-copy -# Also skip the network round-trip -git gtr new agent/my-task --porcelain --no-hooks --no-copy --no-fetch +# Option 2: additionally skip the network round-trip +git gtr new agent/offline-task --porcelain --no-hooks --no-copy --no-fetch ``` With `--no-hooks`, `hook_status` is always `disabled`. The trust model still diff --git a/docs/configuration.md b/docs/configuration.md index 48f71af..4f6211f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -499,7 +499,7 @@ git gtr config set gtr.defaultRemote upstream --global ## Environment Variables -Environment variables sit below every `git config` and `.gtrconfig` source in the precedence order, so they act as fallbacks when no matching `gtr.*` key is set. +For the variables that back a `gtr.*` key (`GTR_WORKTREES_DIR`, `GTR_WORKTREES_PREFIX`, `GTR_DEFAULT_BRANCH`, `GTR_DEFAULT_REMOTE`, `GTR_EDITOR_DEFAULT`, `GTR_AI_DEFAULT`, `GTR_PROVIDER`), the environment value is used only when no `git config` or `.gtrconfig` source sets that key. The other variables are read directly and are not part of that order: `GTR_DIR` is resolved before any configuration loads, `GTR_EDITOR_CMD` and `GTR_AI_CMD` are consumed by the adapter loader, `GTR_COLOR` sets the initial color mode but a `gtr.ui.color` value of `always` or `never` replaces it, and `NO_COLOR` disables color regardless of any other setting. | Variable | Description | Default | | ---------------------- | -------------------------------------------------------------------- | ---------------------------------------- | diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 21a6553..7843e6b 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -164,15 +164,20 @@ git gtr config get gtr.copy.exclude ``` git-worktree-runner/ ├── bin/ -│ ├── git-gtr # Git subcommand entry point (wrapper) -│ └── gtr # Entry point (~105 lines, sources lib/*.sh) +│ ├── git-gtr # Entry point: sources lib/*.sh, dispatches commands +│ └── gtr # Development wrapper (exec bin/git-gtr) ├── lib/ # Core libraries │ ├── core.sh # Git worktree operations │ ├── config.sh # Configuration management │ ├── platform.sh # OS-specific code │ ├── ui.sh # User interface │ ├── copy.sh # File copying -│ └── hooks.sh # Hook execution +│ ├── hooks.sh # Hook execution +│ ├── args.sh # Argument parsing +│ ├── provider.sh # GitHub/GitLab detection +│ ├── adapters.sh # Editor & AI adapter registry +│ ├── launch.sh # Editor & AI launching +│ └── commands/ # One file per subcommand ├── adapters/ # Editor & AI tool plugins │ ├── editor/ │ └── ai/ From 46402fd5a9be70fd7fed7abecd6f6b93d37a9811 Mon Sep 17 00:00:00 2001 From: Tom Elizaga Date: Mon, 14 Sep 2026 11:10:37 -0700 Subject: [PATCH 4/5] Address PR review: record the review corrections in the changelog The Unreleased entry did not mention two changes this PR now makes: the environment-variable precedence split in docs/configuration.md and the corrected entry-point diagram in docs/troubleshooting.md, plus the postCd dispatch correction in the agent guides. --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b74e09..34b99eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this - The README documents `--sparse`/`--no-sparse` under `git gtr new` and lists the Maintainers section in its table of contents. - `docs/agent-usage.md` explains how to suppress hooks, file copying, and fetching for bare automation worktrees. -- `docs/configuration.md` lists the remaining `GTR_*` fallback variables, and `docs/troubleshooting.md` describes `GTR_DEBUG`. +- `docs/configuration.md` lists the remaining `GTR_*` fallback variables and now separates them from the variables read directly (`GTR_DIR`, `GTR_EDITOR_CMD`, `GTR_AI_CMD`, `GTR_COLOR`, `NO_COLOR`), which do not follow the configuration precedence order. +- `docs/troubleshooting.md` describes `GTR_DEBUG`. - `AGENTS.md` and `CLAUDE.md` now cover the `pr` and `trust` commands, `clean --closed`, sparse-checkout inheritance, `postCd` hooks, and the current test suite layout, and describe the completion files as generated by `scripts/generate-completions.sh`. ### Fixed - `AGENTS.md` referenced a nonexistent `adapters/ai/Codex.sh`; it now points at `adapters/ai/claude.sh`. +- The architecture diagram in `docs/troubleshooting.md` described `bin/git-gtr` as a wrapper around `bin/gtr`; the roles are reversed and the remaining `lib/` modules are listed. +- `AGENTS.md` and `CLAUDE.md` attributed `postCd` hooks to `run_hooks_in`; they now describe `run_hooks_export` and the `init`-generated shell functions. ## [2.11.0] - 2026-08-19 From 95f1cba0ab58a0248247fb0b334cba89fbf5333b Mon Sep 17 00:00:00 2001 From: Tom Elizaga Date: Mon, 14 Sep 2026 11:21:14 -0700 Subject: [PATCH 5/5] Correct the GTR_DEBUG and postCd claims this PR introduced An independent verification pass against the code disproved two assertions added here: - GTR_DEBUG does not print file:line:function. bin/git-gtr installs an ERR trap but uses `set -e` without `set -E`, so the trap is not inherited by functions and never fires for failures inside cmd_* handlers. Confirmed with a minimal repro, which stays silent under `set -e` and fires under `set -eE`, and against the real binary. The troubleshooting step is now a trace of the real script, and the agent guides note the limitation. - postCd hooks reach the AI tool only. Both run_hooks_export call sites are AI paths; _auto_launch_editor, _open_editor and cmd_editor run no hooks. --- AGENTS.md | 5 +++-- CHANGELOG.md | 4 ++-- CLAUDE.md | 5 +++-- docs/troubleshooting.md | 5 ++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 4f1b79c..37e9e42 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -66,7 +66,7 @@ mkdir -p /tmp/gtr-test && cd /tmp/gtr-test && git init && git commit --allow-emp Libraries are sourced in the order listed above (ui → args → config → ... → launch → commands/\*.sh glob). -`postCd` hooks have two dispatch paths, neither of which is `run_hooks_in`: `run_hooks_export`, called inside a subshell from `lib/launch.sh` and `lib/commands/ai.sh` so that environment changes made by the hooks reach the launched editor or AI tool, and the `gtr cd` shell functions generated by `init`, which read `gtr.hook.postCd` (plus `.gtrconfig` `hooks.postCd`) and `eval` each hook directly in the user's shell. +`postCd` hooks have two dispatch paths, neither of which is `run_hooks_in`: `run_hooks_export`, called inside a subshell from `lib/launch.sh` and `lib/commands/ai.sh` so that environment changes made by the hooks reach the AI tool launched in that same subshell (the editor paths run no postCd hooks), and the `gtr cd` shell functions generated by `init`, which read `gtr.hook.postCd` (plus `.gtrconfig` `hooks.postCd`) and `eval` each hook directly in the user's shell. ### Adapters @@ -191,7 +191,8 @@ Hook env vars: `REPO_ROOT`, `WORKTREE_PATH`, `BRANCH`. preRemove hooks run with ```bash bash -x ./bin/gtr # Full trace -GTR_DEBUG=1 ./bin/gtr # Print file:line:function on set -e failures +# GTR_DEBUG=1 installs an ERR trap, but bin/git-gtr sets `set -e` without +# `set -E`, so it does not fire for failures inside functions. Use bash -x. declare -f function_name # Check function definition echo "Debug: var=$var" >&2 # Inspect variable ./bin/gtr doctor # Health check diff --git a/CHANGELOG.md b/CHANGELOG.md index 34b99eb..51ae590 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,14 +11,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this - The README documents `--sparse`/`--no-sparse` under `git gtr new` and lists the Maintainers section in its table of contents. - `docs/agent-usage.md` explains how to suppress hooks, file copying, and fetching for bare automation worktrees. - `docs/configuration.md` lists the remaining `GTR_*` fallback variables and now separates them from the variables read directly (`GTR_DIR`, `GTR_EDITOR_CMD`, `GTR_AI_CMD`, `GTR_COLOR`, `NO_COLOR`), which do not follow the configuration precedence order. -- `docs/troubleshooting.md` describes `GTR_DEBUG`. +- `docs/troubleshooting.md` replaces a `bash -x git gtr` instruction that cannot work with a trace of the real script. - `AGENTS.md` and `CLAUDE.md` now cover the `pr` and `trust` commands, `clean --closed`, sparse-checkout inheritance, `postCd` hooks, and the current test suite layout, and describe the completion files as generated by `scripts/generate-completions.sh`. ### Fixed - `AGENTS.md` referenced a nonexistent `adapters/ai/Codex.sh`; it now points at `adapters/ai/claude.sh`. - The architecture diagram in `docs/troubleshooting.md` described `bin/git-gtr` as a wrapper around `bin/gtr`; the roles are reversed and the remaining `lib/` modules are listed. -- `AGENTS.md` and `CLAUDE.md` attributed `postCd` hooks to `run_hooks_in`; they now describe `run_hooks_export` and the `init`-generated shell functions. +- `AGENTS.md` and `CLAUDE.md` attributed `postCd` hooks to `run_hooks_in`; they now describe `run_hooks_export` and the `init`-generated shell functions, and note that only the AI-tool path runs them. ## [2.11.0] - 2026-08-19 diff --git a/CLAUDE.md b/CLAUDE.md index 16b11e8..31b7893 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -66,7 +66,7 @@ mkdir -p /tmp/gtr-test && cd /tmp/gtr-test && git init && git commit --allow-emp Libraries are sourced in the order listed above (ui → args → config → ... → launch → commands/\*.sh glob). -`postCd` hooks have two dispatch paths, neither of which is `run_hooks_in`: `run_hooks_export`, called inside a subshell from `lib/launch.sh` and `lib/commands/ai.sh` so that environment changes made by the hooks reach the launched editor or AI tool, and the `gtr cd` shell functions generated by `init`, which read `gtr.hook.postCd` (plus `.gtrconfig` `hooks.postCd`) and `eval` each hook directly in the user's shell. +`postCd` hooks have two dispatch paths, neither of which is `run_hooks_in`: `run_hooks_export`, called inside a subshell from `lib/launch.sh` and `lib/commands/ai.sh` so that environment changes made by the hooks reach the AI tool launched in that same subshell (the editor paths run no postCd hooks), and the `gtr cd` shell functions generated by `init`, which read `gtr.hook.postCd` (plus `.gtrconfig` `hooks.postCd`) and `eval` each hook directly in the user's shell. ### Adapters @@ -191,7 +191,8 @@ Hook env vars: `REPO_ROOT`, `WORKTREE_PATH`, `BRANCH`. preRemove hooks run with ```bash bash -x ./bin/gtr # Full trace -GTR_DEBUG=1 ./bin/gtr # Print file:line:function on set -e failures +# GTR_DEBUG=1 installs an ERR trap, but bin/git-gtr sets `set -e` without +# `set -E`, so it does not fire for failures inside functions. Use bash -x. declare -f function_name # Check function definition echo "Debug: var=$var" >&2 # Inspect variable ./bin/gtr doctor # Health check diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 7843e6b..7a3ca9c 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -236,9 +236,8 @@ git-worktree-runner/ If you're still having issues: 1. Run `git gtr doctor` to check your setup -2. Locate the failure: `GTR_DEBUG=1 git gtr ` prints `file:line:function` when an internal command fails -3. For a full trace, run the script directly: `bash -x "$(command -v git-gtr)" ` -4. [Open an issue](https://github.com/coderabbitai/git-worktree-runner/issues) with: +2. Get a full trace by running the script directly: `bash -x "$(command -v git-gtr)" ` +3. [Open an issue](https://github.com/coderabbitai/git-worktree-runner/issues) with: - Your OS and version - Git version (`git --version`) - Bash version (`bash --version`)