diff --git a/CHANGELOG.md b/CHANGELOG.md index c2b040bc35..32a3971838 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). "diff3" conflict style, meaning it is more likely to work with external tools, but it doesn't support conflicts with more than 2 sides. +* `jj simplify-parents` now supports configuring the default revset when no + `--source` or `--revisions` arguments are provided with the + `revsets.simplify-parents` config. + ### Fixed bugs * `jj config unset ` no longer removes a table (such as `[ui]`.) diff --git a/cli/src/commands/simplify_parents.rs b/cli/src/commands/simplify_parents.rs index 8d68cfdf3f..52f052fae9 100644 --- a/cli/src/commands/simplify_parents.rs +++ b/cli/src/commands/simplify_parents.rs @@ -20,22 +20,17 @@ use crate::ui::Ui; /// ancestor of B, A will be rewritten to have only B as a parent instead of /// B+C. #[derive(clap::Args, Clone, Debug)] -#[command(group = clap::ArgGroup::new("revision-args").multiple(true).required(true))] pub(crate) struct SimplifyParentsArgs { /// Simplify specified revision(s) together with their trees of descendants /// (can be repeated) - #[arg( - long, short, - group = "revision-args", - add = ArgValueCandidates::new(complete::mutable_revisions), - )] + #[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))] source: Vec, /// Simplify specified revision(s) (can be repeated) - #[arg( - long, short, - group = "revision-args", - add = ArgValueCandidates::new(complete::mutable_revisions), - )] + /// + /// If both `--source` and `--revisions` are not provided, this defaults to + /// the `revsets.simplify-parents` setting, or `reachable(@, mutable())` + /// if it is not set. + #[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))] revisions: Vec, } @@ -45,16 +40,27 @@ pub(crate) fn cmd_simplify_parents( args: &SimplifyParentsArgs, ) -> Result<(), CommandError> { let mut workspace_command = command.workspace_helper(ui)?; - let revs = RevsetExpression::descendants( + let revs = if args.source.is_empty() && args.revisions.is_empty() { + let revs = command + .settings() + .config() + .get_string("revsets.simplify-parents")?; workspace_command - .parse_union_revsets(ui, &args.source)? - .expression(), - ) - .union( - workspace_command - .parse_union_revsets(ui, &args.revisions)? - .expression(), - ); + .parse_revset(ui, &RevisionArg::from(revs))? + .expression() + .clone() + } else { + RevsetExpression::descendants( + workspace_command + .parse_union_revsets(ui, &args.source)? + .expression(), + ) + .union( + workspace_command + .parse_union_revsets(ui, &args.revisions)? + .expression(), + ) + }; let commit_ids: Vec<_> = workspace_command .attach_revset_evaluator(revs) .evaluate_to_commit_ids()? diff --git a/cli/src/config-schema.json b/cli/src/config-schema.json index 436f86cf26..cf7d381994 100644 --- a/cli/src/config-schema.json +++ b/cli/src/config-schema.json @@ -421,6 +421,11 @@ "type": "string", "description": "Revisions to give shorter change and commit IDs to", "default": "" + }, + "simplify-parents": { + "type": "string", + "description": "Default set of revisions to simplify when no explicit revset is given for jj simplify-parents", + "default": "reachable(@, mutable())" } }, "additionalProperties": { diff --git a/cli/src/config/revsets.toml b/cli/src/config/revsets.toml index e036670dcb..5cc9801eea 100644 --- a/cli/src/config/revsets.toml +++ b/cli/src/config/revsets.toml @@ -3,6 +3,7 @@ [revsets] fix = "reachable(@, mutable())" +simplify-parents = "reachable(@, mutable())" # log revset is also used as the default short-prefixes. If it failed to # evaluate, lengthy warning messages would be printed. Use present(expr) to # suppress symbol resolution error. @@ -13,8 +14,8 @@ log = "present(@) | ancestors(immutable_heads().., 2) | present(trunk())" # symbol resolution error should be suppressed. 'trunk()' = ''' latest( - remote_bookmarks(exact:"main", exact:"origin") | - remote_bookmarks(exact:"master", exact:"origin") | + remote_bookmarks(exact:"main", exact:"origin") | + remote_bookmarks(exact:"master", exact:"origin") | remote_bookmarks(exact:"trunk", exact:"origin") | remote_bookmarks(exact:"main", exact:"upstream") | remote_bookmarks(exact:"master", exact:"upstream") | diff --git a/cli/tests/cli-reference@.md.snap b/cli/tests/cli-reference@.md.snap index d89f433728..8c12602997 100644 --- a/cli/tests/cli-reference@.md.snap +++ b/cli/tests/cli-reference@.md.snap @@ -1975,13 +1975,15 @@ Removes all parents of each of the specified revisions that are also indirect an In other words, for all (A, B, C) where A has (B, C) as parents and C is an ancestor of B, A will be rewritten to have only B as a parent instead of B+C. -**Usage:** `jj simplify-parents <--source |--revisions >` +**Usage:** `jj simplify-parents [OPTIONS]` ###### **Options:** * `-s`, `--source ` — Simplify specified revision(s) together with their trees of descendants (can be repeated) * `-r`, `--revisions ` — Simplify specified revision(s) (can be repeated) + If both `--source` and `--revisions` are not provided, this defaults to the `revsets.simplify-parents` setting, or `reachable(@, mutable())` if it is not set. + ## `jj sparse` diff --git a/cli/tests/test_simplify_parents_command.rs b/cli/tests/test_simplify_parents_command.rs index aa360045d4..ba192de3db 100644 --- a/cli/tests/test_simplify_parents_command.rs +++ b/cli/tests/test_simplify_parents_command.rs @@ -36,21 +36,6 @@ fn create_commit(test_env: &TestEnvironment, repo_path: &Path, name: &str, paren test_env.jj_cmd_ok(repo_path, &["bookmark", "create", name]); } -#[test] -fn test_simplify_parents_no_args() { - let (test_env, repo_path) = create_repo(); - - let stderr = test_env.jj_cmd_cli_error(&repo_path, &["simplify-parents"]); - insta::assert_snapshot!(stderr, @r###" - error: the following required arguments were not provided: - <--source |--revisions > - - Usage: jj simplify-parents <--source |--revisions > - - For more information, try '--help'. - "###); -} - #[test] fn test_simplify_parents_no_commits() { let (test_env, repo_path) = create_repo(); @@ -248,3 +233,74 @@ fn test_simplify_parents_multiple_redundant_parents() { ◆ "#); } + +#[test] +fn test_simplify_parents_no_args() { + let (test_env, repo_path) = create_repo(); + + create_commit(&test_env, &repo_path, "a", &["root()"]); + create_commit(&test_env, &repo_path, "b", &["a"]); + create_commit(&test_env, &repo_path, "c", &["a", "b"]); + create_commit(&test_env, &repo_path, "d", &["c"]); + create_commit(&test_env, &repo_path, "e", &["d"]); + create_commit(&test_env, &repo_path, "f", &["d", "e"]); + let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "all()", "-T", "description"]); + insta::assert_snapshot!(stdout, @r#" + @ f + ├─╮ + │ ○ e + ├─╯ + ○ d + ○ c + ├─╮ + │ ○ b + ├─╯ + ○ a + ◆ + "#); + let setup_opid = test_env.current_operation_id(&repo_path); + + let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["simplify-parents"]); + insta::assert_snapshot!(stdout, @""); + insta::assert_snapshot!(stderr, @r#" + Removed 2 edges from 2 out of 6 commits. + Rebased 2 descendant commits + Working copy now at: kmkuslsw 8cc01e1b f | f + Parent commit : znkkpsqq 040ae3a6 e | e + "#); + + let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "all()", "-T", "description"]); + insta::assert_snapshot!(stdout, @r#" + @ f + ○ e + ○ d + ○ c + ○ b + ○ a + ◆ + "#); + + // Test with custom `revsets.simplify-parents`. + test_env.jj_cmd_ok(&repo_path, &["op", "restore", &setup_opid]); + test_env.add_config(r#"revsets.simplify-parents = "d::""#); + let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["simplify-parents"]); + insta::assert_snapshot!(stdout, @""); + insta::assert_snapshot!(stderr, @r#" + Removed 1 edges from 1 out of 3 commits. + Working copy now at: kmkuslsw 0c6b4c43 f | f + Parent commit : znkkpsqq 6a679611 e | e + "#); + + let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-r", "all()", "-T", "description"]); + insta::assert_snapshot!(stdout, @r#" + @ f + ○ e + ○ d + ○ c + ├─╮ + │ ○ b + ├─╯ + ○ a + ◆ + "#); +}