1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
//! Worktree operations with file-based shell integration.
//!
//! # The Directory Change Problem
//!
//! Worktree commands (`switch`, `remove`, `merge`) need to change the user's working directory,
//! but there's a fundamental Unix limitation: **child processes cannot change their parent's
//! working directory**. This is a security feature and core Unix design principle.
//!
//! When a user runs `wt switch my-feature`, the `wt` binary runs as a child process of the shell.
//! The binary can change *its own* working directory, but when it exits, the parent shell remains
//! in the original directory.
//!
//! # Solution: File-Based Directive Passing
//!
//! Shell wrappers create a temp file and set `WORKTRUNK_DIRECTIVE_FILE` to its path:
//!
//! 1. Shell wrapper creates temp file via `mktemp`
//! 2. Shell wrapper sets `WORKTRUNK_DIRECTIVE_FILE=/path/to/temp`
//! 3. wt binary writes commands like `cd '/path'` to that file
//! 4. Shell wrapper sources the file after wt exits
//!
//! ## Without Shell Integration (Direct Binary Call)
//!
//! ```bash
//! $ wt switch my-feature
//! Created new branch and worktree for 'my-feature' @ /path/to/worktree
//!
//! Run `wt config shell install` to enable automatic cd
//!
//! $ pwd
//! /original/directory # ← User is still here!
//! ```
//!
//! The binary performs git operations and prints user-friendly messages, but **cannot** change
//! the parent shell's directory. User must manually `cd` to the worktree.
//!
//! ## With Shell Integration
//!
//! ```bash
//! $ wt switch my-feature
//! Created new branch and worktree for 'my-feature' @ /path/to/worktree
//!
//! $ pwd
//! /path/to/worktree # ← Automatically changed!
//! ```
//!
//! When shell integration is enabled (`eval "$(wt config shell init bash)"`), the shell wrapper:
//!
//! 1. Creates a temp file and sets `WORKTRUNK_DIRECTIVE_FILE` to its path
//! 2. Runs the wt binary (which writes `cd '/path'` to the temp file)
//! 3. Sources the temp file after wt exits
//!
//! # Implementation Details
//!
//! Result types (`SwitchResult`, `RemoveResult`) are pure data structures that only contain
//! operation results. All presentation logic is handled by the `output` module:
//!
//! - `output::handle_switch_output()`: Formats and outputs switch operation results
//! - `output::handle_remove_output()`: Formats and outputs remove operation results
//!
//! The output handlers check `is_shell_integration_active()` to determine if hints should
//! be suppressed (when shell integration is already configured).
//!
//! ## Exit Code Semantics
//!
//! When using `-x` to execute commands after switching:
//!
//! - **If wt operation fails**: Returns wt's exit code (command never executes)
//! - **If wt succeeds but command fails**: Returns the command's exit code
//! - **Rationale**: Enables command chaining with proper error propagation
//!
//! Example:
//! ```bash
//! wt switch feature -x "cargo build" && cargo test
//! # If wt fails (e.g., worktree doesn't exist), cargo build never runs
//! # If cargo build fails, cargo test doesn't run (exit code propagates)
//! ```
//!
//! The shell wrapper is generated by `wt config shell init <shell>` from templates in `templates/`.
pub
use ;
use ;
use generate_removing_path;
use Repository;
// Re-export public types and functions
pub use ;
pub use paths_match;
pub use ;
pub use ;
pub use ;
/// Execute core worktree removal: stop fsmonitor, remove worktree, delete branch.
///
/// Uses the fast path (rename into `.git/wt/trash/` + prune) when possible,
/// falling back to `git worktree remove` on cross-filesystem setups.
/// On the fast path the directory disappears instantly; the caller is responsible
/// for cleaning up the staged trash entry (returned via `staged_path`).
///
/// `branch_result` is the raw `delete_branch_if_safe` outcome, preserved so
/// callers can handle branch deletion failures independently:
/// - The picker ignores it (best-effort in TUI context)
/// - The output handler processes it for user-facing display
///
/// `branch_result` is `None` when deletion was not attempted (no branch name,
/// or `deletion_mode.should_keep()`).
/// Rename a worktree into `.git/wt/trash/` and prune git metadata.
///
/// Returns `Some(staged_path)` on success, `None` if the rename failed.
/// Used internally by `execute_removal` and by the output handler's
/// `execute_instant_removal_or_fallback` (which builds shell command strings
/// and adds a placeholder directory — needs the raw staged path).
pub