Download: 3.12.0-rc4

Documentation: 3.12.0-rc4

Release highlights

Java 21

The language level used for Gerrit source code is set to Java 21, matching its distributed code level since Gerrit v3.11.

It is now mandatory to migrate the Java Virtual Machine to Java 21 and there is no possibility to rebuild Gerrit source code with Java 17 anymore. Also, all the non-core plugins need to be rebuilt and verified with Java 21; existing Java 17 plugins may not load or work properly.

Gitattributes configuration support in JGit merge driver

Gerrit support now the gitattributes with merge driver configuration, introduced in Change 441721.

When Gerrit performs server-side merges, it supports now the reading and processing of the gitattributes reading the global, repo, and in-tree gitattributes files.

The support of gitattributes is implemented for the built-in binary and union merge drivers.

Allow global site-wide override for label’s copyCondition

There are two new config variables introduced with Change 446062:

  • label.<name>.labelCopyEnforcement for enforcing an additional copy condition for all labels on all projects

  • label.<name>.labelCopyRestriction for reducing forcibly any copy condition for all labels on all projects

When the two settings are defined in gerrit.config, then for every project, the final copyCondition is equivalent to (<labelCondition> AND NOT <copyRestriction>) OR <copyEnforcement>

This new behaviour is covered by the experiment feature flag GerritBackendFeature__enable_central_override_for_code_review_copy_condition.

Example of labelCopyEnforcement is making sure all negative votes are copied; similarly labelCopyRestriction could be used for making sure only trusted contributors are allowed to submit changes without reviewers re-confirming that their comments have been addressed.

Introduce the group deletion functionality

It is possible to allow users to delete groups through a new deleteGroup global capability. All the users and groups with the new capability, will have access to the delete group button and the associated backend REST-API that allow to remove Gerrit groups.

In order for a group to be deleted, there are some prerequisites that need to be satisfied:

  • The given group is not a system group
  • The given group is an internal group (it is assumed that we will not allow to delete external groups)
  • The given group is not the owner of any other group(s)
  • The given group is not used in any ref permissions for any projects

New H2 v2 storage backend for persistent caches

The H2 library is upgraded to v2 which provides fully multi-threaded operations and a lower memory footprint, as presented in the GerritMeets of March 2025. Migrating from H2 to H2 v2 requires either the rebuild of the persistent caches from scratch or the execution of a migration tool to translate the legacy cache files to the new format.

Important Notes

Schema and index changes

Gerrit schema version is unchanged; however, because of the Lucene library bump to 10.1.0, the on-line upgrade is possible only from Gerrit v3.11 and not from earlier releases.

All the indexes versions have been increased therefore requiring a reindex:

  • accounts index version updated to 15.
  • changes index version updated to 87.
  • groups index version updated to 12.
  • projects index version updated to 10.

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 all indexes:

    java -jar gerrit.war reindex -d site_path

    See the reindex command for other options.

Online upgrade with zero-downtime

Gerrit v3.12.x supports zero-downtime upgrade from Gerrit v3.11 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.11 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, update gerrit.war, plugins and libs to v3.12.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

Downgrade to Gerrit v3.11 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.11 version
  3. Init Gerrit
    java -jar gerrit.war init -d site_path --batch

Native packaging

The GPG keys for GerritForge’s distribution site have changed and need to be reimported before the upgrade.

  • On Debian / Ubuntu): apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 55787ed781304950

  • on AlmaLinux / RedHat / Fedora: rpm --import 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x72adb205736d7147da56e8c955787ed781304950’

The Docker-based distributions have been updated:

  • AlmaLinux bumped to 9.5

  • Ubuntu bumped to Eclipse Temurin 21.0.6_7 (24.04.1 LTS)

Security Fixes

  • Change 435337 REST API responses are now rendered in the browser rather than downloaded, with XSS protection and blocking the use in i-frame.

Known issues

  • Issue 309098227 Change 360646: The introduction of a per-request ref cache for better performance may break the repository consistency

    The addition of a new core.usePerRequestRefCache setting, true by default, introduced a per request (currently per request thread) ref cache, helping reduce the overhead of checking if the packed-refs file was outdated. However, in some scenarios, such as multi-site or concurrency between git-receive-pack and git-gc, it may lead to split-brain inconsistencies and, in the worst-case scenario, to the corruption of the underlying repository.

Breaking Changes

  • Change 447781 Disabled loading and executing ‘rules.pl’ by default.

    Prolog rules have been deprecated since Gerrit 3.6; they are now officially disabled by default. Gerrit administrators are required to inform all the project owners and convert the Prolog rules to Submit Requirements.

    NOTE: It is still possible to enable the Prolog rules processing again with rules.enable = true in gerrit.config, bearing in mind that the option may not be available anymore in future versions of Gerrit, therefore should be used only as temporary workaround during the migration from Prolog to Submit Requirements.

  • Change 440743 Do not notify listeners when performing online reindexing.

    When performing online reindexing, the notification to listeners and consequent sending of the index-change messages in high-availability and multi-site scenarios was potentially causing unnecessary traffic and CPU utilisation during the schema index updates.

    NOTE: If the reindexing is performed for refreshing outdated index records the online reindexing commands would need to be executed against all the nodes of the Gerrit cluster, as the missed listeners notifications would not trigger the reindexing elsewhere.

  • Change 449321 Change 448244 Set Verified label default function to NoBlock for new sites.

    Label functions are deprected and the submittability of changes needs to be encoded as Submit Requirements, therefore new Gerrit sites are encouraged to define their submittability rather than relying on the legacy label functions deprecated since Gerrit v3.6.

    NOTE: Existing sites would not be impacted, unless they were relying on the default label function; however, Gerrit project owners are invited to remove the use of label functions and use Submit Requirements instead.

  • Change 451223: Added a new MigrateLabelFunctions site program for helping with the migration from label functions to Submit Requirements.

  • Issue 390443239 Swap project-created/ref-updated in stream events upon project creation

    Gerrit always produced the project-created/ref-updated in the wrong order, generating the ref-update of inexistent projects just created. The order is now rectified; however, existing stream events consumers may rely on the previous incorrect ordering and potentially break.

  • Change 457802: Users with the Administrate Server can see all changes, branches and tags, including private changes and refs/meta/config.

    Administrators own the Gerrit service and are responsible to investigate issues; allowing to access everything simplifies the troubleshooting, avoiding them to first assign permissions to themselves, investigate the issue and then remember to undo the permission changes.

    Also note that the skip-visibility option when querying changes is deprecated and effectively ignored. It will be removed in the next version of Gerrit.

    NOTE: With this change, Gerrit would not allow anymore to separate the roles of the security administration and the service management, therefore it is highly recommended to carefully review all the users and groups with the Administrate Server.

  • Change 435338: Patchsets are now downloaded as plain-text patch files using the ?raw parameter and not base64 or ziped.

  • Change 465369: Robot comments are disabled by default. Support for robot comments will be removed with the next release. Checks should be used instead.

New Features

  • Change 442981: Allow restricting users from deleting their own accounts.

    Introduce accounts.enableDelete configuration for disabling the ability for users to remove themselves from the Gerrit Web-UI.

  • Change 445801: Introduce is:POSITIVE and is:NEGATIVE as predicates for copyCondition on labels, allowing generic matching of any positive or negative reviews.

  • Change 447745 Change 459463 Change 447749 Change 447748 Change 447746 Assign TRACE_ID for every request and include in all SSH and HTTP interactions.

    Allow to follow the TRACE_ID across all interactions and logs, including the sshd_log and httpd_log entries.

  • Change 444441 Add changeis predicate as Copy-Condition expressions, with any predicate supported by is:{predicate}

  • Change 444962 Change 457801: Add configuration for case-insensitive email matching in account resolution and API.

    Enable case-insensitive matching of the name part of e-mails on a per-domain basis, as configured in accounts.caseInsensitiveLocalPart.

  • Change 442021: Add success_count and error_count metrics for ssh requests.

  • Change 447841: Disallow addition of new rules.pl files in projects

    Adding a new rules.allowNewRules = false the Gerrit admin can reject the addition of new rules.pl files into the projects.

  • Change 456684 Change 456685: Added draft comments cleanup REST-API and SSH command.

  • Change 456182: Added draftsCleanup background job and automatic scheduled configuration.

  • Change 447629: Added support for adding the Project Owners group as a reviewer

  • Change 445362: Added support for commit validators to return a status + metadata in addition to messages

  • Issue 317340200: Added support for creating a branch on an empty commit.

    Similar to creating a project with an empty commit, allow to create a branch not having any initial commit.

  • Issue 401141848: Fix ref existance check when creating new refs

    Gerrit v3.6 introduced a new check for verifying the existance of refs before crating new refs and avoiding misleading LOCK_FAILURE errors. The check was implemented using a Repository.resolve() API which would expand the ref name as it was a logical name resolution causing the inability to push some refs, like tags that use the git describe in their names. The issue is fixed by using a proper refs finding and brings back the full refs creation functionality.

  • Change 439226: The new configuration style, where index name is explicitly provided as subsection name.

  • Change 447221: Store/provide merge conflict information for revisions created by Gerrit

    For revisions that are created by Gerrit, we know whether conflicts are present and which commits were used as ‘ours’ and ‘theirs’ during the Git merge that created the conflicts. For those revisions we can store this information in NoteDb and make it available to callers in RevisionInfo.

  • Change 446721: Provide index metric for accounts/changes/groups/projects

    Introduce four new Gauge metrics to track the number of documents in the respective search indexes:

    • indexes/accounts
    • indexes/changes
    • indexes/groups
    • indexes/projects
  • Change 447747: Include SSH session in the error_log entries

    The inclusion of the SSH session in the error_log allows to look for the errors associated with a specific session and trace, making it easier to troubleshoot problems.

  • Change 457722: Allow SubmitRequirement atoms to return an explanation

  • Change 447776: Make “message:” predicate for SR consistent with search

Performance improvements

  • Change 442022: Faster replica startup when group reindexing enabled by parallelizing reindexing of groups

  • Change 448182: H2Cache BloomFilter will no longer degrade forever as it is rebuilt automatically after pruning if >= 25% invalidated

  • Change 447141: Reduce bulk action query result payload by not getting already available SUBMIT_REQUIREMENTS data

  • Change 447344: The List Labels endpoint now supports filtering by voteable labels.

  • Issue 390453038: Configure the number of open changes’ refs advertised on push to a repository for reducing CPU utilization and latency.

  • Change 449582: Fix the reference counting for a correct release of repositories from the JGit in-memory repository cache.

    Previously the repositories were never released in the JGit in-memory cache, causing the overload of the JVM heap and consequent degradation of the performance due to the high CPU utilization caused by the continuous JVM GC.

  • Change 448181: With H2 v2 caches are multi-threaded therefore can be set operational concurrently with the building of bloomFilters

Bug fixes

  • Change 453981: gc_log is no longer overwritten when rotated.

  • Change 449582: Fix progress logging in MultiProgressMonitor, which had the unintended side effect to log the progress the receive commits operations

  • Change 464703: Cancel diff tasks failing due to timeout or interrupted preventing them from consuming resources unnecessarily

  • Change 442424: Respect project config and user preference for creating changes as work-in-progress by default for the Revert REST endpoint

  • Change 447640 Change 447639: Reviewer suggestion for empty query: Fallback to project owners and reviewers of recent changes.

Frontend changes

  • Change 449581 Add HTTP request header to distinguish plugins from core.

    A new HTTP header X-Gerrit-Request-Origin added to the requests coming from the Gerrit Web-UI helps identify whether an API is invoked from core-ui or plugin:<plugin-name> for requests originated from plugins.

  • Change 464661: Allow opening edit preference in editor view.

  • Change 435399: Default patchset patch file download in the UI to plain-text patch files.

  • Change 443524: UiFeature__push_notifications experiment is now final and the feature flag is removed, making the browser notifications always enabled for all Gerrit sites.

  • Change 447628: Improved error message when trying to add a non-internal group as a reviewer

  • Change 460961: Send revert notifications from user that created the revert rather than the user that has set the change as ready.

  • Change 458461: The UI tooltop for submit requirement atoms will now show explanations if implemented by the underlying predicate

Other Changes

Documentation changes

  • Change 447161: Clarify the documentation of sshd.waitTimeout

  • Change 451181: Document footer frontend endpoint decorators

  • Change 444481: Document the use of Gerrit-CI by the contributors and maintainers

  • Issue 381372612: Update the config-gerrit documentation mentioning a caveat of using listProjectsFromIndex setting

Plugin changes

  • Change 441561 Introduce a new CachesApi endpoint for accessing and flushing caches from plugins.

  • Change 452183 Change 457362: Introduce Repository leak detection when using AbstractDaemonTest, which can be disabled using @NoGitRepositoryCheckIfClosed

  • Change 447001: Add publish-edit event type for plugins to use.

  • Change 445142 Change 445601: Added an extension point that allows to get to know about commit validation options

  • Change 457542: Added extension point that allows listening to operations retries

  • Change 455641: Updated ExternalIncludedIn extension point to allow plugins to use change information to obtain included-ins

  • Change 444804 Change 442742: Mark setup_gjf.sh and run_gjf.sh for removal and replace them with one script gjf.sh.

  • Change 445202: Allow custom uploaderin operands for CopyCondition, having the format of uploaderin:<operand>_<pluginName>

## JGit Changes

  • Change 469321: Update jgit from stable-6.10 (e328d203f) to servlet-4 branch (7a46fa6f8) which follows the jgit master branch with servlet-api downported to 4.0.4.
```shell
git log --no-merges --oneline e328d203f..7a46fa6f8
```

Notable changes are:

  • c2a8e0026 midx: reader for the multipack index
  • 4a5dfce0d SystemReader: Add support for XDG_CACHE_HOME
  • e2ddcc969 TreeRevFilter: enable Bloom Filter usage with ChangedPathTreeFilter
  • 52dc9fdd0 BlameGenerator: Use cache only for candidates modifying the path
  • ac5146ffb FileReftableStack: use FileSnapshot to detect modification
  • 1ff9c2a1c FileReftableDatabase: consider ref updates by another process
  • 68f454af4 DescribeCommand: Add exclusion matches using setExclude()
  • 8720b352a Insert the Change-Id at the end of the footer block
  • 70a3131d6 Update Change-Id insertion logic to insert after footers
  • bec51e7d7 pgm.MultiPackIndex: CLI command to write/print the multipack index
  • 871c5e177 BlameGenerator: cache and reuse blame results
  • 2d8777536 Downgrade from servlet-api 6.1.0 to 4.0.4
  • c625d67f8 URIish: fix stack overflow in regex matching
  • e9f43b6c1 midx.MultiPackIndexPrettyPrinter: pretty printer to debug multi pack index
  • 072e93fde midx.MultiPackIndexWriter: a writer for the multipack index format
  • 4c4bef885 DirCacheCheckout.preScanOneTree: consider mode bits
  • f41253804 Merge: improve handling of case-variants
  • ff3a15049 Improve configuration of trusting file attributes in FileSnapshot
  • a86e2a7d7 Config: add getters for primitive types without default value
  • 772ee0e5f Log pruned packfiles as debug and not warn logs
  • 32b9a9523 Submodules: Update submodule with deleted worktree
  • 7b8ddc2ce RefDatabase#getReflogReader(String): use #exactRef to resolve refName
  • fda44a444 Add RefDatabase#getReflogReader methods
  • e9094fffd RevertCommand: use only first line in revert commit message
  • df7810957 Submodules: use relative paths for worktree and gitdir
  • bd57a19fa TreeWalk: Make a null check before dereferencing the config variable.
  • 6fa28d767 Add pack-refs command to the CLI
  • 307ef6b4b GitTimeParser: A date parser using the java.time API
  • ba905906c Change default similarity score to 50(%) to match git’s default
  • b2accb0e9 GPG: use bouncycastle PGP secret key parsing out of the box
  • d1a14b8ff SSH signing: implement a SignatureVerifier
  • c9958e9b7 SSH signing: implement a Signer
  • 4902b2baf Add numberOfPackFilesAfterBitmap to RepoStatistics
  • 1519c1479 Align request policies with CGit
  • 0155f8bf6 RevolveMerger: honor ignoreConflicts also for binary files
  • 1332b5156 Record failing paths in recursive merge.
  • 0fd76114e Replace custom encoder Constants#encodeASCII by JDK implementation
  • e5d289899 Replace custom encoder Constants#encode by JDK implementation
  • 9fec73970 Do not set headers if response is already committed
  • a78e6eaef Signing: refactor interfaces
  • 81199f02f Lib: Fix ssh value for gpg.format throwing an IllegalArgumentException
  • f9beeb3b3 Add worktrees read support
  • 47fd412af RepoProject: read the ‘dest-branch’ attribute of a project
  • 48465f840 RepoCommand: Copy manifest upstream into .gitmodules ref field
  • 1dd6324d4 RepoProject: read the “upstream” attribute of a project

Other dependency changes

  • Update auto-value to 1.11.0

  • Update guava to 33.4.0

  • Update reload4j to 1.2.26

  • Update org.tukaani:xz to 1.10

  • Update dropwizard.metrics to 4.2.30

  • Update mina-sshd to 2.15.0

  • Update mina-core to 2.0.27

  • Update commons-io to 2.18.0

  • Update autovalue to 1.11.0

  • Update truth to 1.4.4

  • Update Lucene to 10.1.0

  • Update h2 to 2.3.232

  • Update gitiles to 1.6.0

  • Update bouncycastle to 1.80

  • Remove net.i2p.crypto:eddsa

  • Update errorprone to 2.36.0

  • Update flogger to 0.8

  • Update gson to 2.12.1

  • Update jgit to f22643b39