Download: 3.10.0

Documentation: 3.10.0

Release highlights

Dropped support for Java 11

Java 11 is EOL since September 2023 and Gerrit already supports Java 17. Support for building Gerrit with Java 11 has been dropped and the default minimum version set to Java 17.

Rebase merge commits

It’s now possible to rebase merge commits directly from the UI.

Further improve Suggest Fixes

It’s now possible to have plugin generated suggested fixes directly in the UI. This opens the door for AI integration in the review process with Gerrit Code Review.

Please see more details here

Import changes from other servers

Imported projects from other servers is now fully supported, including also queries by change number on Lucene.

List enabled features/experiments via REST API

It’s now possible to list all experiments currently enabled on a Gerrit server by hitting the config/server/experiments endpoint. Please see more details here

Index management is now more accessible

A number of rest endpoints have been added to simplify management and observability of Gerrit indexes. It’s now possible to:

Less email notifications

Attention has been put on reducing the number of email notifications that Gerrit users receive even when no actions need to be taken.

  • Gerrit no longer send emails to everyone when additional reviewers or CCs are added. Please note, this is also a breaking change, see more details on the change, Change 400822.

  • Only add owner and uploader to the attention set if the label is copied over to the latest patchset, avoiding emails for votes on older patchsets that don’t affect the latest one. The reason for the user being in the attention set is also automatically updated.

  • Stop always cc’ing all “reviewers by email”, as otherwise they receive more emails than intended.

Support project~changeNumber when querying for changes

So far querying changes using the change: predicate did not allow to use the project~changeNumber format. However, since Change 387794 this is the default ID format returned in the ChangeInfo. Being able to use it directly for further queries would be advantageous.


This reinforces the concept that project~changeNumber should be the Id to use when trying to unique identify changes. This should be preferred to project~branch~changeId as this can theoretically contain duplicates, as specified in Issue 313935024

Configurable H2 cache pruning

Schedule of cache pruning of H2 caches is now configurable. This means that it doesn’t necessarily need to run on startup, therefore improving Gerrit startup times. Find more information in the docs.

Improved H2 Cache performances

Indexes have been added to the H2 cache databases, greatly improving performance of persistent caches, especially pruning and building bloom filters.

Allow fixes in Human comments via Rest API

Robot Comments have been officially deprecated for some time and the checks API framework is recommended since Gerrit 3.6. This is great as it provides a way of greatly reducing the size of the repository. However, unlike fixes suggested in Robot-Comments, Human Suggested fixes could not be applied programmatically, until now.

Gerrit 3.10 introduces a way of suggesting fixes that could then be programmatically applied with the the Apply Stored Fixes endpoint. This is done by adding an extra field fix_suggestions in CommentInfo that will be stored separately on NoteDB.

We don’t consider this a breaking change as the comment info payload is serialized as JSON and unknown fields should be ignore when parsing such data format. To be extra cautious, this field is only written if the experiment is enabled.

The experiment can be enabled in gerrit.config like so

          enabled = GerritBackendFeature__allow_fix_suggestions_in_comments

Native log deletion

So far Gerrit admins have always needed to rely on external tools to delete old logs files, now this feature is brought within Gerrit itself and made easily configurable. See more details under log.timeToKeep

Support for secondary emails

It’s now possible to update the commit message with a secondary email, both in the UI and via Rest API.

Update author and committer from the UI

It’s now possible to update the author and the committer identities directly in the UI.

Allow specifying plugins load ordering using plugins.loadPriority

Currently there is no way of specifying an order in which plugins should be loaded, other than alphabetical. However, in some complex Gerrit deployments, the order in which plugins are enabled during startup matters.

I.e. In a multi-site setup, if whichever flavour of events-broker implementation is loaded before pull-replication, then some events could effectively go lost, as pull-replication won’t be ready to consume them.

By using plugins.loadPriority we can now define the order in which plugins should be loaded, ensuring that no events are lost.

Note: If manually enabling/disabling plugins at runtime, the order is no longer guaranteed.

Important Notes

  • Change 394841: The commit-msg hook now operates as a no-op for temporary commits, which are identified by a lowercase word followed by an exclamation mark (e.g., fixup!, squash!).

    Configure gerrit.createChangeId to ‘always’ to force creation on these cases.

  • Change 394841 Introduce server_id in change_notes cache and update its version number.

    This means that if you’re using the change_notes cache, the file needs to be deleted. It will be automatically regenerated.

Submit Requirement Changes

  • Change 396517 allow a max_count = 50 for label predicates for SRs.
  • Issue 325070428 Fixed PostReview to not execute the submit rules twice when the SUBMIT_REQUIREMENTS or SUBMITTABLE options were requested

Schema and index changes

The accounts index version has been increased to version 14. The changes index version has been increased to version 86. The groups index version has been increased to version 11. The projects index version has been increased to version 9.

The schema version hasn’t been updated, however, because Lucen was bumped 2 versions from 7.x to 9.8 the upgrade is supported only from Gerrit v3.9, as Lucene libraries do not support more than one version upgrade at a time.

Online index schema upgrade from 3.9

By default, if you’re upgrading from 3.9, the index is automatically rebuilt upon Gerrit startup after the upgrade.

If you’re upgrading from 3.8 or an earlier version, you must use the Offline upgrade steps below, because of the Lucene upgrade mentioned above.

Note that it is advised to backup existing indexes prior the upgrade in case there is a need to rollback as already existing indexes are affected.

Offline upgrade

  • Download the new gerrit.war
  • Stop Gerrit
  • Backup the existing indexes in case a rollback is required
  • Ensure all installed plugins are compatible with the new API
  • Run init java -jar gerrit.war init -d site_path --batch
  • Reindex if you are upgrading from a 3.9 versions you don’t need to run reindex (see Online index schema upgrade from 3.9 above). If you still want to you will need to run reindex:

    java -jar gerrit.war reindex -d site_path

    If you are upgrading from a 3.8 or an earlier version, you must run a reindex of all indexes:

    java -jar gerrit.war reindex -d site_path

    See the reindex command for other options.

Online upgrade with zero-downtime

Gerrit v3.10.x supports zero-downtime upgrade from Gerrit v3.9 when configured using either high-availability or multi-site setup.

During the zero-downtime upgrade, Gerrit end-users will not experience any outage or service disruption and will be able to perform any read/write Gerrit operation seamlessly.

The zero-downtime upgrade process for high-availability or multi-site setups consists of the following steps (demo):

  1. Have Gerrit servers running v3.9 in high-availability or multi-site configuration, healthy and able to handle the incoming traffic properly.
  2. Set one of the Gerrit servers to unhealthy.
  3. Shutdown the Gerrit server, backup indexes in case a rollback is required, update gerrit.war and plugins to v3.10.x and start Gerrit again.
  4. Verify that the Gerrit server is working properly (e.g. run automated smoke tests) and then make it healthy again.
  5. Ensure the Gerrit server is fully caught up with the events that happened while it was down before directing traffic to it.
  6. Repeat steps 2 to 5 for each of the remaining Gerrit servers.


Downgrade to Gerrit v3.9 release is possible, but requires the following manual steps:

  1. Shutdown all migrated Gerrit servers
  2. Update the gerrit.war and plugins to the previous v3.9 version
  3. Restore all indexes from backup
  4. Run offline reindexing using the previous gerrit.war version
     java -jar gerrit.war init -d site_path --batch
     java -jar gerrit.war reindex -d site_path
  5. Startup Gerrit server

Native packaging

Updated almalinux to 9.3.

Breaking Changes

  • Change 409738: Added validation for label copy conditions

  • Change 407417: Branch links in change metadata now ignore status

    This means that clicking the branch link in the change detail section returns all changes associated with that branch, rather than the ones matching the change’s status. This will return a much greater number of changes than before, potentially impacting plugin/workflow performance.

  • Change 404717: Deprecate review command without project argument

  • Issue 325070428 Added new current_revision_number field to ChangeInfo that contains the current patch set number

    If the consumer is “well designed” adding one extra field in the JSON response should not break any existing behaviour. However, as it’s a change in the response payload, we’re highlighting this as potentially breaking change.

  • Change 400821: AutoMerger#lookupFromGitOrMergeInMemory: Remove mergeStrategy parameter

    This only impacts plugins.

  • Change 401198 DiffOperations: Remove unused diffOptions parameter from load methods

    Potentially breaking change as it impacts plugins that use the DiffOperations interface.

  • Deprecated robot-comments

  • Change 401977: Use RetryScheduler with backoff when server returns 429

    Gerrit UI will now automatically retry the Rest API calls to the backend when the HTTP status code is 429. This could lead to duplicated requests sent to the backend and consequently higher load on the system.

  • Change 396859: Disable dropdown items for downlading files >50 MB

    The 50MB limit is hardcoded and cannot be changed via configuration.

  • Change 400622: PluginCommandModule requires the plugin name in its constructor, hence all plugins that expose SSH commands need amending with an explicit constructor like the following:

    class MySshModule extends PluginCommandModule {
      MySshModule(@PluginName String pluginName) {

Other changes

  • Change 424338: Fix inline editor

  • Change 409729: Added REST endpoint to get the commit message of a change

  • Change 391494: Committer and author identities can be updated in change edit mode via REST

  • Change 394795: Remove ActionType, ChangeActions and RevisionActions enums forwarded as properties from ChangeActionsPluginApi implementation

  • Issue 240676565: Reviewer updates for reviewers by email are returned in change details

  • Issue 326096919: Fixed internal server error when posting a review with a ReviewerInput that didn’t set the reviewer field

  • Change 412617: Fix bug that allows inserting a broken pack

  • Change 413077: Plugins can use VersionedConfigFile to read/write a config file stored in git

  • Change 399657: Fix WorkQueue bug to ensure reliable execution of scheduled tasks

  • Change 392460: Added commit sha and change number to “commit already exists (in change)” Push Rejected response.

  • Change 399237: Improved WorkQueue task thread names

  • Change 412438: Fix behavior of rules.enable config to disable prolog

  • Change 419157: Solves a latency regression related to CallerFinder

  • Change 424957: Mention who owns the change in comment emails

Plugin changes

  • codemirror-editor updated to: d4f9247d3efb6a0e461af701986235511d05b7e3
  • commit-message-length-validator updated to: c38e0a9d36767092b20558b28eff7f546c6d754c
  • delete-project updated to: ea78b4b817151f47f6e3aca7bf1e90f14518caa1
  • download-commands updated to: 978e803c87416eb9e96236446b15b167017c0385
  • gitiles updated to: 4e8bd706e87eb11e3cfe2bfa9bbcb29020f39482
  • hooks updated to: f975f914312b258f84957d19f96014c3edd12644
  • plugin-manager updated to: cdd2d2d69666a70a16ac02bacf8e7fbbf4ca9979
  • replication updated to: 56b8ffbab5bf619c0b6b5d44f0255fd41b9e1c89
  • reviewnotes updated to: 18c867b6a957b3ddeb7a9e9789819fc60bdcd99a
  • singleusergroup updated to: 4bee62cbbc21979b841843dd5faaf79470a35966
  • webhooks updated to: 2e5ec3b3bcf5e7ba50edba9eca3c15c8057ad6c2

JGit changes

Bump JGit version to c0b415f. You can retrieve the full list of changes with:

  git log --no-merges --abbrev-commit --format=oneline  bf70c9f4c2e35548bc6d7853284b2c4d5e1d29ef...c0b415fb028b4c1f29b6df749323bbb11599495d

Notable changes are:

  • 81d64c913 Cache refreshed loose ref dirs in SnapshottingRefDirectory
  • 72fa0a53e TreeRevFilter: correct changedPathFilter usage for multi-paths inclusion
  • 9e841dd4a PathFilterGroup: implement getPathsBestEffort()
  • c1eba8abe DfsPackFile: get commitGraph.readChangePaths from repo config
  • 21f7fdff7 Introduce core.trustLooseRefStat config
  • 5c94dcc56 DfsObjDatabase: Let object database instantiate DfsPackFiles
  • 049749558 DfsPackFile: Abstract the bitmap loading to support other backends
  • 3e624306d Allow to discover bitmap on disk created after the packfile
  • 15363e4c3 PackWriterBitmapPreparer: Do not generate bitmaps for excessive branch tips.
  • c64664925 CherryPick: add ability to customise cherry-picked commit message
  • ba5adc4ce Add tests for handling pack files removal during fetch
  • ee4443091 PackWriterBitmapPreparer: Set limit on excessive branch count
  • 788487316 BasePackFetchConnection: Skip object/ref lookups if local repo is empty
  • faa50c683 LooseObjects: Use File#exists when possible
  • b2abab271 DfsReader: give subclasses visiblity over the pack bitmap index
  • e25bf9573 PackBitmapIndex/StoredBitmap: Expose size and counts
  • 52c18ae15 PackWriter/Statistics: Remove the bitmapt hit stats
  • ab132937f FooterLine: Protect from ill-formed message
  • 340cc787a Improve footer parsing to allow multiline footers.
  • aab75dba7 BitmapIndex: Add interface to track bitmaps found (or not)
  • 4f18c5095 Optimize RefDirectory.getRefsByPrefix(String…)
  • b761a0fc3 Use try-with-resource to ensure UploadPack is closed
  • 3937300f3 Optimise Git protocol v2 ref-prefix scanning
  • 5f563e386 UploadPack: use want-refs as advertised set in fetch v2
  • 093bde518 BasePackFetchConnection: Avoid full clone with useNegotiationTip
  • 8ca649c16 Generate SBOMs using cyclonedx maven plugin
  • f91afe5f5 DfsPackFile: Do not attempt to read stream if pack doesn’t have it
  • 9323b430b PackObjectSizeIndexLoader: Log wrong bytes on exception
  • 0f078da4e FileBasedConfig: in-process synchronization for load() and save()
  • cb46ee354 FileBasedConfig: ensure correct snapshot if no file
  • f93ccb7fd RebaseCommand: return correct status on stash apply conflicts
  • 42917767f UploadPack: Delay freeing refs in sendPack()
  • 11429c6d1 Improve naming of disk cache pruning thread/task

Security Fixes

  • Issue 321784734 Fix endless loop when using “is:watched” in project watches.

    Previous setting up email notification with is:watched predicate would create an infinite loop that would take a CPU offline.

Documentation changes

Other dependency changes

Frontend changes

  • Issue 315957653: account-chip hover-card shows correct email for author and committer

  • Change 397457: Add syntax highlight support for cjs, cts, and mts file

  • Change 400824: Fix scrolling to diff rows covered by the header UI

  • Change 402837: Revert CLs should still say Ready To Submit UI supports updating commit message using a registered secondary email

  • Change 407157: Add plugin endpoint for account links

  • Change 407660: Turn Reply button into Sign in button when logged out

  • Change 407820: Improve reviewer autocomplete on restricted refs/branches

  • Change 407823: Show checks findings on file list

  • Change 407825: Prevent pencil wrapping by itself in change metadata

  • Issue 40015337: Fix browser BACK button when going to plugin pages

  • Change 416260: Diff processor was simplified. It does not split up into multiple async chunks of work anymore.

  • Change 396859: Disable dropdown items for downlading files >50 MB

  • Change 401384: Stop considering combo key after first hit

  • Change 403277: Only show the Show Blame button if blame is enabled.

  • Change 416001: Add a replysent plugin event

  • Change 411358: Fix revision actions constantly showing as “loading” when not signed in

  • Issue 40004507: Added support for filtering branches/tags in plugins

  • Issue 330574510: Fix issue with gr-file-list-header not working correctly after writing a comment

  • Change 394446: fix tabbing for non-emojis starting with colon

  • Change 395461: Fix emoji selector for all keys

  • Change 399797: Enable highlighting for Qt code components

  • Issue 335613081: Fix the saving and rendering of diff-preferences not having an immediate impact on the UI

  • Change 421257: Fix redirection to the target page upon a successful login

  • Issue 295374158: Fix UI issue where the focus was unpredictably lost while typing a draft comment

  • Change 420337: Fix the login button disappearing when the page title was big enough in the navigation bar

  • Issue 337076005: Fix vertical alignment of header icon and text

  • Change 425577: Fix bogus account labels