Skip to content

Commit

Permalink
Rewrite rebasing in jj split using transform_descendants()
Browse files Browse the repository at this point in the history
This is following on the rewrite for `parallelize`.

- #3521

Since rebase_descendants from rebase.rs is no longer used outside of that file,
it can be made private again.
  • Loading branch information
emesterhazy committed Apr 20, 2024
1 parent 0fb582e commit 6da4e91
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 50 deletions.
2 changes: 1 addition & 1 deletion cli/src/commands/rebase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ fn rebase_branch(
}

/// Rebases `old_commits` onto `new_parents`.
pub fn rebase_descendants(
fn rebase_descendants(
tx: &mut WorkspaceCommandTransaction,
settings: &UserSettings,
new_parents: Vec<Commit>,
Expand Down
77 changes: 28 additions & 49 deletions cli/src/commands/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,13 @@
// limitations under the License.
use std::io::Write;

use itertools::Itertools;
use jj_lib::commit::Commit;
use jj_lib::object_id::ObjectId;
use jj_lib::repo::Repo;
use jj_lib::revset::{RevsetExpression, RevsetIteratorExt};
use jj_lib::rewrite::merge_commit_trees;
use jj_lib::settings::UserSettings;
use tracing::instrument;

use crate::cli_util::{CommandHelper, RevisionArg, WorkspaceCommandTransaction};
use crate::cli_util::{CommandHelper, RevisionArg};
use crate::command_error::CommandError;
use crate::commands::rebase::rebase_descendants;
use crate::description_util::{description_template_for_commit, edit_description};
use crate::ui::Ui;

Expand Down Expand Up @@ -179,16 +174,33 @@ the operation will be aborted.
// commit.
tx.mut_repo()
.set_rewritten_commit(commit.id().clone(), second_commit.id().clone());
let num_rebased = if args.siblings {
rebase_children_for_siblings_split(
&mut tx,
command.settings(),
&commit,
vec![first_commit.clone(), second_commit.clone()],
)?
} else {
tx.mut_repo().rebase_descendants(command.settings())?
};
let mut num_rebased = 0;
tx.mut_repo().transform_descendants(
command.settings(),
vec![commit.id().clone()],
|mut rewriter| {
let old_parents = rewriter.old_commit().parent_ids();
// Reserve space up front since we know we're adding at most one more parent.
let mut new_parents = Vec::with_capacity(old_parents.len() + 1);
for parent in old_parents {
if parent != commit.id() {
new_parents.push(parent.clone());
continue;
}
if args.siblings {
new_parents.push(first_commit.id().clone());
}
new_parents.push(second_commit.id().clone());
num_rebased += 1;
}
rewriter.set_new_rewritten_parents(new_parents);
if rewriter.parents_changed() {
let builder = rewriter.rebase(command.settings())?;
builder.write()?;
}
Ok(())
},
)?;

if let Some(mut formatter) = ui.status_formatter() {
if num_rebased > 0 {
Expand All @@ -203,36 +215,3 @@ the operation will be aborted.
tx.finish(ui, format!("split commit {}", commit.id().hex()))?;
Ok(())
}

// Rebases the children of `original_commit` by replacing `original_commit` with
// `new_siblings`. Any parents other than `original_commit` will remain after
// the rebase.
fn rebase_children_for_siblings_split(
tx: &mut WorkspaceCommandTransaction,
settings: &UserSettings,
original_commit: &Commit,
new_siblings: Vec<Commit>,
) -> Result<usize, CommandError> {
let children: Vec<Commit> = RevsetExpression::commit(original_commit.id().clone())
.children()
.evaluate_programmatic(tx.base_repo().as_ref())?
.iter()
.commits(tx.base_repo().store())
.try_collect()?;
let mut num_rebased = 0;
for child in children {
let new_parents = child
.parents()
.into_iter()
.flat_map(|c| {
if c.id() == original_commit.id() {
new_siblings.clone()
} else {
vec![c]
}
})
.collect_vec();
num_rebased += rebase_descendants(tx, settings, new_parents, &[child], Default::default())?;
}
Ok(num_rebased)
}

0 comments on commit 6da4e91

Please sign in to comment.