Description
When using ** glob patterns in gtr.copy.include config, root-level files are not copied on macOS (which uses Bash 3.2 by default).
Steps to Reproduce
- macOS with default Bash 3.2
.gtrconfig:
[copy]
include = **/.env*
include = **/CLAUDE.md
- Root-level
.env and CLAUDE.md exist in the main repo
- Run
git gtr copy <worktree-name>
Expected
Root-level .env and CLAUDE.md are copied to the worktree.
Actual
==> Copying to: <branch-name>
[!] Failed to copy
[!] Failed to copy
With --dry-run:
==> [dry-run] Would copy to: <branch-name>
[OK] [dry-run] Would copy:
[OK] [dry-run] Would copy:
[OK] [dry-run] Would copy 2 file(s)
File names are empty in the output.
Root Cause
In lib/copy.sh, when Bash 3.2 doesn't support globstar, the code falls back to find:
$(find . -path "./$pattern" -type f 2>/dev/null)
For pattern **/.env*, this becomes find . -path "./**/.env*" -type f.
The problem is twofold:
-
find -path doesn't treat ** as recursive glob — it's just a regular wildcard. The pattern **/.env* requires a directory separator before .env, so it never matches root-level files like ./.env.
-
Empty results still trigger one loop iteration — when find returns nothing, the while read loop with heredoc executes once with an empty string, causing cp "" <dest> to fail.
Workaround
Use patterns without **/ prefix:
[copy]
include = .env*
include = CLAUDE.md
Suggested Fix
- For
**-prefixed patterns, also match root-level files (e.g., convert **/.env* to find . -name ".env*" -type f)
- Add an empty-string guard in the copy loop:
[ -z "$file" ] && continue
Description
When using
**glob patterns ingtr.copy.includeconfig, root-level files are not copied on macOS (which uses Bash 3.2 by default).Steps to Reproduce
.gtrconfig:.envandCLAUDE.mdexist in the main repogit gtr copy <worktree-name>Expected
Root-level
.envandCLAUDE.mdare copied to the worktree.Actual
With
--dry-run:File names are empty in the output.
Root Cause
In
lib/copy.sh, when Bash 3.2 doesn't supportglobstar, the code falls back tofind:$(find . -path "./$pattern" -type f 2>/dev/null)For pattern
**/.env*, this becomesfind . -path "./**/.env*" -type f.The problem is twofold:
find -pathdoesn't treat**as recursive glob — it's just a regular wildcard. The pattern**/.env*requires a directory separator before.env, so it never matches root-level files like./.env.Empty results still trigger one loop iteration — when
findreturns nothing, thewhile readloop with heredoc executes once with an empty string, causingcp "" <dest>to fail.Workaround
Use patterns without
**/prefix:Suggested Fix
**-prefixed patterns, also match root-level files (e.g., convert**/.env*tofind . -name ".env*" -type f)[ -z "$file" ] && continue