mirror of
https://github.com/jj-vcs/jj.git
synced 2026-07-03 14:02:54 +08:00
Note: we use longer short change-IDs in test_abandon_command to avoid false codebook detection.
875 lines
29 KiB
Rust
875 lines
29 KiB
Rust
// Copyright 2025 The Jujutsu Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use testutils::TestResult;
|
|
|
|
use crate::common::TestEnvironment;
|
|
use crate::common::create_commit;
|
|
use crate::common::create_commit_with_files;
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_dryrun() {
|
|
let test_env = TestEnvironment::default();
|
|
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
|
|
create_commit(&work_dir, "a", &[]);
|
|
create_commit(&work_dir, "b", &["a"]);
|
|
create_commit(&work_dir, "c", &["a"]);
|
|
let output = work_dir.run_jj(["gerrit", "upload", "-r", "b"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: No remote specified, and no 'gerrit' remote was found
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
// With remote specified but.
|
|
test_env.add_config(r#"gerrit.default-remote="origin""#);
|
|
let output = work_dir.run_jj(["gerrit", "upload", "-r", "b"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: The remote 'origin' (configured via `gerrit.default-remote`) does not exist
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
let output = work_dir.run_jj(["gerrit", "upload", "-r", "b", "--remote=origin"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: The remote 'origin' (specified via `--remote`) does not exist
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
let output = work_dir.run_jj([
|
|
"git",
|
|
"remote",
|
|
"add",
|
|
"origin",
|
|
"http://example.com/repo/foo",
|
|
]);
|
|
insta::assert_snapshot!(output, @"");
|
|
let output = work_dir.run_jj(["gerrit", "upload", "-r", "b", "--remote=origin"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: No target branch specified via --remote-branch, and no 'gerrit.default-remote-branch' was found
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
test_env.add_config(r#"gerrit.default-remote-branch="main""#);
|
|
let output = work_dir.run_jj(["gerrit", "upload", "-r", "b", "--dry-run"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Dry-run: Would push psuskuln dd148a1b b | b
|
|
[EOF]
|
|
");
|
|
|
|
let output = work_dir.run_jj(["gerrit", "upload", "-r", "b", "--dry-run", "-b", "other"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'other'
|
|
Dry-run: Would push psuskuln dd148a1b b | b
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_default_revision() {
|
|
let test_env = TestEnvironment::default();
|
|
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
|
|
work_dir
|
|
.run_jj([
|
|
"git",
|
|
"remote",
|
|
"add",
|
|
"origin",
|
|
"http://example.com/repo/foo",
|
|
])
|
|
.success();
|
|
test_env.add_config(r#"gerrit.default-remote="origin""#);
|
|
test_env.add_config(r#"gerrit.default-remote-branch="main""#);
|
|
|
|
work_dir
|
|
.run_jj(["new", "--message", "parent", "root()"])
|
|
.success();
|
|
work_dir.write_file("parent", "parent");
|
|
let output = work_dir.run_jj(["gerrit", "upload", "--dry-run"]);
|
|
insta::assert_snapshot!(output, @r"
|
|
------- stderr -------
|
|
No revision provided. Defaulting to @
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Dry-run: Would push nkmpptxz f7f633c0 parent
|
|
[EOF]
|
|
");
|
|
|
|
work_dir.run_jj(["new"]).success();
|
|
let output = work_dir.run_jj(["gerrit", "upload", "--dry-run"]);
|
|
insta::assert_snapshot!(output, @r"
|
|
------- stderr -------
|
|
No revision provided and @ has no description. Defaulting to @-
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Dry-run: Would push nkmpptxz f7f633c0 parent
|
|
[EOF]
|
|
");
|
|
|
|
work_dir.run_jj(["new", "@", "@-"]).success();
|
|
let output = work_dir.run_jj(["gerrit", "upload", "--dry-run"]);
|
|
insta::assert_snapshot!(output, @r"
|
|
------- stderr -------
|
|
Error: No revision provided, and @ is a merge commit with no description. Unable to determine a suitable default commit to upload.
|
|
Hint: Explicitly specify a revision to upload with `-r`
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
work_dir.run_jj(["workspace", "forget"]).success();
|
|
let output = work_dir.run_jj(["gerrit", "upload", "--dry-run"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: No revision provided
|
|
Hint: Explicitly specify a revision to upload with `-r`
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
}
|
|
|
|
#[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, @r#"
|
|
------- stderr -------
|
|
No revision provided and @ has no description. Defaulting to @-
|
|
Error: Commit 86be1db760f2 is immutable
|
|
Hint: Could not modify commit: ylvkpnrz 86be1db7 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();
|
|
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
|
|
let work_dir = test_env.work_dir("repo");
|
|
|
|
// upload options are validated before anything else
|
|
// malformed custom option
|
|
let output = work_dir.run_jj(["gerrit", "upload", "--custom", "foo"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: Custom values must be of the form 'key:value'. Got foo
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
// mutually exclusive flags
|
|
let output = work_dir.run_jj(["gerrit", "upload", "--wip", "--ready"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: --wip and --ready are mutually exclusive
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
let output = work_dir.run_jj(["gerrit", "upload", "--private", "--remove-private"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: --private and --remove-private are mutually exclusive
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
let output = work_dir.run_jj([
|
|
"gerrit",
|
|
"upload",
|
|
"--publish-comments",
|
|
"--no-publish-comments",
|
|
]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: --publish-comments and --no-publish-comments are mutually exclusive
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
// cannot skip validation without submitting
|
|
let output = work_dir.run_jj(["gerrit", "upload", "--skip-validation"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: --skip-validation is only supported for --submit
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_failure() {
|
|
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, "a", &[]);
|
|
|
|
test_env
|
|
.run_jj_in(".", ["git", "clone", "remote", "local"])
|
|
.success();
|
|
let local_dir = test_env.work_dir("local");
|
|
|
|
// construct test revisions
|
|
create_commit_with_files(&local_dir, "b", &["a@origin"], &[]);
|
|
create_commit(&local_dir, "c", &["a@origin"]);
|
|
local_dir.run_jj(["describe", "-m="]).success();
|
|
create_commit(&local_dir, "d", &["a@origin"]);
|
|
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "none()", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
No revisions to upload.
|
|
[EOF]
|
|
");
|
|
|
|
// empty revisions are not allowed
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "b", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: Refusing to upload revision pzvwutvlkqwt because it is empty
|
|
Hint: Perhaps you squashed then ran upload? Maybe you meant to upload the parent commit instead (eg. @-)
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
// empty descriptions are not allowed
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "c", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: Refusing to upload revision nqosqzytrlsw because it is has no description
|
|
Hint: Maybe you meant to upload the parent commit instead (eg. @-)
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
// upload failure
|
|
local_dir
|
|
.run_jj(["git", "remote", "set-url", "origin", "nonexistent"])
|
|
.success();
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "d", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Pushing qnkkpsqq 50f9c1c1 d | d
|
|
Error: Internal git error while pushing to gerrit
|
|
Caused by: Could not find repository at '$TEST_ENV/local/nonexistent'
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_local_implicit_change_ids() {
|
|
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, "a", &[]);
|
|
|
|
test_env
|
|
.run_jj_in(".", ["git", "clone", "remote", "local"])
|
|
.success();
|
|
let local_dir = test_env.work_dir("local");
|
|
create_commit(&local_dir, "b", &["a@origin"]);
|
|
create_commit(&local_dir, "c", &["b"]);
|
|
|
|
// Ensure other trailers are preserved (no extra newlines)
|
|
local_dir
|
|
.run_jj([
|
|
"describe",
|
|
"c",
|
|
"-m",
|
|
"c\n\nSigned-off-by: Lucky K Maintainer <lucky@maintainer.example.org>\n",
|
|
])
|
|
.success();
|
|
|
|
// The output should only mention commit IDs from the log output above (no
|
|
// temporary commits)
|
|
let output = local_dir.run_jj(["log", "-r", "all()"]);
|
|
insta::assert_snapshot!(output, @"
|
|
@ nqosqzyt test.user@example.com 2001-02-03 08:05:15 c 06dc682a
|
|
│ c
|
|
○ pzvwutvl test.user@example.com 2001-02-03 08:05:12 b bd2773ca
|
|
│ b
|
|
◆ ylvkpnrz test.user@example.com 2001-02-03 08:05:09 a@origin a1afb583
|
|
│ a
|
|
◆ zzzzzzzz root() 00000000
|
|
[EOF]
|
|
");
|
|
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "c", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Pushing nqosqzyt 06dc682a c | c
|
|
[EOF]
|
|
");
|
|
|
|
// The output should be unchanged because we only add Change-Id trailers
|
|
// transiently
|
|
let output = local_dir.run_jj(["log", "-r", "all()"]);
|
|
insta::assert_snapshot!(output, @"
|
|
@ nqosqzyt test.user@example.com 2001-02-03 08:05:15 c 06dc682a
|
|
│ c
|
|
○ pzvwutvl test.user@example.com 2001-02-03 08:05:12 b bd2773ca
|
|
│ b
|
|
◆ ylvkpnrz test.user@example.com 2001-02-03 08:05:09 a@origin a1afb583
|
|
│ a
|
|
◆ zzzzzzzz root() 00000000
|
|
[EOF]
|
|
");
|
|
|
|
// There's no particular reason to run this with jj util exec, it's just that
|
|
// the infra makes it easier to run this way.
|
|
let output = remote_dir.run_jj(["util", "exec", "--", "git", "log", "refs/for/main"]);
|
|
insta::assert_snapshot!(output, @r"
|
|
commit d8b9cbe0b3ee36981d2d55050589d2d07fb05045
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:13 2001 +0700
|
|
|
|
c
|
|
|
|
Signed-off-by: Lucky K Maintainer <lucky@maintainer.example.org>
|
|
Change-Id: Ic9b790168e73f7a73a98deae21e807c06a6a6964
|
|
|
|
commit 166a6cec7b25f3206d67e661b5b354b60ae29998
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:11 2001 +0700
|
|
|
|
b
|
|
|
|
Change-Id: Ia043564ef93650b06a70f92f9d91912b6a6a6964
|
|
|
|
commit a1afb5834d8ee4dcb61b59db0f682c7a53f96f53
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:08 2001 +0700
|
|
|
|
a
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_local_implicit_change_id_link() {
|
|
let test_env = TestEnvironment::default();
|
|
test_env.add_config(
|
|
r#"
|
|
[gerrit]
|
|
review-url = "https://gerrit.example.com/"
|
|
"#,
|
|
);
|
|
test_env
|
|
.run_jj_in(".", ["git", "init", "--colocate", "remote"])
|
|
.success();
|
|
let remote_dir = test_env.work_dir("remote");
|
|
create_commit(&remote_dir, "a", &[]);
|
|
|
|
test_env
|
|
.run_jj_in(".", ["git", "clone", "remote", "local"])
|
|
.success();
|
|
let local_dir = test_env.work_dir("local");
|
|
create_commit(&local_dir, "b", &["a@origin"]);
|
|
create_commit(&local_dir, "c", &["b"]);
|
|
|
|
// Ensure other trailers are preserved (no extra newlines)
|
|
local_dir
|
|
.run_jj([
|
|
"describe",
|
|
"c",
|
|
"-m",
|
|
"c\n\nSigned-off-by: Lucky K Maintainer <lucky@maintainer.example.org>\n",
|
|
])
|
|
.success();
|
|
|
|
// The output should only mention commit IDs from the log output above (no
|
|
// temporary commits)
|
|
let output = local_dir.run_jj(["log", "-r", "all()"]);
|
|
insta::assert_snapshot!(output, @"
|
|
@ nqosqzyt test.user@example.com 2001-02-03 08:05:15 c 06dc682a
|
|
│ c
|
|
○ pzvwutvl test.user@example.com 2001-02-03 08:05:12 b bd2773ca
|
|
│ b
|
|
◆ ylvkpnrz test.user@example.com 2001-02-03 08:05:09 a@origin a1afb583
|
|
│ a
|
|
◆ zzzzzzzz root() 00000000
|
|
[EOF]
|
|
");
|
|
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "c", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Pushing nqosqzyt 06dc682a c | c
|
|
[EOF]
|
|
");
|
|
|
|
// The output should be unchanged because we only add Link trailers
|
|
// transiently
|
|
let output = local_dir.run_jj(["log", "-r", "all()"]);
|
|
insta::assert_snapshot!(output, @"
|
|
@ nqosqzyt test.user@example.com 2001-02-03 08:05:15 c 06dc682a
|
|
│ c
|
|
○ pzvwutvl test.user@example.com 2001-02-03 08:05:12 b bd2773ca
|
|
│ b
|
|
◆ ylvkpnrz test.user@example.com 2001-02-03 08:05:09 a@origin a1afb583
|
|
│ a
|
|
◆ zzzzzzzz root() 00000000
|
|
[EOF]
|
|
");
|
|
|
|
// There's no particular reason to run this with jj util exec, it's just that
|
|
// the infra makes it easier to run this way.
|
|
let output = remote_dir.run_jj(["util", "exec", "--", "git", "log", "refs/for/main"]);
|
|
insta::assert_snapshot!(output, @r"
|
|
commit f4f2cd7de12a02296bbe8b2aeadf0abda9fc5e58
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:13 2001 +0700
|
|
|
|
c
|
|
|
|
Signed-off-by: Lucky K Maintainer <lucky@maintainer.example.org>
|
|
Link: https://gerrit.example.com/id/Ic9b790168e73f7a73a98deae21e807c06a6a6964
|
|
|
|
commit 0137efaa46414aac8f664eb33f5a7739b3372bda
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:11 2001 +0700
|
|
|
|
b
|
|
|
|
Link: https://gerrit.example.com/id/Ia043564ef93650b06a70f92f9d91912b6a6a6964
|
|
|
|
commit a1afb5834d8ee4dcb61b59db0f682c7a53f96f53
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:08 2001 +0700
|
|
|
|
a
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_local_explicit_change_ids() {
|
|
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, "a", &[]);
|
|
|
|
test_env
|
|
.run_jj_in(".", ["git", "clone", "remote", "local"])
|
|
.success();
|
|
let local_dir = test_env.work_dir("local");
|
|
create_commit(&local_dir, "b", &["a@origin"]);
|
|
|
|
// Add an explicit Change-Id footer to b
|
|
let output = local_dir.run_jj([
|
|
"describe",
|
|
"b",
|
|
"-m",
|
|
"b\n\nChange-Id: Id39b308212fe7e0b746d16c13355f3a90712d7f9\n",
|
|
]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Working copy (@) now at: pzvwutvl a92f28f1 b | b
|
|
Parent commit (@-) : ylvkpnrz a1afb583 a@origin | a
|
|
[EOF]
|
|
");
|
|
|
|
create_commit(&local_dir, "c", &["b"]);
|
|
|
|
// Add an explicit Link footer to c
|
|
let output = local_dir.run_jj([
|
|
"describe",
|
|
"c",
|
|
"-m",
|
|
"c\n\nLink: https://gerrit.example.com/id/Idfac1e8c149efddf5c7a286f787b43886a6a6964\n",
|
|
]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Working copy (@) now at: truxwmqv e5c39e2f c | c
|
|
Parent commit (@-) : pzvwutvl a92f28f1 b | b
|
|
[EOF]
|
|
");
|
|
|
|
// The output should only mention commit IDs from the log output above (no
|
|
// temporary commits)
|
|
let output = local_dir.run_jj(["log", "-r", "all()"]);
|
|
insta::assert_snapshot!(output, @"
|
|
@ truxwmqv test.user@example.com 2001-02-03 08:05:16 c e5c39e2f
|
|
│ c
|
|
○ pzvwutvl test.user@example.com 2001-02-03 08:05:13 b a92f28f1
|
|
│ b
|
|
◆ ylvkpnrz test.user@example.com 2001-02-03 08:05:09 a@origin a1afb583
|
|
│ a
|
|
◆ zzzzzzzz root() 00000000
|
|
[EOF]
|
|
");
|
|
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "c", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Pushing truxwmqv e5c39e2f c | c
|
|
[EOF]
|
|
");
|
|
|
|
// The output should be unchanged because no temporary commits should have
|
|
// been created
|
|
let output = local_dir.run_jj(["log", "-r", "all()"]);
|
|
insta::assert_snapshot!(output, @"
|
|
@ truxwmqv test.user@example.com 2001-02-03 08:05:16 c e5c39e2f
|
|
│ c
|
|
○ pzvwutvl test.user@example.com 2001-02-03 08:05:13 b a92f28f1
|
|
│ b
|
|
◆ ylvkpnrz test.user@example.com 2001-02-03 08:05:09 a@origin a1afb583
|
|
│ a
|
|
◆ zzzzzzzz root() 00000000
|
|
[EOF]
|
|
");
|
|
|
|
// There's no particular reason to run this with jj util exec, it's just that
|
|
// the infra makes it easier to run this way.
|
|
let output = remote_dir.run_jj(["util", "exec", "--", "git", "log", "refs/for/main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
commit e5c39e2fe97d0c6db908e0bfe8487814cc04fa3d
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:14 2001 +0700
|
|
|
|
c
|
|
|
|
Link: https://gerrit.example.com/id/Idfac1e8c149efddf5c7a286f787b43886a6a6964
|
|
|
|
commit a92f28f1118f62b6b8c85eb7252e5a3c63720005
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:11 2001 +0700
|
|
|
|
b
|
|
|
|
Change-Id: Id39b308212fe7e0b746d16c13355f3a90712d7f9
|
|
|
|
commit a1afb5834d8ee4dcb61b59db0f682c7a53f96f53
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:08 2001 +0700
|
|
|
|
a
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_local_mixed_change_ids() {
|
|
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, "a", &[]);
|
|
|
|
test_env
|
|
.run_jj_in(".", ["git", "clone", "remote", "local"])
|
|
.success();
|
|
let local_dir = test_env.work_dir("local");
|
|
create_commit(&local_dir, "b", &["a@origin"]);
|
|
create_commit(&local_dir, "c", &["b"]);
|
|
|
|
// Add an explicit Change-Id footer to c but not b
|
|
let output = local_dir.run_jj([
|
|
"describe",
|
|
"c",
|
|
"-m",
|
|
"c\n\nChange-Id: Id39b308212fe7e0b746d16c13355f3a90712d7f9\n",
|
|
]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Working copy (@) now at: nqosqzyt a030199b c | c
|
|
Parent commit (@-) : pzvwutvl bd2773ca b | b
|
|
[EOF]
|
|
");
|
|
|
|
// The output should only mention commit IDs from the log output above (no
|
|
// temporary commits)
|
|
let output = local_dir.run_jj(["log", "-r", "all()"]);
|
|
insta::assert_snapshot!(output, @"
|
|
@ nqosqzyt test.user@example.com 2001-02-03 08:05:15 c a030199b
|
|
│ c
|
|
○ pzvwutvl test.user@example.com 2001-02-03 08:05:12 b bd2773ca
|
|
│ b
|
|
◆ ylvkpnrz test.user@example.com 2001-02-03 08:05:09 a@origin a1afb583
|
|
│ a
|
|
◆ zzzzzzzz root() 00000000
|
|
[EOF]
|
|
");
|
|
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "c", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Pushing nqosqzyt a030199b c | c
|
|
[EOF]
|
|
");
|
|
|
|
// The output should be unchanged because commits created within 'upload'
|
|
// should all be temporary
|
|
let output = local_dir.run_jj(["log", "-r", "all()"]);
|
|
insta::assert_snapshot!(output, @"
|
|
@ nqosqzyt test.user@example.com 2001-02-03 08:05:15 c a030199b
|
|
│ c
|
|
○ pzvwutvl test.user@example.com 2001-02-03 08:05:12 b bd2773ca
|
|
│ b
|
|
◆ ylvkpnrz test.user@example.com 2001-02-03 08:05:09 a@origin a1afb583
|
|
│ a
|
|
◆ zzzzzzzz root() 00000000
|
|
[EOF]
|
|
");
|
|
|
|
// There's no particular reason to run this with jj util exec, it's just that
|
|
// the infra makes it easier to run this way.
|
|
let output = remote_dir.run_jj(["util", "exec", "--", "git", "log", "refs/for/main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
commit 1fad1dc37e6e6c0b2afc98f5103a7f912537110c
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:13 2001 +0700
|
|
|
|
c
|
|
|
|
Change-Id: Id39b308212fe7e0b746d16c13355f3a90712d7f9
|
|
|
|
commit 166a6cec7b25f3206d67e661b5b354b60ae29998
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:11 2001 +0700
|
|
|
|
b
|
|
|
|
Change-Id: Ia043564ef93650b06a70f92f9d91912b6a6a6964
|
|
|
|
commit a1afb5834d8ee4dcb61b59db0f682c7a53f96f53
|
|
Author: Test User <test.user@example.com>
|
|
Date: Sat Feb 3 04:05:08 2001 +0700
|
|
|
|
a
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_bad_change_ids() {
|
|
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, "a", &[]);
|
|
|
|
test_env
|
|
.run_jj_in(".", ["git", "clone", "remote", "local"])
|
|
.success();
|
|
let local_dir = test_env.work_dir("local");
|
|
create_commit(&local_dir, "b", &["a@origin"]);
|
|
create_commit(&local_dir, "b2", &["b"]);
|
|
create_commit(&local_dir, "b3", &["b2"]);
|
|
create_commit(&local_dir, "b4", &["b3"]);
|
|
create_commit(&local_dir, "c", &["a@origin"]);
|
|
create_commit(&local_dir, "d", &["a@origin"]);
|
|
create_commit(&local_dir, "e", &["a@origin"]);
|
|
|
|
local_dir
|
|
.run_jj(["describe", "-rb", "-m\n\nChange-Id: malformed\n"])
|
|
.success();
|
|
local_dir
|
|
.run_jj([
|
|
"describe",
|
|
"-rb2",
|
|
"-m\n\nChange-Id: i0000000000000000000000000000000000000000\n",
|
|
])
|
|
.success();
|
|
local_dir
|
|
.run_jj(["describe", "-rb3", "-m\n\nLink: malformed\n"])
|
|
.success();
|
|
local_dir
|
|
.run_jj([
|
|
"describe",
|
|
"-rb4",
|
|
"-m\n\nLink: https://gerrit.example.com/id/Imalformed\n",
|
|
])
|
|
.success();
|
|
local_dir
|
|
.run_jj([
|
|
"describe",
|
|
"-rc",
|
|
"-m",
|
|
concat!(
|
|
"\n\n",
|
|
"Change-Id: I1111111111111111111111111111111111111111\n",
|
|
"Change-Id: I2222222222222222222222222222222222222222\n",
|
|
),
|
|
])
|
|
.success();
|
|
local_dir
|
|
.run_jj([
|
|
"describe",
|
|
"-rd",
|
|
"-m",
|
|
concat!(
|
|
"\n\n",
|
|
"Link: https://gerrit.example.com/id/I1111111111111111111111111111111111111111\n",
|
|
"Change-Id: I2222222222222222222222222222222222222222\n",
|
|
),
|
|
])
|
|
.success();
|
|
local_dir
|
|
.run_jj([
|
|
"describe",
|
|
"-re",
|
|
"-m",
|
|
concat!(
|
|
"\n\n",
|
|
"Link: https://gerrit.example.com/id/I1111111111111111111111111111111111111111\n",
|
|
"Link: https://gerrit.example.com/id/I2222222222222222222222222222222222222222\n",
|
|
),
|
|
])
|
|
.success();
|
|
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-rc", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: Multiple Change-Id footers in revision vqnwkozpkust
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-rd", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: Multiple Change-Id footers in revision uxryzmorwvtz
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-re", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Error: Multiple Change-Id footers in revision wyznsvlquzzm
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
|
|
// check both badly and slightly malformed Change-Id / Link trailers
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-rb4", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Warning: Invalid Change-Id footer in revision pzvwutvlkqwt
|
|
Warning: Invalid Change-Id footer in revision nqosqzytrlsw
|
|
Warning: Invalid Link footer in revision rostqsxwqrlt
|
|
Warning: Invalid Link footer in revision kpqxywonksrl
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Pushing kpqxywon 45cdd32b b4
|
|
[EOF]
|
|
");
|
|
}
|
|
|
|
#[test]
|
|
fn test_gerrit_upload_rejected_by_remote() -> TestResult {
|
|
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, "a", &[]);
|
|
|
|
// create a hook on the remote that prevents pushing
|
|
let hook_path = test_env
|
|
.env_root()
|
|
.join("remote")
|
|
.join(".git")
|
|
.join("hooks")
|
|
.join("update");
|
|
|
|
std::fs::write(&hook_path, "#!/bin/sh\nexit 1")?;
|
|
#[cfg(unix)]
|
|
{
|
|
use std::os::unix::fs::PermissionsExt as _;
|
|
|
|
std::fs::set_permissions(&hook_path, std::fs::Permissions::from_mode(0o700))?;
|
|
}
|
|
|
|
test_env
|
|
.run_jj_in(".", ["git", "clone", "remote", "local"])
|
|
.success();
|
|
let local_dir = test_env.work_dir("local");
|
|
create_commit(&local_dir, "b", &["a@origin"]);
|
|
|
|
// Add an explicit Change-Id footer to b
|
|
let output = local_dir.run_jj([
|
|
"describe",
|
|
"b",
|
|
"-m",
|
|
"b\n\nChange-Id: Id39b308212fe7e0b746d16c13355f3a90712d7f9\n",
|
|
]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Working copy (@) now at: pzvwutvl a92f28f1 b | b
|
|
Parent commit (@-) : ylvkpnrz a1afb583 a@origin | a
|
|
[EOF]
|
|
");
|
|
|
|
let output = local_dir.run_jj(["gerrit", "upload", "-r", "b", "--remote-branch=main"]);
|
|
insta::assert_snapshot!(output, @"
|
|
------- stderr -------
|
|
Found 1 heads to push to Gerrit (remote 'origin'), target branch 'main'
|
|
Pushing pzvwutvl a92f28f1 b | b
|
|
remote: error: hook declined to update refs/for/main
|
|
Warning: The remote rejected the following updates:
|
|
refs/for/main (reason: hook declined)
|
|
Hint: Try checking if you have permission to push to all the bookmarks.
|
|
Error: Failed to push all changes to gerrit
|
|
[EOF]
|
|
[exit status: 1]
|
|
");
|
|
Ok(())
|
|
}
|