Change dirty worktree detection from checking only tracked file changes
to using the status_symbols.working_tree field which includes both
tracked and untracked files. This ensures the summary correctly reports
all worktrees with any modifications.
Consider untracked files when determining if a worktree is safe to delete.
Untracked files would be lost on worktree removal, so they should block the
integration state. Pass untracked status to check_integration_state and update
integration detection to require both tracked and untracked files to be clean.
Update snapshots to reflect the visual change from underscore to en-dash for
worktrees with untracked files only (no tracked changes).
* Enable ~49 more Windows tests
Now that we've verified echo commands work through Git Bash on Windows,
enable all tests that use shell commands like 'echo ... > file.txt'.
Remaining 19 Windows-ignored tests have actual platform incompatibilities:
- chmod command (Unix only)
- File locking during worktree removal
- git status CRLF/LF differences
- /tmp paths
- cat command
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Enable 16 Windows tests that use simple echo commands
Selectively enable tests that use:
- Simple echo commands without path template variables
- Non-path template variables ({{ branch }}, {{ target }}, {{ default_branch }})
Tests using path template variables ({{ worktree }}, {{ main_worktree }},
{{ repo_root }}, {{ worktree_name }}) remain ignored due to shell quoting
differences when these paths are echoed on Windows via Git Bash.
Enabled tests by file:
- approval_ui.rs: 7 tests
- merge.rs: 3 tests
- switch.rs: 2 tests
- user_hooks.rs: 2 tests
- remove.rs: 1 test
- post_start_commands.rs: 1 test
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix Windows path quoting in shell templates
Convert Windows native paths (D:\...) to POSIX format (/d/...)
in hook context variables. This avoids shell escaping of `:` and `\`
characters that caused snapshot mismatches between Windows and Unix.
The root cause was that shell_escape::escape() uses unix escaping
when MSYSTEM is set (as it is in Git Bash), and Windows paths contain
characters not in the unix safe character set, causing them to be
wrapped in single quotes.
Changes:
- Add to_posix_path() helper for Git Bash compatibility
- Update build_hook_context() to use POSIX paths for worktree/repo_root
- Enable 15+ tests that were previously skipped due to path differences
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add POSIX path filters for Windows snapshot redaction
The to_posix_path() conversion in command_executor.rs converts Windows
paths like C:\Users\...\repo to POSIX format /c/Users/.../repo for Git
Bash compatibility. However, snapshot redaction patterns weren't catching
these POSIX-formatted paths.
Add:
- to_posix_path() helper in test common module
- POSIX path filters for repo and worktree paths
- Regex fallback pattern for POSIX-style Windows temp paths
This ensures template variables like ${worktree} and ${repo_root} are
properly redacted in snapshots regardless of path format.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Format: split long filter line
* Update user_hooks snapshots after rebase
* Use cygpath for Windows path conversion
Instead of hand-rolling POSIX path conversion, use cygpath from Git for
Windows which handles all edge cases (UNC paths, verbatim paths, etc.).
- Derive cygpath location from cached ShellConfig (no duplicate Git-finding)
- Fall back to pass-through if cygpath unavailable
- Remove duplicate to_posix_path implementations from command_executor and tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Test: enable for_each tests on Windows
Remove stale Windows skip attributes from for_each tests.
These tests run commands through Git Bash (via ShellConfig), so
echo and git commands should behave identically to Unix.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add .gitattributes to force LF line endings in test repos
The for_each tests were skipped on Windows because `git status`
showed files as modified due to CRLF conversion. Adding `.gitattributes`
with `* text=auto eol=lf` ensures consistent line endings across all
platforms.
Changes:
- Add .gitattributes to template-repo
- Update copy_fixture_template() to copy .gitattributes
- Regenerate template git objects with .gitattributes tracked
- Update snapshots (git warning removed, env vars normalized)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Replace `git init` with pre-initialized fixture template to save ~10ms per test.
The fixture at tests/fixtures/template-repo/ contains a minimal git repo with
one deterministic commit (hash 23e5a15, timestamp 2025-01-01T00:00:00Z).
Changes:
- TestRepo::new() now copies fixture instead of running git init
- TestRepo::empty() added for tests needing uninitialized repos
- Removed ~320 redundant `repo.commit("Initial commit")` calls from tests
- Reduced fixture from 32 files to 9 (removed sample hooks, logs, etc.)
- Fixed path canonicalization in TestRepo::empty() for Windows compatibility
- Added typos exception for commit hash substring 'ede'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The status column previously mixed operational concerns (git conflicts,
rebase, merge) with relationship information (main divergence, worktree
location). This reorganization groups related symbols:
- Worktree position 3: operation and location state (conflicts ✘⤴⤵ take
priority over location /⚑⊟⊞)
- Main position 4: relationship to main branch (^✗_⊂↕↑↓, single-stroke arrows)
- Remote position 5: relationship to tracking branch (|⇅⇡⇣, double-stroke arrows)
This grouping reduces cognitive load by keeping related symbols adjacent.
Operations now correctly display regardless of integration state, and the
main column clearly shows branch relationship independent of changes.
JSON field renames reflect the reorganized semantics:
- `branch_state` → split into `main_state` and `operation_state`
- Downstream jq queries use `.operation_state` for conflicts
- Statusline output reordered to match position grid
Separate the "same commit" case (branch HEAD == main) from "ancestor"
case (branch is ancestor of main but main has moved past) to enable
distinct status symbols. Update symbol from `·` to `_` for clarity and
add `Ancestor` variant to `IntegrationReason` enum. Branches that are
ancestors now show `⊂` (integrated) instead of `_` (same commit).
Improve branch cleanup detection with four ordered checks to identify when
branch content is already in the target branch. This enables accurate removal
of squash-merged branches even after target advances.
**New integration checks (in cost order):**
- Same commit: Branch HEAD is literally the same commit as target
- No added changes: Three-dot diff shows no file changes beyond merge-base
- Tree contents match: Tree SHA equals target's tree SHA
- Merge simulation: Merging branch into target adds nothing (--full only)
**Status symbols updated:**
- `·` for same commit (cheapest check)
- `⊂` for content integrated via different history (all other cases)
Previously used `≡` (matches main) and `_` (no commits) which were ambiguous.
The new symbols better represent the checked conditions.
**Implementation:**
- Add `IsAncestorTask`, `HasFileChangesTask`, `WouldMergeAddTask` to task DAG
- Add `is_ancestor`, `has_file_changes`, `would_merge_add` fields to `ListItem`
- Create `IntegrationReason` enum for type-safe reason tracking
- Update `is_potentially_removable()` logic with ordered checks
- Refine `BranchOpState` variants to map to integration reasons
Update terminal output examples to wrap command text in `<span class="cmd">` tags, enabling distinct styling for user input versus output. Adjust snapshot test to apply this formatting automatically when syncing docs with test outputs.
Configuration section now distinguishes between command behavior and defaults, with clearer explanations of what each setting controls. Hooks documentation expanded to explain the three branch cleanup conditions checked before safe deletion, with examples using `{{ repo_root }}` variable.
LLM commits section clarified to show squash-merge workflow as the primary use case. Claude Code statusline explanation expanded on network latency and async suitability. Branch state symbol `_` redefined as "no commits ahead" rather than "empty branch" to better reflect actual behavior.
Updated `wt remove` documentation to cross-reference FAQ instead of switch.md, and simplified tips section by linking to switch.md shortcuts instead of duplicating the list.
The "Advanced Features" page focused primarily on Claude Code integration.
Renaming it better reflects its scope and allows future advanced features
to live elsewhere. Removed the interactive worktree picker section which
belongs in select.md documentation. Updated cross-references in quickstart
and tips-patterns docs to point to the new page location.