@@ -217,17 +217,44 @@ impl Snapshot {
217217
218218 let ws = graph. to_workspace ( ) ?;
219219 let mut seen = BTreeSet :: new ( ) ;
220- for ( ws_stack, in_workspace_stack_id) in
221- ws. stacks . iter ( ) . filter_map ( |s| s. id . map ( |id| ( s, id) ) )
222- {
223- seen. insert ( in_workspace_stack_id) ;
224- let Some ( vb_stack) = self . content . branches . get_mut ( & in_workspace_stack_id) else {
225- tracing:: warn!(
226- "Didn't find stack with id {in_workspace_stack_id} in branches metadata, and it would have to be created or old code may fail"
227- ) ;
228- continue ;
229- } ;
230220
221+ // Make sure we have a stack id, which is something that may not be the case in
222+ // single-branch mode or in tests that start off with just a Git repository.
223+ // Having stack IDs is useful and maybe one day we can pre-generate them just like we do here
224+ // as they only have to be locally unique.
225+ let workspace_unique_stack_id = |mut idx : usize | -> StackId {
226+ let mut stack_id = StackId :: from_number_for_testing ( idx as u128 ) ;
227+ while self . content . branches . contains_key ( & stack_id) {
228+ idx += 1 ;
229+ stack_id = StackId :: from_number_for_testing ( idx as u128 ) ;
230+ }
231+ stack_id
232+ } ;
233+ let ws_stacks_to_represent_in_vb_toml: Vec < _ > = ws
234+ . stacks
235+ . iter ( )
236+ . enumerate ( )
237+ . map ( |( idx, s) | {
238+ let id = s. id . unwrap_or_else ( || workspace_unique_stack_id ( idx + 1 ) ) ;
239+ ( s, id, idx)
240+ } )
241+ . collect ( ) ;
242+ for ( ws_stack, in_workspace_stack_id, ws_stack_idx) in ws_stacks_to_represent_in_vb_toml {
243+ seen. insert ( in_workspace_stack_id) ;
244+ let mut inserted_new_stack = false ;
245+ let vb_stack = self
246+ . content
247+ . branches
248+ . entry ( in_workspace_stack_id)
249+ . or_insert_with ( || {
250+ inserted_new_stack = true ;
251+ Stack :: new_with_just_heads (
252+ vec ! [ ] ,
253+ gix:: date:: Time :: now_utc ( ) . seconds as u128 * 1000 ,
254+ ws_stack_idx,
255+ true ,
256+ )
257+ } ) ;
231258 let made_heads_match = make_heads_match ( ws_stack, vb_stack) ;
232259 if !vb_stack. in_workspace {
233260 tracing:: warn!(
@@ -242,16 +269,19 @@ impl Snapshot {
242269 ) ;
243270 self . set_changed_to_necessitate_write ( ) ;
244271 }
272+ if inserted_new_stack {
273+ self . set_changed_to_necessitate_write ( ) ;
274+ }
245275 }
246276
247- let stack_ids_to_put_in_workspace : Vec < _ > = sideeffect_free_meta
277+ let stack_ids_to_remove_from_workspace : Vec < _ > = sideeffect_free_meta
248278 . data ( )
249279 . branches
250280 . keys ( )
251281 . filter ( |stack_id| !seen. contains ( stack_id) )
252282 . copied ( )
253283 . collect ( ) ;
254- for stack_id_not_in_workspace in stack_ids_to_put_in_workspace {
284+ for stack_id_not_in_workspace in stack_ids_to_remove_from_workspace {
255285 let vb_stack = self
256286 . content
257287 . branches
0 commit comments