forked from mirrors/jj
rewrite: move calculation of set to rebase to MutableRepo
This lets us make `parent_mapping` private again.
This commit is contained in:
parent
53a0e23759
commit
0bbebaf4f9
2 changed files with 47 additions and 42 deletions
|
@ -50,7 +50,7 @@ use crate::operation::Operation;
|
||||||
use crate::refs::{
|
use crate::refs::{
|
||||||
diff_named_ref_targets, diff_named_remote_refs, merge_ref_targets, merge_remote_refs,
|
diff_named_ref_targets, diff_named_remote_refs, merge_ref_targets, merge_remote_refs,
|
||||||
};
|
};
|
||||||
use crate::revset::RevsetExpression;
|
use crate::revset::{RevsetExpression, RevsetIteratorExt};
|
||||||
use crate::rewrite::{DescendantRebaser, RebaseOptions};
|
use crate::rewrite::{DescendantRebaser, RebaseOptions};
|
||||||
use crate::settings::{RepoSettings, UserSettings};
|
use crate::settings::{RepoSettings, UserSettings};
|
||||||
use crate::signing::{SignInitError, Signer};
|
use crate::signing::{SignInitError, Signer};
|
||||||
|
@ -772,7 +772,6 @@ pub struct MutableRepo {
|
||||||
base_repo: Arc<ReadonlyRepo>,
|
base_repo: Arc<ReadonlyRepo>,
|
||||||
index: Box<dyn MutableIndex>,
|
index: Box<dyn MutableIndex>,
|
||||||
view: DirtyCell<View>,
|
view: DirtyCell<View>,
|
||||||
// TODO: make these fields private again
|
|
||||||
// The commit identified by the key has been replaced by all the ones in the value.
|
// The commit identified by the key has been replaced by all the ones in the value.
|
||||||
// * Branches pointing to the old commit should be updated to the new commit, resulting in a
|
// * Branches pointing to the old commit should be updated to the new commit, resulting in a
|
||||||
// conflict if there multiple new commits.
|
// conflict if there multiple new commits.
|
||||||
|
@ -781,7 +780,7 @@ pub struct MutableRepo {
|
||||||
// * Working copies pointing to the old commit should be updated to the first of the new
|
// * Working copies pointing to the old commit should be updated to the first of the new
|
||||||
// commits. However, if the type is `Abandoned`, a new working-copy commit should be created
|
// commits. However, if the type is `Abandoned`, a new working-copy commit should be created
|
||||||
// on top of all of the new commits instead.
|
// on top of all of the new commits instead.
|
||||||
pub(crate) parent_mapping: HashMap<CommitId, (RewriteType, Vec<CommitId>)>,
|
parent_mapping: HashMap<CommitId, (RewriteType, Vec<CommitId>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MutableRepo {
|
impl MutableRepo {
|
||||||
|
@ -1107,6 +1106,47 @@ impl MutableRepo {
|
||||||
self.set_view(view);
|
self.set_view(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Find descendants of commits in `parent_mapping` and then return them in
|
||||||
|
/// an order they should be rebased in. The result is in reverse order
|
||||||
|
/// so the next value can be removed from the end.
|
||||||
|
fn find_descendants_to_rebase(&self) -> Vec<Commit> {
|
||||||
|
let store = self.store();
|
||||||
|
let old_commits_expression =
|
||||||
|
RevsetExpression::commits(self.parent_mapping.keys().cloned().collect());
|
||||||
|
let to_visit_expression = old_commits_expression
|
||||||
|
.descendants()
|
||||||
|
.minus(&old_commits_expression);
|
||||||
|
let to_visit_revset = to_visit_expression.evaluate_programmatic(self).unwrap();
|
||||||
|
let to_visit: Vec<_> = to_visit_revset.iter().commits(store).try_collect().unwrap();
|
||||||
|
drop(to_visit_revset);
|
||||||
|
let to_visit_set: HashSet<CommitId> =
|
||||||
|
to_visit.iter().map(|commit| commit.id().clone()).collect();
|
||||||
|
let mut visited = HashSet::new();
|
||||||
|
// Calculate an order where we rebase parents first, but if the parents were
|
||||||
|
// rewritten, make sure we rebase the rewritten parent first.
|
||||||
|
dag_walk::topo_order_reverse(
|
||||||
|
to_visit,
|
||||||
|
|commit| commit.id().clone(),
|
||||||
|
|commit| {
|
||||||
|
visited.insert(commit.id().clone());
|
||||||
|
let mut dependents = vec![];
|
||||||
|
for parent in commit.parents() {
|
||||||
|
if let Some((_, targets)) = self.parent_mapping.get(parent.id()) {
|
||||||
|
for target in targets {
|
||||||
|
if to_visit_set.contains(target) && !visited.contains(target) {
|
||||||
|
dependents.push(store.get_commit(target).unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if to_visit_set.contains(parent.id()) {
|
||||||
|
dependents.push(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependents
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// After the rebaser returned by this function is dropped,
|
/// After the rebaser returned by this function is dropped,
|
||||||
/// self.parent_mapping needs to be cleared.
|
/// self.parent_mapping needs to be cleared.
|
||||||
fn rebase_descendants_return_rebaser<'settings, 'repo>(
|
fn rebase_descendants_return_rebaser<'settings, 'repo>(
|
||||||
|
@ -1118,7 +1158,9 @@ impl MutableRepo {
|
||||||
// Optimization
|
// Optimization
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
let mut rebaser = DescendantRebaser::new(settings, self);
|
|
||||||
|
let to_visit = self.find_descendants_to_rebase();
|
||||||
|
let mut rebaser = DescendantRebaser::new(settings, self, to_visit);
|
||||||
*rebaser.mut_options() = options;
|
*rebaser.mut_options() = options;
|
||||||
rebaser.rebase_all()?;
|
rebaser.rebase_all()?;
|
||||||
Ok(Some(rebaser))
|
Ok(Some(rebaser))
|
||||||
|
|
|
@ -24,14 +24,12 @@ use tracing::instrument;
|
||||||
|
|
||||||
use crate::backend::{BackendError, BackendResult, CommitId, MergedTreeId};
|
use crate::backend::{BackendError, BackendResult, CommitId, MergedTreeId};
|
||||||
use crate::commit::Commit;
|
use crate::commit::Commit;
|
||||||
use crate::dag_walk;
|
|
||||||
use crate::index::Index;
|
use crate::index::Index;
|
||||||
use crate::matchers::{Matcher, Visit};
|
use crate::matchers::{Matcher, Visit};
|
||||||
use crate::merged_tree::{MergedTree, MergedTreeBuilder};
|
use crate::merged_tree::{MergedTree, MergedTreeBuilder};
|
||||||
use crate::object_id::ObjectId;
|
use crate::object_id::ObjectId;
|
||||||
use crate::repo::{MutableRepo, Repo};
|
use crate::repo::{MutableRepo, Repo};
|
||||||
use crate::repo_path::RepoPath;
|
use crate::repo_path::RepoPath;
|
||||||
use crate::revset::{RevsetExpression, RevsetIteratorExt};
|
|
||||||
use crate::settings::UserSettings;
|
use crate::settings::UserSettings;
|
||||||
use crate::store::Store;
|
use crate::store::Store;
|
||||||
|
|
||||||
|
@ -290,43 +288,8 @@ impl<'settings, 'repo> DescendantRebaser<'settings, 'repo> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
settings: &'settings UserSettings,
|
settings: &'settings UserSettings,
|
||||||
mut_repo: &'repo mut MutableRepo,
|
mut_repo: &'repo mut MutableRepo,
|
||||||
|
to_visit: Vec<Commit>,
|
||||||
) -> DescendantRebaser<'settings, 'repo> {
|
) -> DescendantRebaser<'settings, 'repo> {
|
||||||
let store = mut_repo.store();
|
|
||||||
let old_commits_expression =
|
|
||||||
RevsetExpression::commits(mut_repo.parent_mapping.keys().cloned().collect());
|
|
||||||
let to_visit_expression = old_commits_expression
|
|
||||||
.descendants()
|
|
||||||
.minus(&old_commits_expression);
|
|
||||||
let to_visit_revset = to_visit_expression.evaluate_programmatic(mut_repo).unwrap();
|
|
||||||
let to_visit: Vec<_> = to_visit_revset.iter().commits(store).try_collect().unwrap();
|
|
||||||
drop(to_visit_revset);
|
|
||||||
let to_visit_set: HashSet<CommitId> =
|
|
||||||
to_visit.iter().map(|commit| commit.id().clone()).collect();
|
|
||||||
let mut visited = HashSet::new();
|
|
||||||
// Calculate an order where we rebase parents first, but if the parents were
|
|
||||||
// rewritten, make sure we rebase the rewritten parent first.
|
|
||||||
let to_visit = dag_walk::topo_order_reverse(
|
|
||||||
to_visit,
|
|
||||||
|commit| commit.id().clone(),
|
|
||||||
|commit| {
|
|
||||||
visited.insert(commit.id().clone());
|
|
||||||
let mut dependents = vec![];
|
|
||||||
for parent in commit.parents() {
|
|
||||||
if let Some((_, targets)) = mut_repo.parent_mapping.get(parent.id()) {
|
|
||||||
for target in targets {
|
|
||||||
if to_visit_set.contains(target) && !visited.contains(target) {
|
|
||||||
dependents.push(store.get_commit(target).unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if to_visit_set.contains(parent.id()) {
|
|
||||||
dependents.push(parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dependents
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
DescendantRebaser {
|
DescendantRebaser {
|
||||||
settings,
|
settings,
|
||||||
mut_repo,
|
mut_repo,
|
||||||
|
|
Loading…
Reference in a new issue