@@ -134,7 +134,20 @@ where
134134 return Err ( "Cannot create a worktree from another worktree." . to_string ( ) ) ;
135135 }
136136
137- let worktree_root = data_dir. join ( "worktrees" ) . join ( & parent_entry. id ) ;
137+ // Determine worktree root: per-workspace setting > global setting > default
138+ let worktree_root = if let Some ( custom_folder) = & parent_entry. settings . worktrees_folder {
139+ PathBuf :: from ( custom_folder)
140+ } else {
141+ let global_folder = {
142+ let settings = app_settings. lock ( ) . await ;
143+ settings. global_worktrees_folder . clone ( )
144+ } ;
145+ if let Some ( global_folder) = global_folder {
146+ PathBuf :: from ( global_folder) . join ( & parent_entry. id )
147+ } else {
148+ data_dir. join ( "worktrees" ) . join ( & parent_entry. id )
149+ }
150+ } ;
138151 std:: fs:: create_dir_all ( & worktree_root)
139152 . map_err ( |err| format ! ( "Failed to create worktree directory: {err}" ) ) ?;
140153
@@ -333,7 +346,7 @@ pub(crate) async fn rename_worktree_core<
333346 data_dir : & PathBuf ,
334347 workspaces : & Mutex < HashMap < String , WorkspaceEntry > > ,
335348 sessions : & Mutex < HashMap < String , Arc < WorkspaceSession > > > ,
336- _app_settings : & Mutex < AppSettings > ,
349+ app_settings : & Mutex < AppSettings > ,
337350 storage_path : & PathBuf ,
338351 resolve_git_root : FResolveGitRoot ,
339352 unique_branch_name : FUniqueBranch ,
@@ -393,54 +406,102 @@ where
393406 return Err ( "Branch name is unchanged." . to_string ( ) ) ;
394407 }
395408
396- run_git_command ( & parent_root, & [ "branch" , "-m" , & old_branch, & final_branch] ) . await ?;
397-
398- let worktree_root = data_dir. join ( "worktrees" ) . join ( & parent. id ) ;
409+ // Use the same priority logic as add_worktree_core:
410+ // per-workspace setting > global setting > default
411+ let worktree_root = if let Some ( custom_folder) = & parent. settings . worktrees_folder {
412+ PathBuf :: from ( custom_folder)
413+ } else {
414+ let global_folder = {
415+ let settings = app_settings. lock ( ) . await ;
416+ settings. global_worktrees_folder . clone ( )
417+ } ;
418+ if let Some ( global_folder) = global_folder {
419+ PathBuf :: from ( global_folder) . join ( & parent. id )
420+ } else {
421+ data_dir. join ( "worktrees" ) . join ( & parent. id )
422+ }
423+ } ;
399424 std:: fs:: create_dir_all ( & worktree_root)
400425 . map_err ( |err| format ! ( "Failed to create worktree directory: {err}" ) ) ?;
401426
402427 let safe_name = sanitize_worktree_name ( & final_branch) ;
403428 let current_path = PathBuf :: from ( & entry. path ) ;
404429 let next_path = unique_worktree_path_for_rename ( & worktree_root, & safe_name, & current_path) ?;
405430 let next_path_string = next_path. to_string_lossy ( ) . to_string ( ) ;
406- if next_path_string != entry. path {
431+ let old_path_string = entry. path . clone ( ) ;
432+
433+ run_git_command ( & parent_root, & [ "branch" , "-m" , & old_branch, & final_branch] ) . await ?;
434+
435+ let mut moved_worktree = false ;
436+ if next_path_string != old_path_string {
407437 if let Err ( error) = run_git_command (
408438 & parent_root,
409- & [ "worktree" , "move" , & entry . path , & next_path_string] ,
439+ & [ "worktree" , "move" , & old_path_string , & next_path_string] ,
410440 )
411441 . await
412442 {
413443 let _ =
414444 run_git_command ( & parent_root, & [ "branch" , "-m" , & final_branch, & old_branch] ) . await ;
415445 return Err ( error) ;
416446 }
447+ moved_worktree = true ;
417448 }
418449
419- let ( entry_snapshot , list ) = {
450+ let update_result : Result < ( WorkspaceEntry , WorkspaceEntry , Vec < WorkspaceEntry > ) , String > = {
420451 let mut workspaces = workspaces. lock ( ) . await ;
421- let entry = match workspaces. get_mut ( & id) {
422- Some ( entry) => entry,
423- None => return Err ( "workspace not found" . to_string ( ) ) ,
424- } ;
425- if entry. name . trim ( ) == old_branch {
426- entry. name = final_branch. clone ( ) ;
427- }
428- entry. path = next_path_string. clone ( ) ;
429- match entry. worktree . as_mut ( ) {
430- Some ( worktree) => {
431- worktree. branch = final_branch. clone ( ) ;
452+ if let Some ( entry) = workspaces. get_mut ( & id) {
453+ let old_snapshot = entry. clone ( ) ;
454+ if entry. name . trim ( ) == old_branch {
455+ entry. name = final_branch. clone ( ) ;
432456 }
433- None => {
434- entry. worktree = Some ( WorktreeInfo {
435- branch : final_branch. clone ( ) ,
436- } ) ;
457+ entry. path = next_path_string. clone ( ) ;
458+ match entry. worktree . as_mut ( ) {
459+ Some ( worktree) => {
460+ worktree. branch = final_branch. clone ( ) ;
461+ }
462+ None => {
463+ entry. worktree = Some ( WorktreeInfo {
464+ branch : final_branch. clone ( ) ,
465+ } ) ;
466+ }
437467 }
468+ let snapshot = entry. clone ( ) ;
469+ let list: Vec < _ > = workspaces. values ( ) . cloned ( ) . collect ( ) ;
470+ Ok ( ( old_snapshot, snapshot, list) )
471+ } else {
472+ Err ( "workspace not found" . to_string ( ) )
473+ }
474+ } ;
475+ let ( old_snapshot, entry_snapshot, list) = match update_result {
476+ Ok ( value) => value,
477+ Err ( error) => {
478+ if moved_worktree {
479+ let _ = run_git_command (
480+ & parent_root,
481+ & [ "worktree" , "move" , & next_path_string, & old_path_string] ,
482+ )
483+ . await ;
484+ }
485+ let _ =
486+ run_git_command ( & parent_root, & [ "branch" , "-m" , & final_branch, & old_branch] ) . await ;
487+ return Err ( error) ;
438488 }
439- let snapshot = entry. clone ( ) ;
440- let list: Vec < _ > = workspaces. values ( ) . cloned ( ) . collect ( ) ;
441- ( snapshot, list)
442489 } ;
443- write_workspaces ( storage_path, & list) ?;
490+ if let Err ( error) = write_workspaces ( storage_path, & list) {
491+ if moved_worktree {
492+ let _ = run_git_command (
493+ & parent_root,
494+ & [ "worktree" , "move" , & next_path_string, & old_path_string] ,
495+ )
496+ . await ;
497+ }
498+ let _ = run_git_command ( & parent_root, & [ "branch" , "-m" , & final_branch, & old_branch] ) . await ;
499+ let mut workspaces = workspaces. lock ( ) . await ;
500+ if let Some ( entry) = workspaces. get_mut ( & id) {
501+ * entry = old_snapshot;
502+ }
503+ return Err ( error) ;
504+ }
444505
445506 if let Some ( session) = sessions. lock ( ) . await . get ( & entry_snapshot. id ) . cloned ( ) {
446507 session
0 commit comments