Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 12 additions & 1 deletion cli/src/commands/squash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

use std::collections::HashMap;
use std::iter::once;

use clap_complete::ArgValueCandidates;
use clap_complete::ArgValueCompleter;
Expand Down Expand Up @@ -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;
Expand Down
35 changes: 35 additions & 0 deletions cli/tests/test_squash_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Loading