From b62f00a22013c2dad23f3b91b312d1e05ff58210 Mon Sep 17 00:00:00 2001 From: CoodingPenguin Date: Mon, 27 Apr 2026 15:09:22 +0900 Subject: [PATCH] fix: detect .worktrees/ ignore via git check-ignore --- README.ko.md | 2 +- README.md | 2 +- cwt.sh | 7 +++---- tests/cwt_new.bats | 20 ++++++++++++++++++-- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/README.ko.md b/README.ko.md index e8357de..c6a36c2 100644 --- a/README.ko.md +++ b/README.ko.md @@ -174,7 +174,7 @@ cwt new --no-launch my-task # 어시스턴트 실행 건너뛰기 ``` [fzf](https://github.com/junegunn/fzf)가 설치되어 있으면 브랜치 선택, worktree 선택, setup wizard의 위치/폴더 선택에 우선적으로 사용됩니다. 그렇지 않으면 번호 목록과 화살표 브라우저로 동작합니다. -기본 `.worktrees` 디렉토리를 사용할 때 `cwt new`는 `.gitignore`에 `.worktrees/`가 이미 있어야 하며, 파일을 자동 수정하지 않습니다. +기본 `.worktrees` 디렉토리를 사용할 때 `cwt new`는 `.worktrees/`가 이미 gitignore되어 있어야 하며(저장소 `.gitignore`, `.git/info/exclude`, 글로벌 excludes 파일 모두 가능), 어떤 파일도 자동 수정하지 않습니다. `CWT_AUTO_LAUNCH=false`일 때도 명시적 실행 플래그(`--assistant`, `--split`, `--tab`, `--launch-target`)는 어시스턴트를 실행합니다. ### worktree 목록 diff --git a/README.md b/README.md index a4dd6c6..0fb4ddd 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ cwt new --no-launch my-task # skip assistant launch ``` If [fzf](https://github.com/junegunn/fzf) is installed, cwt prefers it for branch selection, worktree picking, and setup-wizard folder/location choices. Otherwise, numbered lists and the arrow-key browser are used. -When the default `.worktrees` directory is used, `cwt new` requires `.worktrees/` to already be present in `.gitignore` and refuses to edit the file automatically. +When the default `.worktrees` directory is used, `cwt new` requires `.worktrees/` to already be gitignored (via the repo `.gitignore`, `.git/info/exclude`, or your global excludes file) and refuses to edit any file automatically. When `CWT_AUTO_LAUNCH=false`, explicit launch flags (for example `--assistant`, `--split`, `--tab`, `--launch-target`) still launch. ### List worktrees diff --git a/cwt.sh b/cwt.sh index 018fab2..0d082ad 100644 --- a/cwt.sh +++ b/cwt.sh @@ -1676,15 +1676,14 @@ _cwt_ensure_default_worktree_ignored() { local worktrees_dir="${2:-$_cwt_worktrees_dir}" [[ "$worktrees_dir" != "${git_root}/.worktrees" ]] && return 0 - local gitignore_path="${git_root}/.gitignore" local ignore_entry=".worktrees/" - if [[ -f "$gitignore_path" ]] && grep -Eq '^[[:space:]]*\.worktrees/?[[:space:]]*$' "$gitignore_path"; then + if git -C "$git_root" check-ignore -q "$ignore_entry" 2>/dev/null; then return 0 fi - _cwt_log_warn "Default worktree root requires $(_cwt_bold "$ignore_entry") in $(_cwt_bold '.gitignore')." - _cwt_log_error "Refusing to edit $(_cwt_bold '.gitignore') automatically. Add $(_cwt_bold "$ignore_entry") manually and rerun." + _cwt_log_warn "Default worktree root requires $(_cwt_bold "$ignore_entry") to be gitignored (local, global, or info/exclude)." + _cwt_log_error "Add $(_cwt_bold "$ignore_entry") to your gitignore and rerun." return 1 } diff --git a/tests/cwt_new.bats b/tests/cwt_new.bats index c8b567e..2d4a487 100644 --- a/tests/cwt_new.bats +++ b/tests/cwt_new.bats @@ -58,12 +58,28 @@ teardown() { cwt new --no-launch ignore-check HEAD " [ "$status" -eq 1 ] - [[ "$output" == *"Default worktree root requires .worktrees/ in .gitignore."* ]] - [[ "$output" == *"Refusing to edit .gitignore automatically."* ]] + [[ "$output" == *"Default worktree root requires .worktrees/ to be gitignored"* ]] + [[ "$output" == *"Add .worktrees/ to your gitignore and rerun."* ]] [ ! -f "$REPO_DIR/.gitignore" ] [ ! -d "$REPO_DIR/.worktrees/ignore-check" ] } +@test "cwt new: accepts .worktrees/ ignored via .git/info/exclude" { + rm -f "$REPO_DIR/.gitignore" + mkdir -p "$REPO_DIR/.git/info" + printf ".worktrees/\n" >>"$REPO_DIR/.git/info/exclude" + + run zsh -c " + export NO_COLOR=1 + cd '$REPO_DIR' + source '$CWT_SH' + cwt new --no-launch info-exclude HEAD + " + [ "$status" -eq 0 ] + [[ "$output" == *"Worktree created"* ]] || [[ "$output" == *"Worktree ready"* ]] + [ -d "$REPO_DIR/.worktrees/info-exclude" ] +} + @test "cwt new: first-run wizard can save the default worktree root" { local repo_real repo_real="$(cd "$REPO_DIR" && pwd -P)"