@@ -23,7 +23,7 @@ mod util {
2323 }
2424}
2525
26- mod stacked_and_parallel {
26+ mod worktree_new {
2727 use super :: * ;
2828 use anyhow:: Context ;
2929 use but_graph:: VirtualBranchesTomlMetadata ;
@@ -187,3 +187,104 @@ mod stacked_and_parallel {
187187 Ok ( ( ) )
188188 }
189189}
190+
191+ mod worktree_list {
192+ use super :: * ;
193+ use but_graph:: VirtualBranchesTomlMetadata ;
194+ use but_workspace:: { StacksFilter , stacks_v3} ;
195+ use but_worktrees:: { WorktreeHealthStatus , list:: worktree_list, new:: worktree_new} ;
196+ use gitbutler_branch_actions:: BranchManagerExt as _;
197+ use gix:: refs:: transaction:: PreviousValue ;
198+ use util:: test_ctx;
199+
200+ #[ test]
201+ fn can_list_worktrees ( ) -> anyhow:: Result < ( ) > {
202+ let test_ctx = test_ctx ( "stacked-and-parallel" ) ?;
203+ let mut ctx = test_ctx. ctx ;
204+
205+ let repo = ctx. gix_repo ( ) ?;
206+
207+ let mut guard = ctx. project ( ) . exclusive_worktree_access ( ) ;
208+
209+ let a = worktree_new ( & mut ctx, guard. read_permission ( ) , "feature-a" ) ?; // To stay Normal
210+ let b = worktree_new ( & mut ctx, guard. read_permission ( ) , "feature-a" ) ?; // To be BranchMissing
211+ let c = worktree_new ( & mut ctx, guard. read_permission ( ) , "feature-a" ) ?; // To be BranchNotCheckedOut
212+ let d = worktree_new ( & mut ctx, guard. read_permission ( ) , "feature-a" ) ?; // To be WorktreeMissing
213+ let e = worktree_new ( & mut ctx, guard. read_permission ( ) , "feature-c" ) ?; // To be WorkspaceBranchMissing
214+
215+ let all = & [ & a, & b, & c, & d, & e] ;
216+
217+ // All should start normal
218+ assert ! (
219+ worktree_list( & mut ctx, guard. read_permission( ) ) ?
220+ . entries
221+ . iter( )
222+ . all( |e| all. iter( ) . any( |a| a. created == e. worktree)
223+ && e. status == WorktreeHealthStatus :: Normal )
224+ ) ;
225+
226+ // remove b's branch
227+ repo. find_reference ( & b. created . reference ) ?. delete ( ) ?;
228+
229+ // checkout a different branch on c
230+ repo. reference (
231+ "refs/heads/new-ref" ,
232+ c. created . base ,
233+ PreviousValue :: Any ,
234+ "New reference :D" ,
235+ ) ?;
236+ std:: process:: Command :: from ( gix:: command:: prepare ( gix:: path:: env:: exe_invocation ( ) ) )
237+ . current_dir ( & c. created . path )
238+ . arg ( "switch" )
239+ . arg ( "new-ref" )
240+ . output ( ) ?;
241+
242+ // delete d's worktree
243+ std:: process:: Command :: from ( gix:: command:: prepare ( gix:: path:: env:: exe_invocation ( ) ) )
244+ . current_dir ( & ctx. project ( ) . path )
245+ . arg ( "worktree" )
246+ . arg ( "remove" )
247+ . arg ( "-f" )
248+ . arg ( d. created . path . as_os_str ( ) )
249+ . output ( ) ?;
250+
251+ // remove `feature-c` branch from workspace
252+ // It would be nice to invoke the `but` cli here...
253+ let meta = VirtualBranchesTomlMetadata :: from_path (
254+ ctx. project ( ) . gb_dir ( ) . join ( "virtual_branches.toml" ) ,
255+ ) ?;
256+ let stack = stacks_v3 ( & repo, & meta, StacksFilter :: InWorkspace , None ) ?
257+ . into_iter ( )
258+ . find ( |s| s. heads . iter ( ) . any ( |h| h. name == b"feature-c" ) )
259+ . unwrap ( ) ;
260+ let branch_manager = ctx. branch_manager ( ) ;
261+ branch_manager. unapply (
262+ stack. id . unwrap ( ) ,
263+ guard. write_permission ( ) ,
264+ false ,
265+ vec ! [ ] ,
266+ ctx. app_settings ( ) . feature_flags . cv3 ,
267+ ) ?;
268+
269+ assert ! (
270+ worktree_list( & mut ctx, guard. read_permission( ) ) ?
271+ . entries
272+ . into_iter( )
273+ . all( |entry| if entry. worktree == a. created {
274+ entry. status == WorktreeHealthStatus :: Normal
275+ } else if entry. worktree == b. created {
276+ entry. status == WorktreeHealthStatus :: BranchMissing
277+ } else if entry. worktree == c. created {
278+ entry. status == WorktreeHealthStatus :: BranchNotCheckedOut
279+ } else if entry. worktree == d. created {
280+ entry. status == WorktreeHealthStatus :: WorktreeMissing
281+ } else if entry. worktree == e. created {
282+ entry. status == WorktreeHealthStatus :: WorkspaceBranchMissing
283+ } else {
284+ false
285+ } )
286+ ) ;
287+
288+ Ok ( ( ) )
289+ }
290+ }
0 commit comments