ok/jj
1
0
Fork 0
forked from mirrors/jj

evolve: pass Transaction to listener functions, so they see the updated state

This commit is contained in:
Martin von Zweigbergk 2021-02-21 21:47:38 -08:00
parent 62ce5782b5
commit 5aadbcf6fc
3 changed files with 53 additions and 33 deletions

View file

@ -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(

View file

@ -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");
}

View file

@ -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);