gerrit: check default upload revisions are rewritable

The implicit revision selection path for `jj gerrit upload` bypassed the
usual rewritability check. This leads to a panic if the selected revision
was immutable. Run the check before continuing so the command fails with a
user error instead.

Fixes: #9398
This commit is contained in:
rishiad
2026-05-01 23:43:51 +09:30
committed by Austin Seipp
parent f5225927be
commit 755b7b7b51
3 changed files with 49 additions and 2 deletions

View File

@@ -67,6 +67,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
* Pre-existing Git submodule directories are no longer considered conflicts in
checkouts. [#8065](https://github.com/jj-vcs/jj/issues/8065).
* Fixed a panic in `jj gerrit upload` when run without `-r` and the
inferred revision was immutable. [#9398](https://github.com/jj-vcs/jj/issues/9398)
## [0.40.0] - 2026-04-01
### Release highlights

View File

@@ -430,7 +430,7 @@ pub async fn cmd_gerrit_upload(
}
// This distinguishes between the "squash workflow" and "edit workflow".
Some(commit) => {
if commit.description().is_empty() {
let revisions = if commit.description().is_empty() {
let parents = commit.parent_ids();
if parents.len() != 1 {
return Err(user_error(
@@ -447,7 +447,14 @@ pub async fn cmd_gerrit_upload(
} else {
writeln!(ui.status(), "No revision provided. Defaulting to @")?;
vec![commit.id().clone()]
}
};
let revisions_expr = RevsetExpression::commits(revisions.clone());
workspace_command
.check_rewritable_expr(&revisions_expr)
.await?;
revisions
}
}
} else {

View File

@@ -149,6 +149,43 @@ fn test_gerrit_upload_default_revision() {
");
}
#[test]
fn test_gerrit_upload_default_revision_already_in_trunk() {
let test_env = TestEnvironment::default();
test_env
.run_jj_in(".", ["git", "init", "--colocate", "remote"])
.success();
let remote_dir = test_env.work_dir("remote");
create_commit(&remote_dir, "main", &[]);
test_env
.run_jj_in(".", ["git", "clone", "remote", "local"])
.success();
let local_dir = test_env.work_dir("local");
test_env.add_config(r#"gerrit.default-remote="origin""#);
test_env.add_config(r#"gerrit.default-remote-branch="main""#);
test_env.add_config(r#"revset-aliases."trunk()" = "main@origin""#);
// Make @ an empty working-copy commit over immutable main@origin.
local_dir.run_jj(["new", "main@origin"]).success();
local_dir.run_jj(["describe", "-m="]).success();
let output = local_dir.run_jj(["gerrit", "upload", "--dry-run"]);
insta::assert_snapshot!(output, @"
------- stderr -------
No revision provided and @ has no description. Defaulting to @-
Error: Commit 57df4838fd85 is immutable
Hint: Could not modify commit: rlvkpnrz 57df4838 main@origin | main
Hint: Immutable commits are used to protect shared history.
Hint: For more information, see:
- https://docs.jj-vcs.dev/latest/config/#set-of-immutable-commits
- `jj help -k config`, \"Set of immutable commits\"
Hint: This operation would rewrite 1 immutable commits.
[EOF]
[exit status: 1]
");
}
#[test]
fn test_gerrit_upload_option_failure() {
let test_env = TestEnvironment::default();