@@ -4,8 +4,6 @@ use gitbutler_oxidize::{ObjectIdExt, OidExt};
44use gitbutler_stack:: { CommitOrChangeId , VirtualBranchesState } ;
55use gix:: prelude:: ObjectIdExt as _;
66use gix:: refs:: transaction:: PreviousValue ;
7- use gix:: revision:: walk:: Sorting ;
8- use std:: collections:: BTreeMap ;
97
108use super :: StackSegmentId ;
119
@@ -18,16 +16,18 @@ use super::StackSegmentId;
1816pub fn rewrite (
1917 repo : & gix:: Repository ,
2018 state : & mut VirtualBranchesState ,
21- workspace_tip : Option < gix:: ObjectId > ,
2219 mut refs_by_commit_id : gix:: hashtable:: HashMap < gix:: ObjectId , Vec < gix:: refs:: FullName > > ,
2320 changed_commits : impl IntoIterator < Item = ( gix:: ObjectId , gix:: ObjectId ) > ,
2421 updated_refs : & mut Vec < UpdatedReference > ,
2522 stack_segment : Option < & StackSegmentId > ,
2623) -> anyhow:: Result < ( ) > {
2724 let mut ref_edits = Vec :: new ( ) ;
2825 let changed_commits: Vec < _ > = changed_commits. into_iter ( ) . collect ( ) ;
29- let change_id_to_id_map = generate_change_ids_to_commit_mapping ( repo, & * state, workspace_tip) ?;
30- let mut stacks_ordered: Vec < _ > = state. branches . values_mut ( ) . collect ( ) ;
26+ let mut stacks_ordered: Vec < _ > = state
27+ . branches
28+ . values_mut ( )
29+ . filter ( |stack| stack. in_workspace )
30+ . collect ( ) ;
3131 stacks_ordered. sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
3232 for ( old, new) in changed_commits {
3333 let old_git2 = old. to_git2 ( ) ;
@@ -38,8 +38,9 @@ pub fn rewrite(
3838 continue ; // Dont rewrite refs for other stacks
3939 }
4040 }
41- if stack. head == old_git2 {
42- stack. head = new. to_git2 ( ) ;
41+ if stack. head ( repo) ? == old_git2 {
42+ // Perhaps skip this - the head will be updated later in this call
43+ // stack.set_stack_head_without_persisting(repo, new.to_git2(), None)?;
4344 stack. tree = new
4445 . attach ( repo)
4546 . object ( ) ?
@@ -65,21 +66,7 @@ pub fn rewrite(
6566 . find_map ( |( idx, h) | ( h. name == short_name) . then_some ( idx) )
6667 } ) ;
6768 for ( idx, branch) in stack. heads . iter_mut ( ) . rev ( ) . enumerate ( ) {
68- let id = match & mut branch. head ( ) {
69- CommitOrChangeId :: CommitId ( id_hex) => {
70- let Some ( id) = gix:: ObjectId :: from_hex ( id_hex. as_bytes ( ) ) . ok ( ) else {
71- continue ;
72- } ;
73- id
74- }
75- #[ allow( deprecated) ]
76- CommitOrChangeId :: ChangeId ( change_id) => {
77- let Some ( id) = change_id_to_id_map. get ( change_id) else {
78- continue ;
79- } ;
80- * id
81- }
82- } ;
69+ let id = branch. head_oid ( repo) ?. to_gix ( ) ;
8370 if id == old {
8471 if update_up_to_idx. is_some ( ) && Some ( idx) > update_up_to_idx {
8572 // Make sure the actual refs also don't update (later)
@@ -135,63 +122,3 @@ pub fn rewrite(
135122 repo. edit_references ( ref_edits) ?;
136123 Ok ( ( ) )
137124}
138-
139- fn generate_change_ids_to_commit_mapping (
140- repo : & gix:: Repository ,
141- vb : & VirtualBranchesState ,
142- workspace_tip : Option < gix:: ObjectId > ,
143- ) -> anyhow:: Result < BTreeMap < String , gix:: ObjectId > > {
144- let cache = repo. commit_graph_if_enabled ( ) ?;
145- let mut graph = repo. revision_graph ( cache. as_ref ( ) ) ;
146- let default_target_tip = vb
147- . default_target
148- . as_ref ( )
149- . map ( |target| -> anyhow:: Result < _ > {
150- let r = repo. find_reference ( & target. branch . to_string ( ) ) ?;
151- Ok ( r. try_id ( ) )
152- } )
153- . and_then ( Result :: ok)
154- . flatten ( ) ;
155-
156- let mut out = BTreeMap :: new ( ) ;
157- let merge_base = if default_target_tip. is_none ( ) {
158- let Some ( workspace_tip) = workspace_tip else {
159- return Ok ( out) ;
160- } ;
161- let workspace_commit = workspace_tip
162- . attach ( repo)
163- . object ( ) ?
164- . into_commit ( )
165- . decode ( ) ?
166- . to_owned ( ) ;
167- if workspace_commit. parents . len ( ) < 2 {
168- None
169- } else {
170- Some ( repo. merge_base_octopus ( workspace_commit. parents ) ?)
171- }
172- } else {
173- None
174- } ;
175- for stack in vb. branches . values ( ) . filter ( |b| b. in_workspace ) {
176- let stack_tip = stack. head . to_gix ( ) ;
177- for info in stack_tip
178- . attach ( repo)
179- . ancestors ( )
180- . with_boundary ( match default_target_tip {
181- Some ( target_tip) => {
182- Some ( repo. merge_base_with_graph ( stack_tip, target_tip, & mut graph) ?)
183- }
184- None => merge_base,
185- } )
186- . sorting ( Sorting :: BreadthFirst )
187- . all ( ) ?
188- . filter_map ( Result :: ok)
189- {
190- let Some ( headers) = but_core:: Commit :: from_id ( info. id . attach ( repo) ) ?. headers ( ) else {
191- continue ;
192- } ;
193- out. insert ( headers. change_id , info. id ) ;
194- }
195- }
196- Ok ( out)
197- }
0 commit comments