diff --git a/CHANGELOG.md b/CHANGELOG.md index 90084f17c6..b05d7f22f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Commit objects in templates now have a `mine() -> Boolean` method analog to the same function in revsets. It evaluates to true if the email of the commit author matches the current `user.email`. +* A new config option `revsets.always-allow-large-revsets` has been added to + allow large revsets expressions in some commands, without the `all:` prefix. + ### Fixed bugs ## [0.16.0] - 2024-04-03 diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index a393fc58d8..00ec65322f 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -775,7 +775,10 @@ impl WorkspaceCommandHelper { let (expression, modifier) = self.parse_revset_with_modifier(revision_arg)?; let all = match modifier { Some(RevsetModifier::All) => true, - None => false, + None => self + .settings + .config() + .get_bool("revsets.always-allow-large-revsets")?, }; if all { for commit in expression.evaluate_to_commits()? { diff --git a/cli/src/config-schema.json b/cli/src/config-schema.json index a6bca7fffc..c7a95910c4 100644 --- a/cli/src/config-schema.json +++ b/cli/src/config-schema.json @@ -180,14 +180,14 @@ "pattern": "^#[0-9a-fA-F]{6}$" }, "colors": { - "oneOf": [ - { - "$ref": "#/properties/colors/definitions/colorNames" - }, - { - "$ref": "#/properties/colors/definitions/hexColor" - } - ] + "oneOf": [ + { + "$ref": "#/properties/colors/definitions/colorNames" + }, + { + "$ref": "#/properties/colors/definitions/hexColor" + } + ] }, "basicFormatterLabels": { "enum": [ @@ -334,6 +334,11 @@ "type": "string", "description": "Revisions to give shorter change and commit IDs to", "default": "" + }, + "always-allow-large-revsets": { + "type": "boolean", + "description": "Whether to allow large revsets to be used in all commands without the `all:` modifier", + "default": false } }, "additionalProperties": { @@ -391,7 +396,10 @@ "properties": { "backend": { "type": "string", - "enum": ["gpg", "ssh"], + "enum": [ + "gpg", + "ssh" + ], "description": "The backend to use for signing commits" }, "key": { diff --git a/cli/src/config/misc.toml b/cli/src/config/misc.toml index 0b2e1b94db..c803751254 100644 --- a/cli/src/config/misc.toml +++ b/cli/src/config/misc.toml @@ -5,6 +5,8 @@ amend = ["squash"] co = ["checkout"] unamend = ["unsquash"] +[revsets] +always-allow-large-revsets = false [format] tree-level-conflicts = true diff --git a/cli/tests/test_rebase_command.rs b/cli/tests/test_rebase_command.rs index fec0f235bc..eff4715066 100644 --- a/cli/tests/test_rebase_command.rs +++ b/cli/tests/test_rebase_command.rs @@ -484,6 +484,8 @@ fn test_rebase_multiple_destinations() { zsuskuln d370aee1 b | b Hint: Prefix the expression with 'all:' to allow any number of revisions (i.e. 'all:b|c'). "###); + + // try with 'all:', and succeed let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["rebase", "-r", "a", "-d", "all:b|c"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @""); @@ -496,6 +498,32 @@ fn test_rebase_multiple_destinations() { ◉ "###); + // undo and do it again, but with 'revsets.always-allow-large-revsets' + let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["undo"]); + insta::assert_snapshot!(stdout, @""); + insta::assert_snapshot!(stderr, @""); + let (stdout, stderr) = test_env.jj_cmd_ok( + &repo_path, + &[ + "rebase", + "--config-toml=revsets.always-allow-large-revsets=true", + "-r", + "a", + "-d", + "b|c", + ], + ); + insta::assert_snapshot!(stdout, @""); + insta::assert_snapshot!(stderr, @""); + insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" + ◉ a + ├─╮ + │ ◉ b + @ │ c + ├─╯ + ◉ + "###); + let stderr = test_env.jj_cmd_failure(&repo_path, &["rebase", "-r", "a", "-d", "b", "-d", "b"]); insta::assert_snapshot!(stderr, @r###" Error: More than one revset resolved to revision d370aee184ba diff --git a/docs/config.md b/docs/config.md index f00257c4f4..1bbc768fb0 100644 --- a/docs/config.md +++ b/docs/config.md @@ -704,6 +704,30 @@ executable on your system](https://facebook.github.io/watchman/docs/install). Debugging commands are available under `jj debug watchman`. +## Revset behavior + +### Allow "large" revsets by default + +Certain commands (such as `jj rebase`) can take multiple revset arguments, and +each of these may resolve to one-or-many revisions. By default, `jj` will not +allow revsets that resolve to more than one revision — a so-called "large +revset" — and will ask you to confirm that you want to proceed by +prefixing it with the `all:` modifier. + +For instance, to add a new parent `abc` to the commit `xyz`, you may use `jj +rebase`: + +``` +jj rebase -r xyz -d "all:xyz-" -d "abc" +``` + +`jj` requires the `all:` prefix for the above command. However, you may disable +this behavior by setting `revsets.always-allow-large-revsets` to `true`: + +```toml +revsets.always-allow-large-revsets = true +``` + ## Ways to specify `jj` config: details ### User config file