squash: accept multiple --from arguments

Since multiple revisions can be specified, there's no reason to reject multiple
--from arguments.
This commit is contained in:
Yuya Nishihara 2024-04-03 12:25:06 +09:00
parent 2dcdc7fb3f
commit eaa15f804d
3 changed files with 22 additions and 10 deletions

View file

@ -53,9 +53,9 @@ pub(crate) struct SquashArgs {
/// Revision to squash into its parent (default: @)
#[arg(long, short)]
revision: Option<RevisionArg>,
/// Revision to squash from (default: @)
/// Revision(s) to squash from (default: @)
#[arg(long, conflicts_with = "revision")]
from: Option<RevisionArg>,
from: Vec<RevisionArg>,
/// Revision to squash into (default: @)
#[arg(long, conflicts_with = "revision", visible_alias = "to")]
into: Option<RevisionArg>,
@ -83,11 +83,14 @@ pub(crate) fn cmd_squash(
let mut sources: Vec<Commit>;
let destination;
if args.from.is_some() || args.into.is_some() {
sources = workspace_command
.parse_revset(args.from.as_ref().unwrap_or(&RevisionArg::AT))?
.evaluate_to_commits()?
.try_collect()?;
if !args.from.is_empty() || args.into.is_some() {
sources = if args.from.is_empty() {
workspace_command.parse_revset(&RevisionArg::AT)?
} else {
workspace_command.parse_union_revsets(&args.from)?
}
.evaluate_to_commits()?
.try_collect()?;
destination =
workspace_command.resolve_single_rev(args.into.as_ref().unwrap_or(&RevisionArg::AT))?;
if sources.iter().any(|source| source.id() == destination.id()) {
@ -124,7 +127,7 @@ pub(crate) fn cmd_squash(
matcher.as_ref(),
&diff_selector,
description,
args.revision.is_none() && args.from.is_none() && args.into.is_none(),
args.revision.is_none() && args.from.is_empty() && args.into.is_none(),
&args.paths,
)?;
tx.finish(ui, tx_description)?;

View file

@ -1720,7 +1720,7 @@ If a working-copy commit gets abandoned, it will be given a new, empty commit. T
###### **Options:**
* `-r`, `--revision <REVISION>` — Revision to squash into its parent (default: @)
* `--from <FROM>` — Revision to squash from (default: @)
* `--from <FROM>` — Revision(s) to squash from (default: @)
* `--into <INTO>` — Revision to squash into (default: @)
* `-m`, `--message <MESSAGE>` — The description to use for squashed revision (don't open editor)
* `-i`, `--interactive` — Interactively choose which parts to squash

View file

@ -629,7 +629,8 @@ fn test_squash_from_multiple() {
"###);
// Squash a few commits sideways
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["squash", "--from=b|c", "--into=d"]);
let (stdout, stderr) =
test_env.jj_cmd_ok(&repo_path, &["squash", "--from=b", "--from=c", "--into=d"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Rebased 2 descendant commits
@ -690,6 +691,14 @@ fn test_squash_from_multiple() {
insta::assert_snapshot!(stdout, @r###"
f
"###);
// Empty squash shouldn't crash (could be noop)
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["squash", "--from=none()"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: xznxytkn 68d54010 (empty) (no description set)
Parent commit : yostqsxw b7bc1dda e f | (no description set)
"###);
}
#[test]