checkout: Catch multiple changes for same remote
Catch when there are multiple changes for the same remote much earlier
than previously, and with a better error message than "fatal: a branch
named 'working' already exists".
Bug: b/388621007
Change-Id: I05934df6ad4d8f9f0b195fc7310e37b11748c132
Reviewed-on: https://pigweed-review.googlesource.com/c/infra/recipes/+/260065
Lint: Lint 🤖 <android-build-ayeaye@system.gserviceaccount.com>
Pigweed-Auto-Submit: Rob Mohr <mohrr@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ted Pudlik <tpudlik@google.com>
Commit-Queue: Auto-Submit <auto-submit@pigweed-service-accounts.iam.gserviceaccount.com>
diff --git a/recipe_modules/checkout/api.py b/recipe_modules/checkout/api.py
index 5df25df..2797ec2 100644
--- a/recipe_modules/checkout/api.py
+++ b/recipe_modules/checkout/api.py
@@ -1524,6 +1524,34 @@
path = path / repo['strip_prefix']
ctx.bazel_overrides[repo['name']] = path
+ def _check_gerrit_changes(self, ctx: CheckoutContext):
+ """Check that we don't have multiple changes for the same repo."""
+ seen = {}
+
+ for change in ctx.changes:
+ if change.submitted:
+ continue
+
+ for remote, prev_change in seen.items():
+ if ctx.remotes_equivalent(change.remote, remote):
+ failure = (
+ f'Change {prev_change.name} and change {change.name} '
+ f'are from equivalent remotes ({prev_change.remote!r} '
+ f'and {change.remote!r}). This is not supported. '
+ 'Instead, stack these changes, or only refer to the '
+ "top from a 'patches.json' file in another repository."
+ )
+ pres = self.m.step.empty(
+ 'multiple changes for same repo',
+ ).presentation
+ pres.step_summary_text = failure
+ pres.status = 'FAILURE'
+ pres.links[prev_change.name] = prev_change.gerrit_url
+ pres.links[change.name] = change.gerrit_url
+ raise self.m.step.StepFailure(failure)
+
+ seen[change.remote] = change
+
def _configure_insteadof(self, ctx: CheckoutContext):
"""Configure git to use some urls in place of others."""
if not ctx.options.rewrites:
@@ -1627,6 +1655,8 @@
ctx, options.remote, options.branch
)
+ self._check_gerrit_changes(ctx)
+
self._configure_insteadof(ctx)
if options.use_repo:
diff --git a/recipe_modules/checkout/test_api.py b/recipe_modules/checkout/test_api.py
index 733dcae..36f4730 100644
--- a/recipe_modules/checkout/test_api.py
+++ b/recipe_modules/checkout/test_api.py
@@ -404,3 +404,9 @@
) + self.post_process(
post_process.MustRunRE, r'.*excluding submodule {}'.format(name)
)
+
+ def multiple_changes_for_same_repo(self):
+ return self.post_process(
+ post_process.MustRunRE,
+ r'.*multiple changes for same repo',
+ )
diff --git a/recipe_modules/checkout/tests/git.expected/multiple-equiv-remote.json b/recipe_modules/checkout/tests/git.expected/multiple-equiv-remote.json
new file mode 100644
index 0000000..1f4770f
--- /dev/null
+++ b/recipe_modules/checkout/tests/git.expected/multiple-equiv-remote.json
@@ -0,0 +1,423 @@
+[
+ {
+ "cmd": [],
+ "name": "checkout pigweed",
+ "~followup_annotations": [
+ "@@@STEP_FAILURE@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.options",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@remote: \"https://pigweed.googlesource.com/pigweed/pigweed\"\nbranch: \"main\"\ninitialize_submodules: true\nmatch_branch: true\nuse_trigger: true\nequivalent_remotes {\n remotes: \"https://pigweed.googlesource.com/foo\"\n remotes: \"https://pigweed.googlesource.com/bar\"\n}\n@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.options with defaults",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@remote: \"https://pigweed.googlesource.com/pigweed/pigweed\"\nbranch: \"main\"\nmanifest_file: \"default.xml\"\ninitialize_submodules: true\nrepo_init_timeout_sec: 20\nrepo_sync_timeout_sec: 120\nnumber_of_attempts: 3\nmatch_branch: true\nsubmodule_timeout_sec: 600\nuse_trigger: true\nequivalent_remotes {\n remotes: \"https://pigweed.googlesource.com/foo\"\n remotes: \"https://pigweed.googlesource.com/bar\"\n}\n@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.0",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.get packages",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@5@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "RECIPE_MODULE[fuchsia::gerrit]/resources/cipd.ensure",
+ "/path/to/tmp/"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.get packages.read ensure file",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@6@@@",
+ "@@@STEP_LOG_LINE@cipd.ensure@infra/tools/luci/gerrit/${platform} version:pinned-version@@@",
+ "@@@STEP_LOG_END@cipd.ensure@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.install infra/tools/luci/gerrit",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@5@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0o777",
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.install infra/tools/luci/gerrit.ensure package directory",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@6@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07",
+ "-ensure-file",
+ "infra/tools/luci/gerrit/${platform} version:pinned-version",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.install infra/tools/luci/gerrit.ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@6@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-version:pinned-v\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/luci/gerrit/resolved-platform\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07/gerrit",
+ "change-detail",
+ "-host",
+ "https://pigweed-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"1000\", \"params\": {\"o\": [\"CURRENT_COMMIT\", \"CURRENT_REVISION\"]}}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.0.details",
+ "timeout": 30,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"branch\": \"main\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"current_revision\": \"ffffffffffffffffffffffffffffffffffffffff\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"project\": \"foo\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"ffffffffffffffffffffffffffffffffffffffff\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": 3,@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"commit\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"message\": \"\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"parents\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {}@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LOG_LINE@json.input@{@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"change_id\": \"1000\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"params\": {@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"o\": [@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_COMMIT\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_REVISION\"@@@",
+ "@@@STEP_LOG_LINE@json.input@ ]@@@",
+ "@@@STEP_LOG_LINE@json.input@ }@@@",
+ "@@@STEP_LOG_LINE@json.input@}@@@",
+ "@@@STEP_LOG_END@json.input@@@",
+ "@@@STEP_LINK@gerrit link@https://pigweed-review.googlesource.com/q/1000@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.1",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07/gerrit",
+ "change-detail",
+ "-host",
+ "https://pigweed-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"2000\", \"params\": {\"o\": [\"CURRENT_COMMIT\", \"CURRENT_REVISION\"]}}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.1.details",
+ "timeout": 30,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"branch\": \"main\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"current_revision\": \"ffffffffffffffffffffffffffffffffffffffff\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"project\": \"bar\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"ffffffffffffffffffffffffffffffffffffffff\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": 3,@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"commit\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"message\": \"\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"parents\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {}@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LOG_LINE@json.input@{@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"change_id\": \"2000\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"params\": {@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"o\": [@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_COMMIT\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_REVISION\"@@@",
+ "@@@STEP_LOG_LINE@json.input@ ]@@@",
+ "@@@STEP_LOG_LINE@json.input@ }@@@",
+ "@@@STEP_LOG_LINE@json.input@}@@@",
+ "@@@STEP_LOG_END@json.input@@@",
+ "@@@STEP_LINK@gerrit link@https://pigweed-review.googlesource.com/q/2000@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07/gerrit",
+ "change-detail",
+ "-host",
+ "https://pigweed-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"2000\", \"params\": {\"o\": [\"CURRENT_COMMIT\", \"CURRENT_FILES\", \"CURRENT_REVISION\"]}}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps.details pigweed:2000",
+ "timeout": 30,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": 2000,@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"current_revision\": \"HASH\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"project\": \"project\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"HASH\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": 1,@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"commit\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"message\": \"\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ },@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"files\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"filename\": {}@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ },@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"status\": \"NEW\"@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LOG_LINE@json.input@{@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"change_id\": \"2000\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"params\": {@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"o\": [@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_COMMIT\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_FILES\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_REVISION\"@@@",
+ "@@@STEP_LOG_LINE@json.input@ ]@@@",
+ "@@@STEP_LOG_LINE@json.input@ }@@@",
+ "@@@STEP_LOG_LINE@json.input@}@@@",
+ "@@@STEP_LOG_END@json.input@@@",
+ "@@@STEP_LINK@gerrit link@https://pigweed-review.googlesource.com/q/2000@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps.resolve deps for pigweed:2000",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@",
+ "@@@STEP_SUMMARY_TEXT@no dependencies@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps.no topic",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps.pass",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.changes",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.changes.pigweed:1000",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@",
+ "@@@STEP_SUMMARY_TEXT@Change(number=1000, remote='https://pigweed.googlesource.com/foo', ref='refs/changes/00/1000/1', rebase=True, project='foo', branch='main', gerrit_name='pigweed', submitted=False, patchset=1, path=None, base=None, base_type=None, is_merge=False, commit_message='', topic=None, current_revision='ffffffffffffffffffffffffffffffffffffffff')@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.changes.pigweed:2000",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@",
+ "@@@STEP_SUMMARY_TEXT@Change(number=2000, remote='https://pigweed.googlesource.com/bar', ref='refs/changes/00/2000/1', rebase=True, project='bar', branch='main', gerrit_name='pigweed', submitted=False, patchset=1, path=None, base=None, base_type=None, is_merge=False, commit_message='', topic=None, current_revision='ffffffffffffffffffffffffffffffffffffffff')@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.multiple changes for same repo",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@Change pigweed:1000 and change pigweed:2000 are from equivalent remotes ('https://pigweed.googlesource.com/foo' and 'https://pigweed.googlesource.com/bar'). This is not supported. Instead, stack these changes, or only refer to the top from a 'patches.json' file in another repository.@@@",
+ "@@@STEP_LINK@pigweed:1000@https://pigweed-review.googlesource.com/c/1000@@@",
+ "@@@STEP_LINK@pigweed:2000@https://pigweed-review.googlesource.com/c/2000@@@",
+ "@@@STEP_FAILURE@@@"
+ ]
+ },
+ {
+ "failure": {
+ "failure": {},
+ "humanReason": "Change pigweed:1000 and change pigweed:2000 are from equivalent remotes ('https://pigweed.googlesource.com/foo' and 'https://pigweed.googlesource.com/bar'). This is not supported. Instead, stack these changes, or only refer to the top from a 'patches.json' file in another repository."
+ },
+ "name": "$result"
+ }
+]
\ No newline at end of file
diff --git a/recipe_modules/checkout/tests/git.expected/multiple-same-remote.json b/recipe_modules/checkout/tests/git.expected/multiple-same-remote.json
new file mode 100644
index 0000000..637a6d6
--- /dev/null
+++ b/recipe_modules/checkout/tests/git.expected/multiple-same-remote.json
@@ -0,0 +1,423 @@
+[
+ {
+ "cmd": [],
+ "name": "checkout pigweed",
+ "~followup_annotations": [
+ "@@@STEP_FAILURE@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.options",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@remote: \"https://pigweed.googlesource.com/pigweed/pigweed\"\nbranch: \"main\"\ninitialize_submodules: true\nmatch_branch: true\nuse_trigger: true\n@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.options with defaults",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@remote: \"https://pigweed.googlesource.com/pigweed/pigweed\"\nbranch: \"main\"\nmanifest_file: \"default.xml\"\ninitialize_submodules: true\nrepo_init_timeout_sec: 20\nrepo_sync_timeout_sec: 120\nnumber_of_attempts: 3\nmatch_branch: true\nsubmodule_timeout_sec: 600\nuse_trigger: true\n@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.0",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.get packages",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@5@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "RECIPE_MODULE[fuchsia::gerrit]/resources/cipd.ensure",
+ "/path/to/tmp/"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.get packages.read ensure file",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@6@@@",
+ "@@@STEP_LOG_LINE@cipd.ensure@infra/tools/luci/gerrit/${platform} version:pinned-version@@@",
+ "@@@STEP_LOG_END@cipd.ensure@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.install infra/tools/luci/gerrit",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@5@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0o777",
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.install infra/tools/luci/gerrit.ensure package directory",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@6@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07",
+ "-ensure-file",
+ "infra/tools/luci/gerrit/${platform} version:pinned-version",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.0.ensure infra/tools/luci/gerrit/${platform}.install infra/tools/luci/gerrit.ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@6@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-version:pinned-v\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/luci/gerrit/resolved-platform\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07/gerrit",
+ "change-detail",
+ "-host",
+ "https://pigweed-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"1000\", \"params\": {\"o\": [\"CURRENT_COMMIT\", \"CURRENT_REVISION\"]}}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.0.details",
+ "timeout": 30,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"branch\": \"main\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"current_revision\": \"ffffffffffffffffffffffffffffffffffffffff\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"project\": \"foo\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"ffffffffffffffffffffffffffffffffffffffff\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": 3,@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"commit\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"message\": \"\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"parents\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {}@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LOG_LINE@json.input@{@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"change_id\": \"1000\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"params\": {@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"o\": [@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_COMMIT\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_REVISION\"@@@",
+ "@@@STEP_LOG_LINE@json.input@ ]@@@",
+ "@@@STEP_LOG_LINE@json.input@ }@@@",
+ "@@@STEP_LOG_LINE@json.input@}@@@",
+ "@@@STEP_LOG_END@json.input@@@",
+ "@@@STEP_LINK@gerrit link@https://pigweed-review.googlesource.com/q/1000@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.1",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07/gerrit",
+ "change-detail",
+ "-host",
+ "https://pigweed-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"2000\", \"params\": {\"o\": [\"CURRENT_COMMIT\", \"CURRENT_REVISION\"]}}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.1.details",
+ "timeout": 30,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"branch\": \"main\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"current_revision\": \"ffffffffffffffffffffffffffffffffffffffff\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"project\": \"foo\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"ffffffffffffffffffffffffffffffffffffffff\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": 3,@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"commit\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"message\": \"\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"parents\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {}@@@",
+ "@@@STEP_LOG_LINE@json.output@ ]@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LOG_LINE@json.input@{@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"change_id\": \"2000\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"params\": {@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"o\": [@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_COMMIT\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_REVISION\"@@@",
+ "@@@STEP_LOG_LINE@json.input@ ]@@@",
+ "@@@STEP_LOG_LINE@json.input@ }@@@",
+ "@@@STEP_LOG_LINE@json.input@}@@@",
+ "@@@STEP_LOG_END@json.input@@@",
+ "@@@STEP_LINK@gerrit link@https://pigweed-review.googlesource.com/q/2000@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@"
+ ]
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cipd_tool/infra/tools/luci/gerrit/0e548aa33f8113a45a5b3b62201e114e98e63d00f97296912380138f44597b07/gerrit",
+ "change-detail",
+ "-host",
+ "https://pigweed-review.googlesource.com",
+ "-input",
+ "{\"change_id\": \"2000\", \"params\": {\"o\": [\"CURRENT_COMMIT\", \"CURRENT_FILES\", \"CURRENT_REVISION\"]}}",
+ "-output",
+ "/path/to/tmp/json"
+ ],
+ "infra_step": true,
+ "luci_context": {
+ "realm": {
+ "name": "project:try"
+ },
+ "resultdb": {
+ "current_invocation": {
+ "name": "invocations/build:8945511751514863184",
+ "update_token": "token"
+ },
+ "hostname": "rdbhost"
+ }
+ },
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps.details pigweed:2000",
+ "timeout": 30,
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@",
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": 2000,@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"current_revision\": \"HASH\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"project\": \"project\",@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"revisions\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"HASH\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"_number\": 1,@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"commit\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"message\": \"\"@@@",
+ "@@@STEP_LOG_LINE@json.output@ },@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"files\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"filename\": {}@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ }@@@",
+ "@@@STEP_LOG_LINE@json.output@ },@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"status\": \"NEW\"@@@",
+ "@@@STEP_LOG_LINE@json.output@}@@@",
+ "@@@STEP_LOG_END@json.output@@@",
+ "@@@STEP_LOG_LINE@json.input@{@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"change_id\": \"2000\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"params\": {@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"o\": [@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_COMMIT\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_FILES\",@@@",
+ "@@@STEP_LOG_LINE@json.input@ \"CURRENT_REVISION\"@@@",
+ "@@@STEP_LOG_LINE@json.input@ ]@@@",
+ "@@@STEP_LOG_LINE@json.input@ }@@@",
+ "@@@STEP_LOG_LINE@json.input@}@@@",
+ "@@@STEP_LOG_END@json.input@@@",
+ "@@@STEP_LINK@gerrit link@https://pigweed-review.googlesource.com/q/2000@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps.resolve deps for pigweed:2000",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@",
+ "@@@STEP_SUMMARY_TEXT@no dependencies@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps.no topic",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.process gerrit changes.resolve CL deps.pass",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@4@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.changes",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@2@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.changes.pigweed:1000",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@",
+ "@@@STEP_SUMMARY_TEXT@Change(number=1000, remote='https://pigweed.googlesource.com/foo', ref='refs/changes/00/1000/1', rebase=True, project='foo', branch='main', gerrit_name='pigweed', submitted=False, patchset=1, path=None, base=None, base_type=None, is_merge=False, commit_message='', topic=None, current_revision='ffffffffffffffffffffffffffffffffffffffff')@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.change data.changes.pigweed:2000",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@3@@@",
+ "@@@STEP_SUMMARY_TEXT@Change(number=2000, remote='https://pigweed.googlesource.com/foo', ref='refs/changes/00/2000/1', rebase=True, project='foo', branch='main', gerrit_name='pigweed', submitted=False, patchset=1, path=None, base=None, base_type=None, is_merge=False, commit_message='', topic=None, current_revision='ffffffffffffffffffffffffffffffffffffffff')@@@"
+ ]
+ },
+ {
+ "cmd": [],
+ "name": "checkout pigweed.multiple changes for same repo",
+ "~followup_annotations": [
+ "@@@STEP_NEST_LEVEL@1@@@",
+ "@@@STEP_SUMMARY_TEXT@Change pigweed:1000 and change pigweed:2000 are from equivalent remotes ('https://pigweed.googlesource.com/foo' and 'https://pigweed.googlesource.com/foo'). This is not supported. Instead, stack these changes, or only refer to the top from a 'patches.json' file in another repository.@@@",
+ "@@@STEP_LINK@pigweed:1000@https://pigweed-review.googlesource.com/c/1000@@@",
+ "@@@STEP_LINK@pigweed:2000@https://pigweed-review.googlesource.com/c/2000@@@",
+ "@@@STEP_FAILURE@@@"
+ ]
+ },
+ {
+ "failure": {
+ "failure": {},
+ "humanReason": "Change pigweed:1000 and change pigweed:2000 are from equivalent remotes ('https://pigweed.googlesource.com/foo' and 'https://pigweed.googlesource.com/foo'). This is not supported. Instead, stack these changes, or only refer to the top from a 'patches.json' file in another repository."
+ },
+ "name": "$result"
+ }
+]
\ No newline at end of file
diff --git a/recipe_modules/checkout/tests/git.py b/recipe_modules/checkout/tests/git.py
index 6cb2ef6..0bb292b 100644
--- a/recipe_modules/checkout/tests/git.py
+++ b/recipe_modules/checkout/tests/git.py
@@ -112,3 +112,36 @@
api.step_data('checkout pigweed.cache.git fetch', retcode=1),
status='INFRA_FAILURE',
)
+
+ yield api.test(
+ 'multiple-same-remote',
+ properties(),
+ api.checkout.try_test_data(
+ gerrit_changes=[
+ api.checkout.cl('pigweed-review.googlesource.com', 'foo', 1000),
+ api.checkout.cl('pigweed-review.googlesource.com', 'foo', 2000),
+ ]
+ ),
+ api.checkout.multiple_changes_for_same_repo(),
+ status='FAILURE',
+ )
+
+ yield api.test(
+ 'multiple-equiv-remote',
+ properties(
+ equivalent_remotes=(
+ (
+ 'https://pigweed.googlesource.com/foo',
+ 'https://pigweed.googlesource.com/bar',
+ ),
+ ),
+ ),
+ api.checkout.try_test_data(
+ gerrit_changes=[
+ api.checkout.cl('pigweed-review.googlesource.com', 'foo', 1000),
+ api.checkout.cl('pigweed-review.googlesource.com', 'bar', 2000),
+ ]
+ ),
+ api.checkout.multiple_changes_for_same_repo(),
+ status='FAILURE',
+ )