Skip to content

Conversation

@helizaga
Copy link
Collaborator

@helizaga helizaga commented Dec 10, 2025

  • Introduced .gtrconfig file for team-shared settings, allowing configuration to be stored alongside git config.
  • Updated configuration precedence to include .gtrconfig, detailing the order of settings resolution.
  • Enhanced functions to retrieve configuration values from both git config and .gtrconfig.
  • Added example .gtrconfig file template for user reference.

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 <branch> - Create worktree
  • git gtr go <branch> - Navigate to worktree
  • git gtr editor <branch> - Open in editor (if applicable)
  • git gtr ai <branch> - Start AI tool (if applicable)
  • git gtr rm <branch> - Remove worktree
  • git gtr list - List worktrees
  • git gtr config - Configuration commands (if applicable)
  • Other commands affected by this change: **__**

Test Steps

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
  • 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.

Summary by CodeRabbit

  • New Features

    • Repository-level .gtrconfig support for shared copy patterns, hooks, and defaults; multi-value settings merge repo + git config with deduplication.
    • Six-level configuration precedence (local, repo, global, system, environment, fallback).
    • New env vars to override directories, editor and AI command defaults.
  • Bug Fixes / Behavior

    • Hook and default lookups now consult repo config; copy include/exclude and directory-exclude handling respect repo settings.
  • Documentation

    • Expanded docs with mappings, precedence, examples, and a .gtrconfig template; AI tools table simplified.

✏️ Tip: You can customize this high-level summary in your review settings.

- Introduced .gtrconfig file for team-shared settings, allowing configuration to be stored alongside git config.
- Updated configuration precedence to include .gtrconfig, detailing the order of settings resolution.
- Enhanced functions to retrieve configuration values from both git config and .gtrconfig.
- Added example .gtrconfig file template for user reference.
@helizaga helizaga requested a review from NatoBoram as a code owner December 10, 2025 04:50
@coderabbitai
Copy link

coderabbitai bot commented Dec 10, 2025

Walkthrough

Adds repository-level configuration via an optional .gtrconfig (gitconfig format), extends configuration precedence to include it, updates config helper signatures to read .gtrconfig, adjusts CLI and hooks to pass file-specific keys, and adds a .gtrconfig example and documentation updates.

Changes

Cohort / File(s) Summary
Documentation
CLAUDE.md, README.md
Documented .gtrconfig usage, added six-level config precedence, key mappings between gtr.* and .gtrconfig, new environment variables, sample .gtrconfig, and revised AI tools table.
CLI Integration
bin/gtr
Updated config lookups to pass secondary file keys (e.g., copy.include, copy.exclude, copy.includeDirs, copy.excludeDirs, defaults.editor, defaults.ai) so values are read from .gtrconfig in addition to git config; minor help/text tweaks.
Configuration Library
lib/config.sh
Added _gtrconfig_path, cfg_get_file, cfg_get_all_file; changed cfg_get_all to cfg_get_all key [file_key] [scope]; changed cfg_default to accept optional [file_key]; implemented reading/merging from .gtrconfig with deduplication and updated precedence (local git → .gtrconfig → global/system git → env → fallback).
Hooks
lib/hooks.sh
Hook lookup now queries both git config and .gtrconfig by passing hooks.<phase> as file_key to cfg_get_all; execution behavior unchanged.
Examples / Templates
templates/.gtrconfig.example
New repository-level example showing [copy], [hooks], and [defaults] sections with include/exclude patterns, directory excludes, sample postCreate/postRemove hooks, and default editor/AI settings.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Inspect changed public function signatures in lib/config.sh (cfg_get_all, cfg_default) and ensure call sites use the new parameters correctly.
  • Verify _gtrconfig_path, cfg_get_file, and cfg_get_all_file handle missing files, parse gitconfig format reliably, and deduplicate while preserving precedence.
  • Check bin/gtr and lib/hooks.sh use consistent file_key names (e.g., hooks.<phase>, copy.include*, defaults.*) matching templates/.gtrconfig.example.
  • Review README for duplicated .gtrconfig blocks and ensure documentation examples match implemented key names.

Poem

🐇 A dot-file tucked beneath the root,
.gtrconfig hummed a quiet route.
From local, repo, global — settings blend,
Hooks and defaults hop and mend.
Teamwork sprouts where configs meet the root.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing a .gtrconfig file for declarative configuration, which is the primary feature across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/gtrconfig-file

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 560aaf7 and a9598a9.

📒 Files selected for processing (1)
  • CLAUDE.md (8 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-24T19:17:34.750Z
Learnt from: CR
Repo: coderabbitai/git-worktree-runner PR: 0
File: .github/instructions/lib.instructions.md:0-0
Timestamp: 2025-11-24T19:17:34.750Z
Learning: Applies to lib/**/*.sh : Implement Git version fallbacks (e.g., Git 2.22+ `--show-current` vs older `rev-parse`); check `lib/core.sh:97-100` for example

Applied to files:

  • CLAUDE.md
🪛 LanguageTool
CLAUDE.md

[uncategorized] ~577-~577: The official name of this software platform is spelled with a capital “H”.
Context: ...on specific areas, consult the relevant .github/instructions/*.md file for detailed gu...

(GITHUB)

🔇 Additional comments (4)
CLAUDE.md (4)

405-446: Configuration precedence and .gtrconfig mapping are well-documented.

The six-level precedence hierarchy is clearly laid out, the File-based Configuration section is comprehensive, and the Key Mapping table provides excellent clarity for developers mapping between gtr.* git config keys and their .gtrconfig equivalents.


450-457: Environment variables documentation expanded appropriately.

The additions clarify the generic adapter fallback mechanism and align with the new precedence model. The distinction between GTR_EDITOR_CMD and GTR_EDITOR_CMD_NAME is helpful for understanding command parsing.


479-481: Configuration Precedence and Multi-Value Pattern descriptions are accurate.

The documentation clearly explains cfg_default() precedence and cfg_get_all() behavior with the file_key parameter. The example mapping (copy.include for gtr.copy.include) correctly reflects the Key Mapping table.


561-575: Documentation Structure section is a helpful addition.

Organizing all project documentation and its purposes in a dedicated section will guide contributors to the right file for different contexts. The file-pattern-specific guidance cross-references are particularly valuable.


Comment @coderabbitai help to get the list of available commands and usage tips.

- Revised descriptions of binary structure and command flow for improved understanding.
- Clarified function names and their roles in the codebase.
- Enhanced documentation on configuration management and adapter loading processes.
- Added a new section outlining the documentation structure for better navigation.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
CLAUDE.md (1)

479-482: Stale description of cfg_default / cfg_get_all behavior

This paragraph still says cfg_default checks only git config (local > global > system) then env, and references old line ranges for cfg_get_all. After introducing .gtrconfig into precedence and changing signatures, this description is now inaccurate.

Recommend updating it to:

  • Mention .gtrconfig between local and global/system.
  • Reflect the new cfg_get_all key [file_key] [scope] and cfg_default key env fallback [file_key] signatures.
  • Drop hardcoded line numbers or refresh them.

This keeps CLAUDE’s internal model aligned with the current implementation.

bin/gtr (1)

897-904: cmd_config get passes scope to wrong parameter in cfg_get_all call

cfg_get_all expects (key, file_key, scope), but line 903 calls:

cfg_get_all "$key" "$scope"

This passes scope as file_key (second position), leaving scope defaulted to "auto". The --global and --local flags are ignored, and the function attempts to read a non-existent .gtrconfig key matching the scope string.

Fix:

-      cfg_get_all "$key" "$scope"
+      cfg_get_all "$key" "" "$scope"

The empty string for file_key is correct here since config get queries git config only, not .gtrconfig file entries.

🧹 Nitpick comments (1)
README.md (1)

243-280: Configuration precedence docs slightly out of sync with implementation

The README precedence list stops at global → env → defaults, but lib/config.sh and CLAUDE.md document and implement an additional git config --system layer between global and env. Consider updating this section to mention the system scope so docs fully mirror actual behavior.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2446f30 and e4bc8a0.

📒 Files selected for processing (6)
  • CLAUDE.md (3 hunks)
  • README.md (2 hunks)
  • bin/gtr (6 hunks)
  • lib/config.sh (4 hunks)
  • lib/hooks.sh (1 hunks)
  • templates/.gtrconfig.example (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
bin/gtr

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

bin/gtr: Dispatch commands through cmd_* functions in bin/gtr (case block lines 36‑77)
Update GTR_VERSION on line 8 of bin/gtr when releasing; this affects gtr version / --version output

Global set -e in bin/gtr: guard non-critical commands with || true

list --porcelain output must remain stable for scripting purposes

Update the version constant (line 8: GTR_VERSION="2.0.0") when releasing a new version

Files:

  • bin/gtr
{bin/gtr,lib/**/*.sh,adapters/**/*.sh}

📄 CodeRabbit inference engine (.github/instructions/testing.instructions.md)

{bin/gtr,lib/**/*.sh,adapters/**/*.sh}: All commands must exit 0 (except intentional failures) and produce expected side-effects
No unquoted path errors; spaces must be handled in file paths
Hooks must run only once per creation/removal event

Files:

  • bin/gtr
  • lib/hooks.sh
  • lib/config.sh
lib/**/*.sh

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

lib/**/*.sh: Core libraries (lib/core.sh, lib/config.sh, lib/ui.sh, lib/copy.sh, lib/hooks.sh, lib/platform.sh) must be sourced at startup and implement specific functionality
Maintain backwards compatibility with Git <2.22 by using fallback rev-parse --abbrev-ref HEAD instead of branch --show-current

lib/**/*.sh: Maintain backwards compatibility with existing configs in shell scripts
Quote all paths to support spaces in directory names
Use log_error / log_info from lib/ui.sh for user messages
Implement Git version fallbacks (e.g., Git 2.22+ --show-current vs older rev-parse); check lib/core.sh:97-100 for example
Add new config keys with gtr.<name> prefix to avoid collisions
For performance-sensitive loops (e.g., directory scans), prefer built-ins (find, grep) with minimal subshells
For any new Git command, add fallback for older versions or guard with detection

Files:

  • lib/hooks.sh
  • lib/config.sh
**/*.sh

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.sh: Always quote paths to handle spaces and special characters; avoid unguarded globbing
Keep set -e active in shell scripts; ensure non-critical failures are guarded with command || true

**/*.sh: Use shebang #!/usr/bin/env bash (not /bin/bash or /bin/sh) for all shell scripts
Use snake_case naming for functions and local variables, UPPER_CASE for constants and environment variables
Use 2-space indentation (no tabs) for all shell scripts
Always quote all variables and paths (e.g., "$var") in shell scripts
Check return codes and use || exit 1 or || return 1 for error handling in shell scripts

Files:

  • lib/hooks.sh
  • lib/config.sh
**/*.{bash,fish,sh}

📄 CodeRabbit inference engine (.github/instructions/sh.instructions.md)

**/*.{bash,fish,sh}: Bash 3.2+ compatible (macOS default), but 4.0+ features allowed where appropriate
Always quote variables: use "$var" not $var
Use function-scoped variables: local var="value"
Check return codes; functions return 1 on failure
Use snake_case for functions and variables, UPPER_CASE for constants
Prefer [ ] over [[ ]] for POSIX portability; use [[ only when needed
Always quote glob inputs; disable unintended globbing with set -f temporarily if required
Avoid associative arrays in shell scripts; use simple string/loop constructs for Bash 3.2+ compatibility
Avoid readarray and process substitution unsupported in older Bash
Debug with bash -x ./bin/gtr <cmd> or wrap suspicious blocks with set -x / set +x
Check function presence with declare -f create_worktree or declare -f resolve_target
Use stderr for variable inspection: echo "DEBUG var=$var" >&2 to keep stdout clean for command substitution
Keep dependencies minimal: only use git, sed, awk, find, grep; avoid jq/curl unless justified
Check availability of external commands before use when adding new tools
Use "${var}" for variable expansion; for line loops use while IFS= read -r line; do ... done to preserve spaces
Sanitize branch names via sanitize_branch_name function; do NOT duplicate logic elsewhere
Everything is sourced at startup with set -e enabled; functions call each other directly; no subshells except for hooks and AI tools

Files:

  • lib/hooks.sh
  • lib/config.sh
lib/*.sh

📄 CodeRabbit inference engine (CLAUDE.md)

lib/*.sh: Maintain backwards compatibility with existing configurations when modifying core functionality files
Follow POSIX-compatible Bash patterns targeting Bash 3.2+ in core library files
Use local for function-scoped variables in library files to prevent variable scope leakage
Provide clear error messages via log_error and log_info from lib/ui.sh in library files

Files:

  • lib/hooks.sh
  • lib/config.sh
lib/config.sh

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

For multi-value git config keys, use git config --add to merge and deduplicate values rather than overwriting the entire list

Files:

  • lib/config.sh
README.md

📄 CodeRabbit inference engine (CLAUDE.md)

Always reference git gtr in user-facing documentation (not ./bin/gtr), which is for development/testing only

Files:

  • README.md
🧬 Code graph analysis (1)
lib/hooks.sh (1)
lib/config.sh (1)
  • cfg_get_all (85-113)
🔇 Additional comments (8)
lib/hooks.sh (1)

11-14: Hook lookup correctly extended to .gtrconfig

Using cfg_get_all "gtr.hook.$phase" "hooks.$phase" cleanly merges git config and .gtrconfig hook entries while preserving existing behavior and precedence. No issues spotted.

bin/gtr (2)

241-275: Copy pattern config now correctly sources from .gtrconfig

The updated cfg_get_all calls for gtr.copy.* keys with copy.* file keys correctly merge git config and .gtrconfig values, preserving newline-separated lists and deduplication. This fits the documented precedence and keeps behavior backward compatible.


500-503: Editor/AI defaults correctly wired to .gtrconfig

cfg_default gtr.editor.default ... defaults.editor and cfg_default gtr.ai.default ... defaults.ai correctly hook up repository-level [defaults] settings in .gtrconfig while still honoring local/global git config, env, and fallbacks. The same pattern in cmd_doctor keeps diagnostics in sync.

Also applies to: 564-567, 755-758, 775-778

templates/.gtrconfig.example (1)

1-55: Example .gtrconfig aligns with implementation and key mapping

The example cleanly matches the documented mappings (copy.*, hooks.*, defaults.*) and will be correctly picked up by cfg_get_all_file/cfg_get_file. Duplicate [copy] sections are valid gitconfig and aggregate as expected.

README.md (1)

335-343: AI tools table refactor improves clarity

The new table layout (Tool / Install / Use Case / Set as Default) is consistent and makes configuring gtr.ai.default much clearer. No issues.

CLAUDE.md (1)

224-225: CLAUDE guidance correctly documents new .gtrconfig model

The updated sections on configuration storage, precedence, file-based configuration, and the .gtrconfig key mapping table align with the new cfg_default/cfg_get_all behavior and key usage in lib/config.sh and bin/gtr. This is very helpful for future changes.

Also applies to: 405-447

lib/config.sh (2)

2-59: .gtrconfig helpers and file readers are robust and set -e–safe

_gtrconfig_path, cfg_get_file, and cfg_get_all_file are implemented defensively: git lookups are guarded (2>/dev/null with || return 0 / || true), paths are quoted, and they gracefully no-op outside a repo. The comment and behavior around --git-common-dir vs --show-toplevel make the intended “main repo root” semantics clear for worktrees.


80-113: Config precedence implementation matches documented model

The updated cfg_get_all and cfg_default correctly implement:

  • Merge & dedupe order for multi-valued keys: local → .gtrconfig (via file_key) → global → system.
  • Scalar precedence for defaults: local → .gtrconfig (if file_key provided) → global/system → env (env_name) → fallback.

Signatures and behavior are consistent with README/CLAUDE docs and with how callers in bin/gtr/lib/hooks.sh use file_key.

Also applies to: 189-220

…E.md

- Clarified the order of configuration precedence, explicitly mentioning the .gtrconfig file.
- Updated README to include system defaults in the configuration hierarchy.
- Adjusted function call in gtr script to align with updated configuration retrieval logic.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
CLAUDE.md (1)

405-447: Remove or mark as planned the unimplemented configuration keys from the Git Config Keys section and Key Mapping Table.

The documented configuration keys (lines 420-446) claim support for gtr.editor.default, gtr.ai.default, and the gtr.copy.* keys, but these are not implemented in the codebase. Only gtr.defaultBranch, gtr.hook.postCreate, and gtr.hook.postRemove are actually retrieved and used via the configuration functions. The copy functionality does not retrieve these keys through cfg_get_all, and editor/AI defaults are not retrieved anywhere in the code. Either remove these keys from the documentation or mark them as planned/future features. The Key Mapping Table should be updated to reflect only the currently implemented configuration keys.

🧹 Nitpick comments (2)
CLAUDE.md (2)

432-433: Clarify .worktreeinclude deprecation timeline and migration path.

Line 433 marks .worktreeinclude as deprecated in favor of .gtrconfig, but doesn't specify:

  • When deprecation will take effect (v2.1.0, v3.0.0?)
  • Whether it will still be supported (and in what precedence order)
  • Migration guidance for users currently relying on .worktreeinclude

Consider adding a deprecation timeline and migration instructions to help users transition smoothly.


561-576: Ensure documentation structure section is discoverable and kept in sync.

The new Documentation Structure section (lines 561-576) provides valuable navigation guidance for different documentation files and their purposes. Consider:

  • Adding a similar navigation section to README.md or CONTRIBUTING.md so new contributors discover it
  • Adding inline comments in each instruction file cross-referencing the others
  • Setting up a periodic check (e.g., in CI or PR review checklists) to keep file references in sync as documentation evolves
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6f603ad and 560aaf7.

📒 Files selected for processing (3)
  • CLAUDE.md (8 hunks)
  • README.md (2 hunks)
  • bin/gtr (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • bin/gtr
  • README.md
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-24T19:17:34.750Z
Learnt from: CR
Repo: coderabbitai/git-worktree-runner PR: 0
File: .github/instructions/lib.instructions.md:0-0
Timestamp: 2025-11-24T19:17:34.750Z
Learning: Applies to lib/**/*.sh : Implement Git version fallbacks (e.g., Git 2.22+ `--show-current` vs older `rev-parse`); check `lib/core.sh:97-100` for example

Applied to files:

  • CLAUDE.md
🪛 LanguageTool
CLAUDE.md

[uncategorized] ~577-~577: The official name of this software platform is spelled with a capital “H”.
Context: ...on specific areas, consult the relevant .github/instructions/*.md file for detailed gu...

(GITHUB)

- Removed mention of deprecation for .worktreeinclude, clarifying its integration with gtr.copy.include.
@helizaga helizaga merged commit e1ad20c into main Dec 10, 2025
1 check passed
@helizaga helizaga deleted the feat/gtrconfig-file branch December 10, 2025 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants