<commit_before>:linkattrs:
= Gerrit Code Review - Submitting Changes Across Repositories by using Topics

== Goal

This document describes how to propose and submit code changes across multiple
Git repositories together in Gerrit.

== When to Use

Oftentimes, especially for larger code bases, code is split across multiple
repositories. The Android operating system’s code base, for example, consists of
https://android.googlesource.com/[hundreds] of separate repositories. When
making a change, you might make code changes that span multiple repositories.
For example, one repository could define an API which is used in another
repository. Submitting these changes across these repositories separately could
cause the build to break for other developers.

Gerrit provides a mechanism called link:intro-user.html#topics[Topics] to submit
changes together to prevent this problem.

|===
|NOTE: Usage of topics to submit multiple changes together requires your
Gerrit host having
link:config-gerrit.html#change.submitWholeTopic[config.submitWholeTopic] set to
true. Ask your Gerrit administrator if you're not sure if this is enabled for
your Gerrit instance.
|===

== What is a Topic?

* A topic is a string that can be associated with a change.
* Multiple changes can use that topic to be submitted at the same time (assuming
  approvals, etc.).
* Submitting a change with a topic causes all of the changes in the topic *to be
  submitted together*
  ** Topics that span only a single repository are guaranteed to be submitted
  together
  ** Topics that span multiple repositories simply triggers submission of all
  changes. No other guarantees are given. Submission of all changes could
  fail, so you could get a partial topic submission. This is very rare but
  can happen in some of the following situations:
  *** Storage layer failures. This is unlikely in single-master installation and
  more likely with multi-master setups.
  *** Race conditions. Concurrent submits to the same repository or concurrent
  updates of the pending changes.

Here are a few intricacies you should be aware of:

1. Topics can only be used for changes within a single Gerrit instance. There is
no builtin support for synchronizing with other Gerrit or Git hosting sites.

2. A topic can be any string, and they are not namespaced in a Gerrit instance;
there is a chance for collisions and inadvertently grouping changes together
that weren’t meant to be grouped. This could even happen with changes you can’t
see, leading to more confusion e.g. (change not submittable, but you can't see
why it's not submittable.). We suggest prefixing topic strings with the author’s
username e.g. “username-” to help avoid this.

You can view the assigned topic from the change screen in Gerrit:

image::images/cross-repository-changes-topic.png[width=600]

=== Topic submission behavior
* Submitting a topic will submit any dependent changes as well. For example,
  an unsubmitted parent change will also be submitted, even if it isn’t in the
  original topic.
* A change with a topic is submittable when *all changes* in the topic are
  submittable and *all of the changes’ dependent changes* (and their topics!)
  are also submittable.
* Gerrit calls the totality of these changes "Submitted Together", and they can
be found with the
  link:rest-api-changes.html#submitted-together[Submitted Together endpoint] or
  on the change screen.

image::images/cross-repository-changes-submitted-together.png[width=600]

* A submission creates a unique submission ID
    (link:rest-api-changes.html#change-info[`submission_id`]), which can be
    used in Gerrit's search bar to find all the submitted changes for the
    submission. This ID is relevant when <<reverting,reverting a submission>>.

To better underestand this behavior, consider this following example.

==== Example Submission[[example_submission]]

image::images/cross-repository-changes-example.png[width=600]

* Two repositories: A and B
* Two changes in A: A1 and A2, where A2 is the child change.
* Two changes in B: B1 and B2, where B2 is the child change.
* Topic X contains change A1 and B1
* Topic Y contains change A2 and B2

Submission of A2 will submit all four of these changes because submission of A2
submits all of topic Y as well as all dependent changes and their topics i.e. A1
and topic X.

Because of this, any submission is blocked until all four of these changes are
submittable.

|===
| Important point: B1 can unexpectedly block the submission of A2!
This kind of situation is hard to immediately grok: B1 isn't in the topic you're
trying to submit, and it isn't a depnedent change of A2. If your topic isn’t
submittable and you can’t figure out why, this might be a reason.
|===

== Submitting Changes Using Topics

=== 1. *Associate the changes to a topic*

The first step is to associate all the changes you want to be submitted together
with the same topic. There are multiple ways to associate changes with a topic.

==== From the command line
You can set the topic name when uploading to Gerrit

----
$ git push origin HEAD:refs/heads/master -o topic=[YOUR_TOPIC_NAME]
----

*OR*

----
$ git push origin HEAD:refs/for/master%topic=[YOUR_TOPIC_NAME]
----

If you’re using https://source.android.com/setup/develop[repo] to upload a
change to Android Gerrit, you can associate a topic via:

----
$ repo upload -o topic=[YOUR_TOPIC_NAME]
----

If you’re using
https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools.html[depot_tools]
to upload a change to Chromium Gerrit, you can associate a topic via:

----
$ git cl upload --topic=[YOUR_TOPIC_NAME]
----

==== From the UI

If the change has already been created, you can add a topic from the change page
by clicking ADD TOPIC, found on the left side of the top of the Change screen.

image::images/cross-repository-changes-add-topic.png[width=600]

=== 2. *Go through the normal code review process*

Each change still goes through the normal code review process where reviewers
vote on each change individually. The changes won’t be able to be submitted
until *all* changes in the topic are submittable.

The requirements for submittability vary based on rules set by your repository
administrators; often this includes being approved by all requisite parties,
passing presubmit testing, and being able to merge cleanly (without conflicts)
into the target branch.

=== 3. *Submit the change*

When all changes in the topic are submittable, you’ll see *SUBMIT WHOLE TOPIC*
at the top of the _Change screen_. Clicking it will submit all the changes in
"Submitted Together."

image::images/cross-repository-changes-submit-topic.png[width=600]

== Reverting a Submission[[reverting]]

After a topic is submitted, you can revert all or one of the changes by clicking
the *REVERT* button on any change.

image::images/cross-repository-changes-revert-topic.png[width=600]

This will give you the option to either revert just the change in question or
the entire topic:

image::images/cross-repository-changes-revert-topic-options.png[width=600]

Reverting the entire submission creates revert commits for each change and
automatically associates them together under the same topic. To submit
these changes, go through the normal review process.

When submitting a topic, dependent changes and their topics are submitted as<commit_msg>Tidy up cross-repository-changes documentation<commit_after>:linkattrs:
= Gerrit Code Review - Submitting Changes Across Repositories by using Topics

== Goal

This document describes how to propose and submit code changes across multiple
Git repositories together in Gerrit.

== When to Use

Oftentimes, especially for larger code bases, code is split across multiple
repositories. The Android operating system’s code base, for example, consists of
https://android.googlesource.com/[hundreds] of separate repositories. When
making a change, you might make code changes that span multiple repositories.
For example, one repository could define an API which is used in another
repository. Submitting these changes across these repositories separately could
cause the build to break for other developers.

Gerrit provides a mechanism called link:intro-user.html#topics[Topics] to submit
changes together to prevent this problem.

|===
|NOTE: Usage of topics to submit multiple changes together requires your
Gerrit host having
link:config-gerrit.html#change.submitWholeTopic[config.submitWholeTopic] set to
true. Ask your Gerrit administrator if you're not sure if this is enabled for
your Gerrit instance.
|===

== What is a Topic?

* A topic is a string that can be associated with a change.
* Multiple changes can use that topic to be submitted at the same time (assuming
  approvals, etc.).
* Submitting a change with a topic causes all of the changes in the topic *to be
  submitted together*
  ** Topics that span only a single repository are guaranteed to be submitted
  together
  ** Topics that span multiple repositories simply triggers submission of all
  changes. No other guarantees are given. Submission of all changes could
  fail, so you could get a partial topic submission. This is very rare but
  can happen in some of the following situations:
  *** Storage layer failures. This is unlikely in single-master installation and
  more likely with multi-master setups.
  *** Race conditions. Concurrent submits to the same repository or concurrent
  updates of the pending changes.

Here are a few intricacies you should be aware of:

1. Topics can only be used for changes within a single Gerrit instance. There is
no builtin support for synchronizing with other Gerrit or Git hosting sites.

2. A topic can be any string, and they are not namespaced in a Gerrit instance;
there is a chance for collisions and inadvertently grouping changes together
that weren’t meant to be grouped. This could even happen with changes you can’t
see, leading to more confusion e.g. (change not submittable, but you can't see
why it's not submittable.). We suggest prefixing topic strings with the author’s
username e.g. “username-” to help avoid this.

You can view the assigned topic from the change screen in Gerrit:

image::images/cross-repository-changes-topic.png[width=600]

=== Topic submission behavior
* Submitting a topic will submit any dependent changes as well. For example,
  an unsubmitted parent change will also be submitted, even if it isn’t in the
  original topic.
* A change with a topic is submittable when *all changes* in the topic are
  submittable and *all of the changes’ dependent changes* (and their topics!)
  are also submittable.
* Gerrit calls the totality of these changes "Submitted Together", and they can
be found with the
  link:rest-api-changes.html#submitted-together[Submitted Together endpoint] or
  on the change screen.

image::images/cross-repository-changes-submitted-together.png[width=600]

* A submission creates a unique submission ID
    (link:rest-api-changes.html#change-info[`submission_id`]), which can be
    used in Gerrit's search bar to find all the submitted changes for the
    submission. This ID is relevant when <<reverting,reverting a submission>>.

To better underestand this behavior, consider this following example.

[[example_submission]]
=== Example Submission

image::images/cross-repository-changes-example.png[width=600]

* Two repositories: A and B
* Two changes in A: A1 and A2, where A2 is the child change.
* Two changes in B: B1 and B2, where B2 is the child change.
* Topic X contains change A1 and B1
* Topic Y contains change A2 and B2

Submission of A2 will submit all four of these changes because submission of A2
submits all of topic Y as well as all dependent changes and their topics i.e. A1
and topic X.

Because of this, any submission is blocked until all four of these changes are
submittable.

|===
| Important point: B1 can unexpectedly block the submission of A2!
This kind of situation is hard to immediately grok: B1 isn't in the topic you're
trying to submit, and it isn't a depnedent change of A2. If your topic isn’t
submittable and you can’t figure out why, this might be a reason.
|===

== Submitting Changes Using Topics

=== 1. *Associate the changes to a topic*

The first step is to associate all the changes you want to be submitted together
with the same topic. There are multiple ways to associate changes with a topic.

==== From the command line
You can set the topic name when uploading to Gerrit

----
$ git push origin HEAD:refs/heads/master -o topic=[YOUR_TOPIC_NAME]
----

*OR*

----
$ git push origin HEAD:refs/for/master%topic=[YOUR_TOPIC_NAME]
----

If you’re using https://source.android.com/setup/develop[repo] to upload a
change to Android Gerrit, you can associate a topic via:

----
$ repo upload -o topic=[YOUR_TOPIC_NAME]
----

If you’re using
https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools.html[depot_tools]
to upload a change to Chromium Gerrit, you can associate a topic via:

----
$ git cl upload --topic=[YOUR_TOPIC_NAME]
----

==== From the UI

If the change has already been created, you can add a topic from the change page
by clicking ADD TOPIC, found on the left side of the top of the Change screen.

image::images/cross-repository-changes-add-topic.png[width=600]

=== 2. *Go through the normal code review process*

Each change still goes through the normal code review process where reviewers
vote on each change individually. The changes won’t be able to be submitted
until *all* changes in the topic are submittable.

The requirements for submittability vary based on rules set by your repository
administrators; often this includes being approved by all requisite parties,
passing presubmit testing, and being able to merge cleanly (without conflicts)
into the target branch.

=== 3. *Submit the change*

When all changes in the topic are submittable, you’ll see *SUBMIT WHOLE TOPIC*
at the top of the _Change screen_. Clicking it will submit all the changes in
"Submitted Together."

image::images/cross-repository-changes-submit-topic.png[width=600]

[[reverting]]
== Reverting a Submission

After a topic is submitted, you can revert all or one of the changes by clicking
the *REVERT* button on any change.

image::images/cross-repository-changes-revert-topic.png[width=600]

This will give you the option to either revert just the change in question or
the entire topic:

image::images/cross-repository-changes-revert-topic-options.png[width=600]

Reverting the entire submission creates revert commits for each change and
automatically associates them together under the same topic. To submit
these changes, go through the normal review process.

When submitting a topic, dependent changes and their topics are submitted as
{'fraction_non_alphanumeric': 0.06219611021069692, 'fraction_numerical': 0.005807671528903296, 'mean_word_length': 4.464575645756457, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2261119', 'n_tokens_mistral': 4085, 'n_tokens_neox': 3850, 'n_words': 2052}