From 4d81f4113e559cfb7c99eea92e2e3170e044ac74 Mon Sep 17 00:00:00 2001 From: him0 Date: Tue, 25 Nov 2025 15:12:27 +0900 Subject: [PATCH 1/3] feat: add .worktreeinclude file support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for reading glob patterns from a `.worktreeinclude` file in the repository root, similar to Claude Code's implementation. This feature allows users to commit file copy patterns to the repository instead of requiring each developer to configure `gtr.copy.include` manually. Features: - `.gitignore`-style syntax (# for comments, empty lines ignored) - Patterns are merged with `gtr.copy.include` config (both sources used) - File is optional - missing file is silently ignored Implementation: - Add `parse_pattern_file()` function in lib/copy.sh - Read and merge patterns in cmd_create() in bin/gtr 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CLAUDE.md | 10 ++++++++++ README.md | 15 +++++++++++++++ bin/gtr | 14 +++++++++++++- lib/copy.sh | 14 ++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 09d159b..e2b1819 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -133,6 +133,15 @@ git config --add gtr.copy.exclude "**/.env" ./bin/gtr new test-copy # Expected: Copies .env.example but not .env +# Test .worktreeinclude file +echo -e "# Test patterns\n**/.env.example\n*.md" > .worktreeinclude +echo "TEST=value" > .env.example +./bin/gtr new test-worktreeinclude +# Expected: Copies .env.example and *.md files to worktree +ls "$(./bin/gtr go test-worktreeinclude)/.env.example" +./bin/gtr rm test-worktreeinclude +rm .worktreeinclude .env.example + # Test directory copying with include/exclude patterns git config --add gtr.copy.includeDirs "node_modules" git config --add gtr.copy.excludeDirs "node_modules/.cache" @@ -402,6 +411,7 @@ All config keys use `gtr.*` prefix and are managed via `git config`: - `gtr.ai.default`: Default AI tool (aider, claude, codex, etc.) - `gtr.copy.include`: Multi-valued glob patterns for files to copy - `gtr.copy.exclude`: Multi-valued glob patterns for files to exclude +- `.worktreeinclude`: File in repo root with glob patterns (merged with `gtr.copy.include`) - `gtr.copy.includeDirs`: Multi-valued directory patterns to copy (e.g., "node_modules", ".venv", "vendor") - `gtr.copy.excludeDirs`: Multi-valued directory patterns to exclude when copying (supports globs like "node_modules/.cache", "\*/.cache") - `gtr.hook.postCreate`: Multi-valued commands to run after creating worktree diff --git a/README.md b/README.md index ce8518b..45f6652 100644 --- a/README.md +++ b/README.md @@ -369,6 +369,21 @@ git gtr config add gtr.copy.exclude "**/.env" git gtr config add gtr.copy.exclude "**/secrets.*" ``` +#### Using .worktreeinclude file + +Alternatively, create a `.worktreeinclude` file in your repository root: + +``` +# .worktreeinclude - files to copy to new worktrees +# Comments start with # + +**/.env.example +**/CLAUDE.md +*.config.js +``` + +The file uses `.gitignore`-style syntax (one pattern per line, `#` for comments, empty lines ignored). Patterns from `.worktreeinclude` are merged with `gtr.copy.include` config settings - both sources are used together. + #### Security Best Practices **The key distinction:** Development secrets (test API keys, local DB passwords) are **low risk** on personal machines. Production credentials are **high risk** everywhere. diff --git a/bin/gtr b/bin/gtr index cc3de6f..5bc781f 100755 --- a/bin/gtr +++ b/bin/gtr @@ -240,10 +240,22 @@ cmd_create() { # Copy files based on patterns if [ "$skip_copy" -eq 0 ]; then - local includes excludes + local includes excludes file_includes includes=$(cfg_get_all gtr.copy.include) excludes=$(cfg_get_all gtr.copy.exclude) + # Read .worktreeinclude file if exists + file_includes=$(parse_pattern_file "$repo_root/.worktreeinclude") + + # Merge patterns (newline-separated) + if [ -n "$file_includes" ]; then + if [ -n "$includes" ]; then + includes="$includes"$'\n'"$file_includes" + else + includes="$file_includes" + fi + fi + if [ -n "$includes" ]; then log_step "Copying files..." copy_patterns "$repo_root" "$worktree_path" "$includes" "$excludes" diff --git a/lib/copy.sh b/lib/copy.sh index 35bf626..2d89222 100644 --- a/lib/copy.sh +++ b/lib/copy.sh @@ -1,6 +1,20 @@ #!/usr/bin/env bash # File copying utilities with pattern matching +# Parse .gitignore-style pattern file +# Usage: parse_pattern_file file_path +# Returns: newline-separated patterns (comments and empty lines stripped) +parse_pattern_file() { + local file_path="$1" + + if [ ! -f "$file_path" ]; then + return 0 + fi + + # Read file, strip comments and empty lines + grep -v '^#' "$file_path" 2>/dev/null | grep -v '^[[:space:]]*$' || true +} + # Copy files matching patterns from source to destination # Usage: copy_patterns src_root dst_root includes excludes [preserve_paths] # includes: newline-separated glob patterns to include From 126641fa72377f2ec8d641c5444dfd6115ff441a Mon Sep 17 00:00:00 2001 From: him0 Date: Sun, 30 Nov 2025 14:53:23 +0900 Subject: [PATCH 2/3] docs: use printf instead of echo -e for POSIX compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace echo -e with printf in the .worktreeinclude test example to ensure compatibility with POSIX shells that don't support the -e flag. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index e2b1819..1a58c30 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -134,7 +134,7 @@ git config --add gtr.copy.exclude "**/.env" # Expected: Copies .env.example but not .env # Test .worktreeinclude file -echo -e "# Test patterns\n**/.env.example\n*.md" > .worktreeinclude +printf '# Test patterns\n**/.env.example\n*.md\n' > .worktreeinclude echo "TEST=value" > .env.example ./bin/gtr new test-worktreeinclude # Expected: Copies .env.example and *.md files to worktree From c3afa0607b59388d3cdeab6587ca8bbab0059496 Mon Sep 17 00:00:00 2001 From: him0 Date: Sun, 30 Nov 2025 15:24:06 +0900 Subject: [PATCH 3/3] docs: add language specifier to code block in README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add gitignore language specifier to the .worktreeinclude example code block for proper syntax highlighting. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45f6652..c462c92 100644 --- a/README.md +++ b/README.md @@ -373,7 +373,7 @@ git gtr config add gtr.copy.exclude "**/secrets.*" Alternatively, create a `.worktreeinclude` file in your repository root: -``` +```gitignore # .worktreeinclude - files to copy to new worktrees # Comments start with #