mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-15 16:53:25 +00:00
rewrite: remove return value from rebase_next()
`rebase_next()` returns an `Option<RebasedDescendant>`, but the only way we use it is to decide whether to terminate the loop over `to_visit`. Let's simplify by making the caller iterate over `to_visit` instead.
This commit is contained in:
parent
881d75e899
commit
9efa66e8c9
1 changed files with 67 additions and 77 deletions
|
@ -539,81 +539,77 @@ impl<'settings, 'repo> DescendantRebaser<'settings, 'repo> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rebase_next(&mut self) -> Result<Option<RebasedDescendant>, TreeMergeError> {
|
fn rebase_one(&mut self, old_commit: Commit) -> Result<(), TreeMergeError> {
|
||||||
while let Some(old_commit) = self.to_visit.pop() {
|
let old_commit_id = old_commit.id().clone();
|
||||||
let old_commit_id = old_commit.id().clone();
|
if let Some(new_parent_ids) = self.parent_mapping.get(&old_commit_id).cloned() {
|
||||||
if let Some(new_parent_ids) = self.parent_mapping.get(&old_commit_id).cloned() {
|
// This is a commit that had already been rebased before `self` was created
|
||||||
// This is a commit that had already been rebased before `self` was created
|
// (i.e. it's part of the input for this rebase). We don't need
|
||||||
// (i.e. it's part of the input for this rebase). We don't need
|
// to rebase it, but we still want to update branches pointing
|
||||||
// to rebase it, but we still want to update branches pointing
|
// to the old commit.
|
||||||
// to the old commit.
|
self.update_references(old_commit_id, new_parent_ids, false)?;
|
||||||
self.update_references(old_commit_id, new_parent_ids, false)?;
|
return Ok(());
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some(divergent_ids) = self.divergent.get(&old_commit_id).cloned() {
|
|
||||||
// Leave divergent commits in place. Don't update `parent_mapping` since we
|
|
||||||
// don't want to rebase descendants either.
|
|
||||||
self.update_references(old_commit_id, divergent_ids, false)?;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let old_parent_ids = old_commit.parent_ids();
|
|
||||||
let new_parent_ids = self.new_parents(old_parent_ids);
|
|
||||||
if self.abandoned.contains(&old_commit_id) {
|
|
||||||
// Update the `new_parents` map so descendants are rebased correctly.
|
|
||||||
self.parent_mapping
|
|
||||||
.insert(old_commit_id.clone(), new_parent_ids.clone());
|
|
||||||
self.update_references(old_commit_id, new_parent_ids, true)?;
|
|
||||||
continue;
|
|
||||||
} else if new_parent_ids == old_parent_ids {
|
|
||||||
// The commit is already in place.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't create commit where one parent is an ancestor of another.
|
|
||||||
let head_set: HashSet<_> = self
|
|
||||||
.mut_repo
|
|
||||||
.index()
|
|
||||||
.heads(&mut new_parent_ids.iter())
|
|
||||||
.into_iter()
|
|
||||||
.collect();
|
|
||||||
let new_parents: Vec<_> = new_parent_ids
|
|
||||||
.iter()
|
|
||||||
.filter(|new_parent| head_set.contains(new_parent))
|
|
||||||
.map(|new_parent_id| self.mut_repo.store().get_commit(new_parent_id))
|
|
||||||
.try_collect()?;
|
|
||||||
let (new_commit, abandoned_old_commit) = rebase_commit_with_options(
|
|
||||||
self.settings,
|
|
||||||
self.mut_repo,
|
|
||||||
&old_commit,
|
|
||||||
&new_parents,
|
|
||||||
&self.options,
|
|
||||||
)?;
|
|
||||||
let previous_rebased_value = self
|
|
||||||
.rebased
|
|
||||||
.insert(old_commit_id.clone(), new_commit.id().clone());
|
|
||||||
let previous_mapping_value = self
|
|
||||||
.parent_mapping
|
|
||||||
.insert(old_commit_id.clone(), vec![new_commit.id().clone()]);
|
|
||||||
assert_eq!(
|
|
||||||
(previous_rebased_value, previous_mapping_value),
|
|
||||||
(None, None),
|
|
||||||
"Trying to rebase the same commit {old_commit_id:?} in two different ways",
|
|
||||||
);
|
|
||||||
self.update_references(
|
|
||||||
old_commit_id,
|
|
||||||
vec![new_commit.id().clone()],
|
|
||||||
abandoned_old_commit,
|
|
||||||
)?;
|
|
||||||
return Ok(Some(RebasedDescendant {
|
|
||||||
old_commit,
|
|
||||||
new_commit,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
Ok(None)
|
if let Some(divergent_ids) = self.divergent.get(&old_commit_id).cloned() {
|
||||||
|
// Leave divergent commits in place. Don't update `parent_mapping` since we
|
||||||
|
// don't want to rebase descendants either.
|
||||||
|
self.update_references(old_commit_id, divergent_ids, false)?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let old_parent_ids = old_commit.parent_ids();
|
||||||
|
let new_parent_ids = self.new_parents(old_parent_ids);
|
||||||
|
if self.abandoned.contains(&old_commit_id) {
|
||||||
|
// Update the `new_parents` map so descendants are rebased correctly.
|
||||||
|
self.parent_mapping
|
||||||
|
.insert(old_commit_id.clone(), new_parent_ids.clone());
|
||||||
|
self.update_references(old_commit_id, new_parent_ids, true)?;
|
||||||
|
return Ok(());
|
||||||
|
} else if new_parent_ids == old_parent_ids {
|
||||||
|
// The commit is already in place.
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't create commit where one parent is an ancestor of another.
|
||||||
|
let head_set: HashSet<_> = self
|
||||||
|
.mut_repo
|
||||||
|
.index()
|
||||||
|
.heads(&mut new_parent_ids.iter())
|
||||||
|
.into_iter()
|
||||||
|
.collect();
|
||||||
|
let new_parents: Vec<_> = new_parent_ids
|
||||||
|
.iter()
|
||||||
|
.filter(|new_parent| head_set.contains(new_parent))
|
||||||
|
.map(|new_parent_id| self.mut_repo.store().get_commit(new_parent_id))
|
||||||
|
.try_collect()?;
|
||||||
|
let (new_commit, abandoned_old_commit) = rebase_commit_with_options(
|
||||||
|
self.settings,
|
||||||
|
self.mut_repo,
|
||||||
|
&old_commit,
|
||||||
|
&new_parents,
|
||||||
|
&self.options,
|
||||||
|
)?;
|
||||||
|
let previous_rebased_value = self
|
||||||
|
.rebased
|
||||||
|
.insert(old_commit_id.clone(), new_commit.id().clone());
|
||||||
|
let previous_mapping_value = self
|
||||||
|
.parent_mapping
|
||||||
|
.insert(old_commit_id.clone(), vec![new_commit.id().clone()]);
|
||||||
|
assert_eq!(
|
||||||
|
(previous_rebased_value, previous_mapping_value),
|
||||||
|
(None, None),
|
||||||
|
"Trying to rebase the same commit {old_commit_id:?} in two different ways",
|
||||||
|
);
|
||||||
|
self.update_references(
|
||||||
|
old_commit_id,
|
||||||
|
vec![new_commit.id().clone()],
|
||||||
|
abandoned_old_commit,
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rebase_all(&mut self) -> Result<(), TreeMergeError> {
|
pub fn rebase_all(&mut self) -> Result<(), TreeMergeError> {
|
||||||
while self.rebase_next()?.is_some() {}
|
while let Some(old_commit) = self.to_visit.pop() {
|
||||||
|
self.rebase_one(old_commit)?;
|
||||||
|
}
|
||||||
let mut view = self.mut_repo.view().store_view().clone();
|
let mut view = self.mut_repo.view().store_view().clone();
|
||||||
for commit_id in &self.heads_to_remove {
|
for commit_id in &self.heads_to_remove {
|
||||||
view.head_ids.remove(commit_id);
|
view.head_ids.remove(commit_id);
|
||||||
|
@ -627,9 +623,3 @@ impl<'settings, 'repo> DescendantRebaser<'settings, 'repo> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
|
||||||
pub struct RebasedDescendant {
|
|
||||||
pub old_commit: Commit,
|
|
||||||
pub new_commit: Commit,
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue