Skip to content

Commit 15ec2e3

Browse files
authored
feat: add .worktreeinclude file support (#28)
1 parent 74a3549 commit 15ec2e3

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

CLAUDE.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ git config --add gtr.copy.exclude "**/.env"
133133
./bin/gtr new test-copy
134134
# Expected: Copies .env.example but not .env
135135

136+
# Test .worktreeinclude file
137+
printf '# Test patterns\n**/.env.example\n*.md\n' > .worktreeinclude
138+
echo "TEST=value" > .env.example
139+
./bin/gtr new test-worktreeinclude
140+
# Expected: Copies .env.example and *.md files to worktree
141+
ls "$(./bin/gtr go test-worktreeinclude)/.env.example"
142+
./bin/gtr rm test-worktreeinclude
143+
rm .worktreeinclude .env.example
144+
136145
# Test directory copying with include/exclude patterns
137146
git config --add gtr.copy.includeDirs "node_modules"
138147
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`:
402411
- `gtr.ai.default`: Default AI tool (aider, claude, codex, etc.)
403412
- `gtr.copy.include`: Multi-valued glob patterns for files to copy
404413
- `gtr.copy.exclude`: Multi-valued glob patterns for files to exclude
414+
- `.worktreeinclude`: File in repo root with glob patterns (merged with `gtr.copy.include`)
405415
- `gtr.copy.includeDirs`: Multi-valued directory patterns to copy (e.g., "node_modules", ".venv", "vendor")
406416
- `gtr.copy.excludeDirs`: Multi-valued directory patterns to exclude when copying (supports globs like "node_modules/.cache", "\*/.cache")
407417
- `gtr.hook.postCreate`: Multi-valued commands to run after creating worktree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,21 @@ git gtr config add gtr.copy.exclude "**/.env"
369369
git gtr config add gtr.copy.exclude "**/secrets.*"
370370
```
371371

372+
#### Using .worktreeinclude file
373+
374+
Alternatively, create a `.worktreeinclude` file in your repository root:
375+
376+
```gitignore
377+
# .worktreeinclude - files to copy to new worktrees
378+
# Comments start with #
379+
380+
**/.env.example
381+
**/CLAUDE.md
382+
*.config.js
383+
```
384+
385+
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.
386+
372387
#### Security Best Practices
373388

374389
**The key distinction:** Development secrets (test API keys, local DB passwords) are **low risk** on personal machines. Production credentials are **high risk** everywhere.

bin/gtr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,22 @@ cmd_create() {
240240

241241
# Copy files based on patterns
242242
if [ "$skip_copy" -eq 0 ]; then
243-
local includes excludes
243+
local includes excludes file_includes
244244
includes=$(cfg_get_all gtr.copy.include)
245245
excludes=$(cfg_get_all gtr.copy.exclude)
246246

247+
# Read .worktreeinclude file if exists
248+
file_includes=$(parse_pattern_file "$repo_root/.worktreeinclude")
249+
250+
# Merge patterns (newline-separated)
251+
if [ -n "$file_includes" ]; then
252+
if [ -n "$includes" ]; then
253+
includes="$includes"$'\n'"$file_includes"
254+
else
255+
includes="$file_includes"
256+
fi
257+
fi
258+
247259
if [ -n "$includes" ]; then
248260
log_step "Copying files..."
249261
copy_patterns "$repo_root" "$worktree_path" "$includes" "$excludes"

lib/copy.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
#!/usr/bin/env bash
22
# File copying utilities with pattern matching
33

4+
# Parse .gitignore-style pattern file
5+
# Usage: parse_pattern_file file_path
6+
# Returns: newline-separated patterns (comments and empty lines stripped)
7+
parse_pattern_file() {
8+
local file_path="$1"
9+
10+
if [ ! -f "$file_path" ]; then
11+
return 0
12+
fi
13+
14+
# Read file, strip comments and empty lines
15+
grep -v '^#' "$file_path" 2>/dev/null | grep -v '^[[:space:]]*$' || true
16+
}
17+
418
# Copy files matching patterns from source to destination
519
# Usage: copy_patterns src_root dst_root includes excludes [preserve_paths]
620
# includes: newline-separated glob patterns to include

0 commit comments

Comments
 (0)