From 5aadbcf6fc8231269c617fae603de496872a04ee Mon Sep 17 00:00:00 2001 From: Martin von Zweigbergk Date: Sun, 21 Feb 2021 21:47:38 -0800 Subject: [PATCH] evolve: pass Transaction to listener functions, so they see the updated state --- lib/src/evolution.rs | 26 ++++++++++++++------- lib/tests/test_evolution.rs | 14 +++++++---- src/commands.rs | 46 ++++++++++++++++++++----------------- 3 files changed, 53 insertions(+), 33 deletions(-) diff --git a/lib/src/evolution.rs b/lib/src/evolution.rs index 17fc46af1..a822c50b8 100644 --- a/lib/src/evolution.rs +++ b/lib/src/evolution.rs @@ -379,10 +379,20 @@ pub struct ReadonlyEvolution<'r> { } pub trait EvolveListener { - fn orphan_evolved(&mut self, orphan: &Commit, new_commit: &Commit); - fn orphan_target_ambiguous(&mut self, orphan: &Commit); - fn divergent_resolved(&mut self, divergents: &[Commit], resolved: &Commit); - fn divergent_no_common_predecessor(&mut self, commit1: &Commit, commit2: &Commit); + fn orphan_evolved(&mut self, tx: &mut Transaction, orphan: &Commit, new_commit: &Commit); + fn orphan_target_ambiguous(&mut self, tx: &mut Transaction, orphan: &Commit); + fn divergent_resolved( + &mut self, + tx: &mut Transaction, + divergents: &[Commit], + resolved: &Commit, + ); + fn divergent_no_common_predecessor( + &mut self, + tx: &mut Transaction, + commit1: &Commit, + commit2: &Commit, + ); } impl<'r> ReadonlyEvolution<'r> { @@ -541,10 +551,10 @@ pub fn evolve( ); } if ambiguous_new_parents { - listener.orphan_target_ambiguous(&orphan); + listener.orphan_target_ambiguous(tx, &orphan); } else { let new_commit = rebase_commit(user_settings, tx, &orphan, &new_parents); - listener.orphan_evolved(&orphan, &new_commit); + listener.orphan_evolved(tx, &orphan, &new_commit); } } } @@ -576,7 +586,7 @@ fn evolve_divergent_change( ); match common_predecessor { None => { - listener.divergent_no_common_predecessor(&commit1, &commit2); + listener.divergent_no_common_predecessor(tx, &commit1, &commit2); return; } Some(common_predecessor) => { @@ -594,7 +604,7 @@ fn evolve_divergent_change( } let resolved = commits.pop().unwrap(); - listener.divergent_resolved(&sources, &resolved); + listener.divergent_resolved(tx, &sources, &resolved); } fn evolve_two_divergent_commits( diff --git a/lib/tests/test_evolution.rs b/lib/tests/test_evolution.rs index 5f94ae3ad..7f431af24 100644 --- a/lib/tests/test_evolution.rs +++ b/lib/tests/test_evolution.rs @@ -20,6 +20,7 @@ use jujube_lib::repo::ReadonlyRepo; use jujube_lib::repo_path::FileRepoPath; use jujube_lib::settings::UserSettings; use jujube_lib::testutils; +use jujube_lib::transaction::Transaction; use test_case::test_case; #[must_use] @@ -482,22 +483,27 @@ impl Default for RecordingEvolveListener { } impl EvolveListener for RecordingEvolveListener { - fn orphan_evolved(&mut self, orphan: &Commit, new_commit: &Commit) { + fn orphan_evolved(&mut self, _tx: &mut Transaction, orphan: &Commit, new_commit: &Commit) { self.evolved_orphans .push((orphan.clone(), new_commit.clone())); } - fn orphan_target_ambiguous(&mut self, _orphan: &Commit) { + fn orphan_target_ambiguous(&mut self, _tx: &mut Transaction, _orphan: &Commit) { // TODO: Record this too and add tests panic!("unexpected call to orphan_target_ambiguous"); } - fn divergent_resolved(&mut self, sources: &[Commit], resolved: &Commit) { + fn divergent_resolved(&mut self, _tx: &mut Transaction, sources: &[Commit], resolved: &Commit) { self.evolved_divergents .push((sources.iter().cloned().collect(), resolved.clone())); } - fn divergent_no_common_predecessor(&mut self, _commit1: &Commit, _commit2: &Commit) { + fn divergent_no_common_predecessor( + &mut self, + _tx: &mut Transaction, + _commit1: &Commit, + _commit2: &Commit, + ) { // TODO: Record this too and add tests panic!("unexpected call to divergent_no_common_predecessor"); } diff --git a/src/commands.rs b/src/commands.rs index 219c992d8..ea10eaa68 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -41,7 +41,7 @@ use jujube_lib::files; use jujube_lib::files::DiffLine; use jujube_lib::git; use jujube_lib::op_store::{OpStoreError, OperationId}; -use jujube_lib::repo::{ReadonlyRepo, RepoLoadError, RepoRef}; +use jujube_lib::repo::{ReadonlyRepo, RepoLoadError}; use jujube_lib::repo_path::RepoPath; use jujube_lib::rewrite::{back_out_commit, merge_commit_trees, rebase_commit}; use jujube_lib::settings::UserSettings; @@ -1658,48 +1658,57 @@ fn cmd_evolve<'s>( let mut repo = get_repo(ui, &matches)?; let owned_wc = repo.working_copy().clone(); - struct Listener<'a, 's, 'r> { + struct Listener<'a, 's> { ui: &'a mut Ui<'s>, - repo: RepoRef<'a, 'r>, }; - impl<'a, 's, 'r> EvolveListener for Listener<'a, 's, 'r> { - fn orphan_evolved(&mut self, orphan: &Commit, new_commit: &Commit) { + impl<'a, 's> EvolveListener for Listener<'a, 's> { + fn orphan_evolved(&mut self, tx: &mut Transaction, orphan: &Commit, new_commit: &Commit) { self.ui.write("Resolving orphan: "); - self.ui.write_commit_summary(self.repo, &orphan); + self.ui.write_commit_summary(tx.as_repo_ref(), &orphan); self.ui.write("\n"); self.ui.write("Resolved as: "); - self.ui.write_commit_summary(self.repo, &new_commit); + self.ui.write_commit_summary(tx.as_repo_ref(), &new_commit); self.ui.write("\n"); } - fn orphan_target_ambiguous(&mut self, orphan: &Commit) { + fn orphan_target_ambiguous(&mut self, tx: &mut Transaction, orphan: &Commit) { self.ui .write("Skipping orphan with ambiguous new parents: "); - self.ui.write_commit_summary(self.repo, &orphan); + self.ui.write_commit_summary(tx.as_repo_ref(), &orphan); self.ui.write("\n"); } - fn divergent_resolved(&mut self, sources: &[Commit], resolved: &Commit) { + fn divergent_resolved( + &mut self, + tx: &mut Transaction, + sources: &[Commit], + resolved: &Commit, + ) { self.ui.write("Resolving divergent commits:\n"); for source in sources { self.ui.write(" "); - self.ui.write_commit_summary(self.repo, &source); + self.ui.write_commit_summary(tx.as_repo_ref(), &source); self.ui.write("\n"); } self.ui.write("Resolved as: "); - self.ui.write_commit_summary(self.repo, &resolved); + self.ui.write_commit_summary(tx.as_repo_ref(), &resolved); self.ui.write("\n"); } - fn divergent_no_common_predecessor(&mut self, commit1: &Commit, commit2: &Commit) { + fn divergent_no_common_predecessor( + &mut self, + tx: &mut Transaction, + commit1: &Commit, + commit2: &Commit, + ) { self.ui .write("Skipping divergent commits with no common predecessor:\n"); self.ui.write(" "); - self.ui.write_commit_summary(self.repo, &commit1); + self.ui.write_commit_summary(tx.as_repo_ref(), &commit1); self.ui.write("\n"); self.ui.write(" "); - self.ui.write_commit_summary(self.repo, &commit2); + self.ui.write_commit_summary(tx.as_repo_ref(), &commit2); self.ui.write("\n"); } } @@ -1708,12 +1717,7 @@ fn cmd_evolve<'s>( // mutable borrow? But the mutable borrow might be useful for making sure we // have only one Ui instance we write to across threads? let user_settings = ui.settings().clone(); - let mut listener = Listener { - ui, - // TODO: This should be using tx.as_repo_ref() so the templater sees the updated state, but - // we can't do that because we let evolution::evolve() mutably borrow the Transaction. - repo: repo.as_repo_ref(), - }; + let mut listener = Listener { ui }; let mut tx = repo.start_transaction("evolve"); evolve(&user_settings, &mut tx, &mut listener); update_checkout_after_rewrite(ui, &mut tx);