From 29b2084e43e166bbc5c4094eecbec517f9bc98ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Lehmann?= Date: Mon, 6 Oct 2025 22:53:53 +0200 Subject: [PATCH] squash: fix -A -B behavior and add the corresponding test. The children of the new commit were not properly rebased on their parents. fix: #7636 --- CHANGELOG.md | 3 +++ cli/src/commands/squash.rs | 13 +++++++++++- cli/tests/test_squash_command.rs | 35 ++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98728dc7423..6971ae28c4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). * `jj metaedit --author-timestamp` twice with the same value no longer edits the change twice in some cases. +* `jj squash`: fixed improper revision rebase when both `--insert-after` and + `--insert-before` were used. + ## [0.34.0] - 2025-10-01 ### Release highlights diff --git a/cli/src/commands/squash.rs b/cli/src/commands/squash.rs index 6d33ada4f7b..e6011a288b7 100644 --- a/cli/src/commands/squash.rs +++ b/cli/src/commands/squash.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::collections::HashMap; +use std::iter::once; use clap_complete::ArgValueCandidates; use clap_complete::ArgValueCompleter; @@ -273,11 +274,21 @@ pub(crate) fn cmd_squash( .write()?; let mut rewritten = HashMap::new(); tx.repo_mut() - .transform_descendants(child_ids, async |mut rewriter| { + .transform_descendants(child_ids.clone(), async |mut rewriter| { let old_commit_id = rewriter.old_commit().id().clone(); for parent_id in &parent_ids { rewriter.replace_parent(parent_id, [commit.id()]); } + let new_parents = rewriter.new_parents(); + if child_ids.contains(&old_commit_id) && !new_parents.contains(commit.id()) { + rewriter.set_new_parents( + new_parents + .iter() + .cloned() + .chain(once(commit.id().clone())) + .collect(), + ); + } let new_commit = rewriter.rebase().await?.write()?; rewritten.insert(old_commit_id, new_commit); num_rebased += 1; diff --git a/cli/tests/test_squash_command.rs b/cli/tests/test_squash_command.rs index ec0ed983cfb..17aaefa1101 100644 --- a/cli/tests/test_squash_command.rs +++ b/cli/tests/test_squash_command.rs @@ -2211,6 +2211,41 @@ fn test_squash_to_new_commit() { -- operation a8bb9104802c new empty commit [EOF] "); + + // --before and --after together + work_dir.run_jj(["op", "restore", &setup_opid]).success(); + let output = work_dir.run_jj([ + "squash", + "-m", + "file 3&4", + "-f", + "kkmpptxzrspx::", + "--insert-after", + "root()", + "--insert-before", + "rlvkpnrzqnoo", + ]); + insta::assert_snapshot!(output, @r" + ------- stderr ------- + Created new commit pyoswmwk d5aa6638 file 3&4 + Rebased 1 descendant commits + Working copy (@) now at: yqnpwwmq 68513612 (empty) (no description set) + Parent commit (@-) : rlvkpnrz ed79225c file2 + [EOF] + "); + + insta::assert_snapshot!(get_log_with_summary(&work_dir), @r" + @ yqnpwwmqtwyk + ○ rlvkpnrzqnoo file2 + ├─╮ A file2 + │ ○ pyoswmwkkqyt file 3&4 + │ │ A file3 + │ │ A file4 + ○ │ qpvuntsmwlqt file1 + ├─╯ A file1 + ◆ zzzzzzzzzzzz + [EOF] + "); } #[must_use]