11use  std:: { path:: PathBuf ,  sync:: Arc } ; 
22
3+ use  super :: { events,  Change } ; 
34use  anyhow:: { Context ,  Result } ; 
4- use  gitbutler_branch_actions:: { VirtualBranchActions ,  VirtualBranches } ; 
5+ use  gitbutler_branch_actions:: { RemoteBranchFile ,   VirtualBranchActions ,  VirtualBranches } ; 
56use  gitbutler_command_context:: CommandContext ; 
7+ use  gitbutler_diff:: DiffByPathMap ; 
68use  gitbutler_error:: error:: Marker ; 
79use  gitbutler_operating_modes:: { 
810    in_open_workspace_mode,  in_outside_workspace_mode,  operating_mode, 
@@ -18,8 +20,6 @@ use gitbutler_sync::cloud::{push_oplog, push_repo};
1820use  gitbutler_user as  users; 
1921use  tracing:: instrument; 
2022
21- use  super :: { events,  Change } ; 
22- 
2323/// A type that contains enough state to make decisions based on changes in the filesystem, which themselves 
2424/// may trigger [Changes](Change) 
2525// NOTE: This is `Clone` as each incoming event is spawned onto a thread for processing. 
@@ -71,7 +71,7 @@ impl Handler {
7171
7272            // This is only produced at the end of mutating Tauri commands to trigger a fresh state being served to the UI. 
7373            events:: InternalEvent :: CalculateVirtualBranches ( project_id)  => self 
74-                 . calculate_virtual_branches ( project_id) 
74+                 . calculate_virtual_branches ( project_id,   None ) 
7575                . context ( "failed to handle virtual branch event" ) , 
7676        } 
7777    } 
@@ -90,8 +90,12 @@ impl Handler {
9090        CommandContext :: open ( & project) . context ( "Failed to create a command context" ) 
9191    } 
9292
93-     #[ instrument( skip( self ,  project_id) ) ]  
94-     fn  calculate_virtual_branches ( & self ,  project_id :  ProjectId )  -> Result < ( ) >  { 
93+     #[ instrument( skip( self ,  project_id,  worktree_changes) ) ]  
94+     fn  calculate_virtual_branches ( 
95+         & self , 
96+         project_id :  ProjectId , 
97+         worktree_changes :  Option < DiffByPathMap > , 
98+     )  -> Result < ( ) >  { 
9599        let  ctx = self . open_command_context ( project_id) ?; 
96100        // Skip if we're not on the open workspace mode 
97101        if  !in_open_workspace_mode ( & ctx)  { 
@@ -102,7 +106,7 @@ impl Handler {
102106            . projects 
103107            . get ( project_id) 
104108            . context ( "failed to get project" ) ?; 
105-         match  VirtualBranchActions . list_virtual_branches ( & project)  { 
109+         match  VirtualBranchActions . list_virtual_branches_cached ( & project,  worktree_changes )  { 
106110            Ok ( ( branches,  skipped_files) )  => self . emit_app_event ( Change :: VirtualBranches  { 
107111                project_id :  project. id , 
108112                virtual_branches :  VirtualBranches  { 
@@ -126,26 +130,36 @@ impl Handler {
126130    fn  recalculate_everything ( & self ,  paths :  Vec < PathBuf > ,  project_id :  ProjectId )  -> Result < ( ) >  { 
127131        let  ctx = self . open_command_context ( project_id) ?; 
128132
129-         self . emit_uncommited_files ( ctx. project ( ) ) ; 
133+         let  worktree_changes =  self . emit_uncommited_files ( ctx. project ( ) ) . ok ( ) ; 
130134
131135        if  in_open_workspace_mode ( & ctx)  { 
132136            self . maybe_create_snapshot ( project_id) . ok ( ) ; 
133-             self . calculate_virtual_branches ( project_id) ?; 
137+             self . calculate_virtual_branches ( project_id,  worktree_changes ) ?; 
134138        } 
135139
136140        Ok ( ( ) ) 
137141    } 
138142
139143    /// Try to emit uncommited files. Swollow errors if they arrise. 
140- fn  emit_uncommited_files ( & self ,  project :  & Project )  { 
141-         let  Ok ( files)  = VirtualBranchActions . get_uncommited_files ( project)  else  { 
142-             return ; 
143-         } ; 
144+ fn  emit_uncommited_files ( & self ,  project :  & Project )  -> Result < DiffByPathMap >  { 
145+         let  files = VirtualBranchActions . get_uncommited_files_reusable ( project) ?; 
144146
145147        let  _ = self . emit_app_event ( Change :: UncommitedFiles  { 
146148            project_id :  project. id , 
147-             files, 
149+             files :  files
150+                 . clone ( ) 
151+                 . into_iter ( ) 
152+                 . map ( |( path,  file) | { 
153+                     let  binary = file. hunks . iter ( ) . any ( |h| h. binary ) ; 
154+                     RemoteBranchFile  { 
155+                         path, 
156+                         hunks :  file. hunks , 
157+                         binary, 
158+                     } 
159+                 } ) 
160+                 . collect ( ) , 
148161        } ) ; 
162+         Ok ( files) 
149163    } 
150164
151165    fn  maybe_create_snapshot ( & self ,  project_id :  ProjectId )  -> anyhow:: Result < ( ) >  { 
0 commit comments