diff --git a/cli/tests/test_rebase_command.rs b/cli/tests/test_rebase_command.rs index 0381e3cba..181453770 100644 --- a/cli/tests/test_rebase_command.rs +++ b/cli/tests/test_rebase_command.rs @@ -2521,17 +2521,17 @@ fn test_rebase_skip_emptied_descendants() { insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Skipped rebase of 1 commits that were already in place - Rebased 2 descendant commits - Abandoned 1 newly emptied commits - Working copy now at: znkkpsqq 873ada86 (empty) also already empty - Parent commit : yostqsxw bfc5dad7 (empty) already empty + Rebased 3 descendant commits + Working copy now at: znkkpsqq 353bac5c (empty) also already empty + Parent commit : yostqsxw 0a3f76fd (empty) already empty "#); - // TODO: Commits not in the rebase target set should not be abandoned even - // if they were emptied. + // Commits not in the rebase target set should not be abandoned even if they + // were emptied. insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["log", "-T", "description"]), @r#" @ also already empty ○ already empty + ○ c (will become empty) ○ b ○ a ◆ diff --git a/lib/src/rewrite.rs b/lib/src/rewrite.rs index 5e531552c..34d351892 100644 --- a/lib/src/rewrite.rs +++ b/lib/src/rewrite.rs @@ -826,6 +826,12 @@ pub fn move_commits( let mut num_skipped_rebases = 0; let mut num_abandoned = 0; + // Always keep empty commits when rebasing descendants. + let rebase_descendant_options = &RebaseOptions { + empty: EmptyBehaviour::Keep, + simplify_ancestor_merge: options.simplify_ancestor_merge, + }; + // Rebase each commit onto its new parents in the reverse topological order // computed above. while let Some(old_commit_id) = to_visit.pop() { @@ -834,10 +840,19 @@ pub fn move_commits( let new_parent_ids = mut_repo.new_parents(parent_ids); let rewriter = CommitRewriter::new(mut_repo, old_commit.clone(), new_parent_ids); if rewriter.parents_changed() { - let rebased_commit = rebase_commit_with_options(settings, rewriter, options)?; + let is_target_commit = target_commit_ids.contains(&old_commit_id); + let rebased_commit = rebase_commit_with_options( + settings, + rewriter, + if is_target_commit { + options + } else { + rebase_descendant_options + }, + )?; if let RebasedCommit::Abandoned { .. } = rebased_commit { num_abandoned += 1; - } else if target_commit_ids.contains(&old_commit_id) { + } else if is_target_commit { num_rebased_targets += 1; } else { num_rebased_descendants += 1;