diff --git a/lib/src/evolution.rs b/lib/src/evolution.rs index c899cf683..da71b8e4c 100644 --- a/lib/src/evolution.rs +++ b/lib/src/evolution.rs @@ -348,12 +348,18 @@ pub fn evolve( listener: &mut dyn EvolveListener, ) { let store = tx.store().clone(); - // TODO: update the state in the transaction - let state = tx.as_repo_mut().evolution_mut().state.clone(); // Resolving divergence can creates new orphans but not vice versa, so resolve // divergence first. - for commit_ids in state.divergent_changes.values() { + let divergent_changes: Vec<_> = tx + .as_repo_mut() + .evolution_mut() + .state + .divergent_changes + .values() + .cloned() + .collect(); + for commit_ids in divergent_changes { let commits: HashSet = commit_ids .iter() .map(|id| store.get_commit(&id).unwrap()) @@ -361,7 +367,12 @@ pub fn evolve( evolve_divergent_change(user_settings, &store, tx, listener, &commits); } - let orphans: HashSet = state + // Dom't reuse the state from above, since the divergence-resolution may have + // created new orphans, or resolved existing orphans. + let orphans: HashSet = tx + .as_repo_mut() + .evolution_mut() + .state .orphan_commits .iter() .map(|id| store.get_commit(&id).unwrap()) @@ -376,7 +387,7 @@ pub fn evolve( commit .parents() .iter() - .filter(|commit| state.orphan_commits.contains(commit.id())) + .filter(|commit| orphans.contains(commit)) .cloned() .collect::>() }), @@ -389,8 +400,9 @@ pub fn evolve( let old_parents = orphan.parents(); let mut new_parents = vec![]; let mut ambiguous_new_parents = false; + let evolution = tx.as_repo_mut().evolution(); for old_parent in &old_parents { - let new_parent_candidates = state.new_parent(&store, old_parent.id()); + let new_parent_candidates = evolution.new_parent(old_parent.id()); if new_parent_candidates.len() > 1 { ambiguous_new_parents = true; break; diff --git a/lib/tests/test_evolution.rs b/lib/tests/test_evolution.rs index 4ca8abe17..bd4035e61 100644 --- a/lib/tests/test_evolution.rs +++ b/lib/tests/test_evolution.rs @@ -503,11 +503,10 @@ fn test_evolve_orphan(use_git: bool) { assert_eq!(&listener.evolved_orphans[0].0, &child); assert_eq!(&listener.evolved_orphans[0].1.parents(), &vec![rewritten]); assert_eq!(&listener.evolved_orphans[1].0, &grandchild); - // TODO: the grandchild currently doesn't get rebased onto the rewritten child - // assert_eq!( - // &listener.evolved_orphans[1].1.parents(), - // &vec![listener.evolved_orphans[0].1.clone()] - // ); + assert_eq!( + &listener.evolved_orphans[1].1.parents(), + &vec![listener.evolved_orphans[0].1.clone()] + ); tx.discard(); }