Skip to content

Commit 9d49c4b

Browse files
authored
fix(copy): honor configured directory patterns (#173)
1 parent d182c32 commit 9d49c4b

3 files changed

Lines changed: 80 additions & 8 deletions

File tree

lib/commands/copy.sh

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,19 @@ cmd_copy() {
4343
src_path="$_ctx_worktree_path"
4444

4545
# Get patterns (flag > config + .worktreeinclude)
46-
local excludes
46+
local excludes dir_includes="" dir_excludes=""
4747
if [ -z "$patterns" ]; then
4848
merge_copy_patterns "$repo_root"
4949

5050
patterns="$_ctx_copy_includes" excludes="$_ctx_copy_excludes"
51+
dir_includes=$(cfg_get_all gtr.copy.includeDirs copy.includeDirs)
52+
dir_excludes=$(cfg_get_all gtr.copy.excludeDirs copy.excludeDirs)
5153
else
5254
excludes=$(cfg_get_all gtr.copy.exclude copy.exclude)
5355
fi
5456

55-
if [ -z "$patterns" ]; then
56-
log_error "No patterns specified. Use '-- <pattern>...' or configure gtr.copy.include"
57+
if [ -z "$patterns" ] && [ -z "$dir_includes" ]; then
58+
log_error "No patterns specified. Use '-- <pattern>...' or configure gtr.copy.include or gtr.copy.includeDirs"
5759
exit 1
5860
fi
5961

@@ -85,15 +87,17 @@ cmd_copy() {
8587

8688
if [ "$dry_run" -eq 1 ]; then
8789
log_step "[dry-run] Would copy to: $dst_branch"
88-
copy_patterns "$src_path" "$dst_path" "$patterns" "$excludes" "true" "true"
90+
[ -n "$patterns" ] && copy_patterns "$src_path" "$dst_path" "$patterns" "$excludes" "true" "true"
91+
[ -n "$dir_includes" ] && copy_directories "$src_path" "$dst_path" "$dir_includes" "$dir_excludes" "true"
8992
else
9093
log_step "Copying to: $dst_branch"
91-
copy_patterns "$src_path" "$dst_path" "$patterns" "$excludes" "true"
94+
[ -n "$patterns" ] && copy_patterns "$src_path" "$dst_path" "$patterns" "$excludes" "true"
95+
[ -n "$dir_includes" ] && copy_directories "$src_path" "$dst_path" "$dir_includes" "$dir_excludes"
9296
fi
9397
copied_any=1
9498
done
9599

96100
if [ "$copied_any" -eq 0 ]; then
97101
log_warn "No files copied (source and target may be the same)"
98102
fi
99-
}
103+
}

lib/copy.sh

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ EOF
319319
}
320320

321321
# Copy directories matching patterns (typically git-ignored directories like node_modules)
322-
# Usage: copy_directories src_root dst_root dir_patterns excludes
322+
# Usage: copy_directories src_root dst_root dir_patterns excludes [dry_run]
323323
# dir_patterns: newline-separated directory names to copy (e.g., "node_modules", ".venv")
324324
# excludes: newline-separated directory patterns to exclude (supports globs like "node_modules/.cache")
325325
# WARNING: This copies entire directories including potentially sensitive files.
@@ -329,6 +329,7 @@ copy_directories() {
329329
local dst_root="$2"
330330
local dir_patterns="$3"
331331
local excludes="$4"
332+
local dry_run="${5:-false}"
332333

333334
if [ -z "$dir_patterns" ]; then
334335
return 0
@@ -372,6 +373,13 @@ copy_directories() {
372373
local dest_dir="$dst_root/$dir_path"
373374
local dest_parent
374375
dest_parent=$(dirname "$dest_dir")
376+
377+
if [ "$dry_run" = "true" ]; then
378+
log_info "[dry-run] Would copy directory $dir_path"
379+
copied_count=$((copied_count + 1))
380+
continue
381+
fi
382+
375383
mkdir -p "$dest_parent"
376384

377385
# Copy directory using CoW when available (preserves symlinks as symlinks)
@@ -392,7 +400,11 @@ EOF
392400
cd "$old_pwd" || return 1
393401

394402
if [ "$copied_count" -gt 0 ]; then
395-
log_info "Copied $copied_count directories"
403+
if [ "$dry_run" = "true" ]; then
404+
log_info "[dry-run] Would copy $copied_count directories"
405+
else
406+
log_info "Copied $copied_count directories"
407+
fi
396408
fi
397409

398410
return 0

tests/cmd_copy.bats

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,39 @@ teardown() {
3737
[ -f "$TEST_WORKTREES_DIR/copy-target/config.json" ]
3838
}
3939

40+
@test "cmd_copy copies configured includeDirs" {
41+
mkdir -p "$TEST_REPO/.zed"
42+
echo "settings" > "$TEST_REPO/.zed/settings.json"
43+
git config --add gtr.copy.includeDirs ".zed"
44+
45+
run cmd_copy copy-target
46+
[ "$status" -eq 0 ]
47+
[ -f "$TEST_WORKTREES_DIR/copy-target/.zed/settings.json" ]
48+
}
49+
50+
@test "cmd_copy dry-run does not copy configured includeDirs" {
51+
mkdir -p "$TEST_REPO/.zed"
52+
echo "settings" > "$TEST_REPO/.zed/settings.json"
53+
git config --add gtr.copy.includeDirs ".zed"
54+
55+
run cmd_copy copy-target --dry-run
56+
[ "$status" -eq 0 ]
57+
[ ! -d "$TEST_WORKTREES_DIR/copy-target/.zed" ]
58+
}
59+
60+
@test "cmd_copy applies configured excludeDirs" {
61+
mkdir -p "$TEST_REPO/.zed/cache"
62+
echo "settings" > "$TEST_REPO/.zed/settings.json"
63+
echo "token" > "$TEST_REPO/.zed/cache/token"
64+
git config --add gtr.copy.includeDirs ".zed"
65+
git config --add gtr.copy.excludeDirs ".zed/cache"
66+
67+
run cmd_copy copy-target
68+
[ "$status" -eq 0 ]
69+
[ -f "$TEST_WORKTREES_DIR/copy-target/.zed/settings.json" ]
70+
[ ! -e "$TEST_WORKTREES_DIR/copy-target/.zed/cache/token" ]
71+
}
72+
4073
# ── --all flag ───────────────────────────────────────────────────────────────
4174

4275
@test "cmd_copy --all copies to all worktrees" {
@@ -47,6 +80,29 @@ teardown() {
4780
[ -f "$TEST_WORKTREES_DIR/copy-target-2/.env" ]
4881
}
4982

83+
@test "cmd_copy --all copies configured includeDirs to all worktrees" {
84+
create_test_worktree "copy-target-2"
85+
mkdir -p "$TEST_REPO/.zed"
86+
echo "settings" > "$TEST_REPO/.zed/settings.json"
87+
git config --add gtr.copy.includeDirs ".zed"
88+
89+
run cmd_copy --all
90+
[ "$status" -eq 0 ]
91+
[ -f "$TEST_WORKTREES_DIR/copy-target/.zed/settings.json" ]
92+
[ -f "$TEST_WORKTREES_DIR/copy-target-2/.zed/settings.json" ]
93+
}
94+
95+
@test "cmd_copy --from copies configured includeDirs from source worktree" {
96+
create_test_worktree "copy-source"
97+
mkdir -p "$TEST_WORKTREES_DIR/copy-source/.idea"
98+
echo "workspace" > "$TEST_WORKTREES_DIR/copy-source/.idea/workspace.xml"
99+
git config --add gtr.copy.includeDirs ".idea"
100+
101+
run cmd_copy copy-target --from copy-source
102+
[ "$status" -eq 0 ]
103+
[ -f "$TEST_WORKTREES_DIR/copy-target/.idea/workspace.xml" ]
104+
}
105+
50106
# ── Error cases ──────────────────────────────────────────────────────────────
51107

52108
@test "cmd_copy fails with no arguments" {

0 commit comments

Comments
 (0)