Skip to content

Commit

Permalink
rebase: skip rebasing if commit's parents are identical to new parents
Browse files Browse the repository at this point in the history
  • Loading branch information
bnjmnt4n committed Mar 25, 2024
1 parent 15ff7df commit 7043382
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
24 changes: 23 additions & 1 deletion cli/src/commands/rebase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,27 @@ fn rebase_descendants(
rebase_options: RebaseOptions,
) -> Result<(), CommandError> {
workspace_command.check_rewritable(old_commits)?;
let (skipped_commits, old_commits) = old_commits
.iter()
.partition::<Vec<_>, _>(|commit| commit.parents().eq(new_parents));
for commit in skipped_commits.iter() {
writeln!(
ui.stderr(),
"Skipping rebase of commit {}",
short_commit_hash(commit.id()),
)?;
continue;
}
if old_commits.is_empty() {
return Ok(());
}
for old_commit in old_commits.iter() {
check_rebase_destinations(workspace_command.repo(), new_parents, old_commit)?;
}
let mut tx = workspace_command.start_transaction();
// `rebase_descendants` takes care of sorting in reverse topological order, so
// no need to do it here.
for old_commit in old_commits {
for old_commit in old_commits.iter() {
rebase_commit_with_options(
settings,
tx.mut_repo(),
Expand Down Expand Up @@ -330,6 +344,14 @@ fn rebase_revision(
) -> Result<(), CommandError> {
let old_commit = workspace_command.resolve_single_rev(rev_str)?;
workspace_command.check_rewritable([&old_commit])?;
if old_commit.parents().eq(new_parents) {
writeln!(
ui.stderr(),
"Skipping rebase of commit {}",
short_commit_hash(old_commit.id()),
)?;
return Ok(());
}
if new_parents.contains(&old_commit) {
return Err(user_error(format!(
"Cannot rebase {} onto itself",
Expand Down
4 changes: 1 addition & 3 deletions cli/tests/test_duplicate_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,7 @@ fn test_rebase_duplicates() {
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["rebase", "-s", "a", "-d", "a-"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Rebased 4 commits
Working copy now at: zsuskuln 29bd36b6 b | b
Parent commit : rlvkpnrz 2f6dc5a1 a | a
Skipping rebase of commit 2443ea76b0b1
"###);
// Some of the duplicate commits' timestamps were changed a little to make them
// have distinct commit ids.
Expand Down
7 changes: 3 additions & 4 deletions cli/tests/test_rebase_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ fn test_rebase_branch() {
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["rebase", "-b=e", "-b=d", "-d=b"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Rebased 2 commits
Skipping rebase of commit 514fa6b265d4
Rebased 1 commits
Working copy now at: znkkpsqq 9ca2a154 e | e
Parent commit : zsuskuln 1394f625 b | b
Added 1 files, modified 0 files, removed 0 files
Expand Down Expand Up @@ -692,9 +693,7 @@ fn test_rebase_with_child_and_descendant_bug_2600() {
test_env.jj_cmd_ok(&repo_path, &["rebase", "-s", "base", "-d", "root()"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Rebased 4 commits
Working copy now at: vruxwmqv 13b23fa1 c | c
Parent commit : royxmykx 15092f8a b | b
Skipping rebase of commit 0c61db1be8c8
"###);
// This should be a no-op
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
Expand Down

0 comments on commit 7043382

Please sign in to comment.