worktree finish prints a git fatal because the .cc-os symlink is not ignored #649

Closed
opened 2026-09-23 17:42:29 +00:00 by jared · 1 comment
Owner

worktree finish leaks a git fatal line on untracked-only removal

Problem

#645 merge verification on 2026-09-23 found that plugins/os/bin/worktree finish prints a fatal git error even though it completes successfully and removes the worktree. The real cause is in plugins/os/lib/worktree/removal.rb, not .gitignore: Removal#call runs git worktree remove with bare system (stderr leaks the fatal), then retries with --force when untracked_only_linked? is true.

Cases

  1. Given a worktree whose only untracked file is the .cc-os symlink, when worktree finish runs, then no git fatal line reaches stderr or stdout.
  2. Given a worktree removal that fails on the final --force attempt too, when worktree finish runs, then the real failure is still surfaced to the operator.

Approach

Capture the first git worktree remove attempt's output via Open3 instead of bare system. Surface stderr only when the final attempt also fails, or skip straight to --force when untracked_only_linked? is already true.

Required work:

  1. Change Removal#call to use Open3 for the first attempt and suppress its stderr unless the retry also fails — check: plugins/os/bin/worktree finish ticket-649 2>&1 | grep fatal (expect no match on the untracked-only-linked path)
  2. Extend plugins/os/tests/worktree/finish_command_untracked_link_only_test.rb to assert no fatal reaches stderr/stdout

Acceptance criteria

  1. Given a worktree whose only untracked file is the .cc-os symlink, when worktree finish runs, then it reports success with no fatal line in stderr or stdout.
  2. Given a worktree removal where both attempts fail, when worktree finish runs, then the operator sees the git failure.

Non-goals

.gitignore is unchanged; the trailing-slash pattern is not the cause.

Origin

  • Trigger: #645 merge verification, 2026-09-23
  • Where: plugins/os/lib/worktree/removal.rb, plugins/os/bin/worktree
  • Session: 073fd763-259f-4218-95e6-e8449caae354
# worktree finish leaks a git fatal line on untracked-only removal ## Problem #645 merge verification on 2026-09-23 found that `plugins/os/bin/worktree finish` prints a fatal git error even though it completes successfully and removes the worktree. The real cause is in `plugins/os/lib/worktree/removal.rb`, not `.gitignore`: `Removal#call` runs `git worktree remove` with bare system (stderr leaks the fatal), then retries with `--force` when `untracked_only_linked?` is true. ## Cases 1. Given a worktree whose only untracked file is the `.cc-os` symlink, when `worktree finish` runs, then no git fatal line reaches stderr or stdout. 2. Given a worktree removal that fails on the final `--force` attempt too, when `worktree finish` runs, then the real failure is still surfaced to the operator. ## Approach Capture the first `git worktree remove` attempt's output via Open3 instead of bare system. Surface stderr only when the final attempt also fails, or skip straight to `--force` when `untracked_only_linked?` is already true. Required work: 1. Change `Removal#call` to use Open3 for the first attempt and suppress its stderr unless the retry also fails — check: `plugins/os/bin/worktree finish ticket-649 2>&1 | grep fatal` (expect no match on the untracked-only-linked path) 2. Extend plugins/os/tests/worktree/finish_command_untracked_link_only_test.rb to assert no fatal reaches stderr/stdout ## Acceptance criteria 1. Given a worktree whose only untracked file is the `.cc-os` symlink, when `worktree finish` runs, then it reports success with no fatal line in stderr or stdout. 2. Given a worktree removal where both attempts fail, when `worktree finish` runs, then the operator sees the git failure. ## Non-goals `.gitignore` is unchanged; the trailing-slash pattern is not the cause. ## Origin - Trigger: #645 merge verification, 2026-09-23 - Where: plugins/os/lib/worktree/removal.rb, plugins/os/bin/worktree - Session: 073fd763-259f-4218-95e6-e8449caae354
Author
Owner

Resolution

Done: Removal skips straight to --force when only linked entries are untracked and captures git stderr with Open3, so finish prints no fatal

Evidence: commit 1c25318f; plugins/os tests 22 runs 0 failures; the next two worktree finish runs printed no fatal line

Follow-ups: none

## Resolution **Done:** Removal skips straight to --force when only linked entries are untracked and captures git stderr with Open3, so finish prints no fatal **Evidence:** commit 1c25318f; plugins/os tests 22 runs 0 failures; the next two worktree finish runs printed no fatal line **Follow-ups:** none
jared closed this issue 2026-09-24 20:34:20 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#649
No description provided.