diff --git a/cli/src/cli_util.rs b/cli/src/cli_util.rs index 8afdf2d37..b4119918e 100644 --- a/cli/src/cli_util.rs +++ b/cli/src/cli_util.rs @@ -965,10 +965,18 @@ impl WorkspaceCommandHelper { .map(|commit| commit.id().clone()) .collect(), ); - let immutable = revset_util::parse_immutable_expression(&self.revset_parse_context())?; + let immutable = revset_util::parse_immutable_expression(&self.revset_parse_context()) + .map_err(|e| { + config_error_with_message("Invalid `revset-aliases.immutable_heads()`", e) + })?; let mut expression = self.attach_revset_evaluator(immutable)?; expression.intersect_with(&to_rewrite_revset); - if let Some(commit_id) = expression.evaluate_to_commit_ids()?.next() { + + let mut commit_id_iter = expression.evaluate_to_commit_ids().map_err(|e| { + config_error_with_message("Invalid `revset-aliases.immutable_heads()`", e) + })?; + + if let Some(commit_id) = commit_id_iter.next() { let error = if &commit_id == self.repo().store().root_commit_id() { user_error(format!( "The root commit {} is immutable", diff --git a/cli/tests/test_immutable_commits.rs b/cli/tests/test_immutable_commits.rs index 57c77ecfc..2d5e83b4a 100644 --- a/cli/tests/test_immutable_commits.rs +++ b/cli/tests/test_immutable_commits.rs @@ -56,6 +56,30 @@ fn test_rewrite_immutable_generic() { insta::assert_snapshot!(stderr, @r###" Error: The root commit 000000000000 is immutable "###); + + // Error mutating the repo if immutable_heads() uses a ref that can't be + // resolved + test_env.add_config(r#"revset-aliases."immutable_heads()" = "branch_that_does_not_exist""#); + let stderr = test_env.jj_cmd_failure(&repo_path, &["new", "main"]); + insta::assert_snapshot!(stderr, @r###" + Config error: Invalid `revset-aliases.immutable_heads()` + Caused by: Revision "branch_that_does_not_exist" doesn't exist + For help, see https://github.com/martinvonz/jj/blob/main/docs/config.md. + "###); + + // Mutating the repo works if ref is wrapped in present() + test_env.add_config( + r#"revset-aliases."immutable_heads()" = "present(branch_that_does_not_exist)""#, + ); + let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["new", "main"]); + insta::assert_snapshot!(stdout, @r###" + "###); + insta::assert_snapshot!(stderr, @r###" + Working copy now at: kpqxywon dbce15b4 (empty) (no description set) + Parent commit : kkmpptxz c8d4c7ca main | b + Added 0 files, modified 1 files, removed 0 files + "###); + // Error if we redefine immutable_heads() with an argument test_env.add_config(r#"revset-aliases."immutable_heads(foo)" = "none()""#); let stderr = test_env.jj_cmd_failure(&repo_path, &["edit", "root()"]); diff --git a/docs/contributing.md b/docs/contributing.md index c4c75c644..881185385 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -114,7 +114,7 @@ You will probably also want to make the `gh-pages` branch immutable (and thereby hidden from the default `jj log` output) by running the following in your repo: ```shell -jj config set --repo "revset-aliases.immutable_heads()" "main@origin | gh-pages@origin" +jj config set --repo "revset-aliases.immutable_heads()" 'remote_branches(exact:"main") | remote_branches(exact:"gh-pages")' ``` ### Summary