rewrite: move_commits: do not allow emptying of descendants

This commit is contained in:
Benjamin Tan 2024-11-06 07:38:28 +08:00
parent 5b8e755909
commit 9b99f4810c
2 changed files with 23 additions and 8 deletions

View file

@ -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

View file

@ -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;