Download: 3.12.3 | 3.12.2 | 3.12.1 | 3.12.0
Documentation: 3.12.3 | 3.12.2 | 3.12.1 | 3.12.0
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.
Gerrit now supports gitattributes with merge driver configuration, introduced in Change 441721.
When Gerrit performs server-side merges, it now supports reading and processing gitattributes from the global, repo, and in-tree gitattributes files.
The support of gitattributes is implemented for the built-in binary and union merge drivers.
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.
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 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 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.
NOTE: Please check the Known Issues section to be aware of potential problems introduced by this update.
Gerrit 3.12 has had a total of 55 contributors, of which 7 first-time contributors:
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.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.
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):
Downgrade to Gerrit v3.11 release is possible, but requires the following manual steps:
java -jar gerrit.war init -d site_path --batch
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)
The new H2 library brings multi-threaded operations, but also one critical issue, reported on cache files corruptions upon Gerrit ungracefully shutdowns.
NOTE: The
gerrit.sh stopcommand performs a forced shutdown if the JVM does not exit within the shutdown timeout.
Whilst the problem is investigated, you may consider using alternative persistent cache backends like:
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.
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 = trueingerrit.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.
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 for investigating issues; allowing access to everything simplifies 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 no longer allow to separate the roles of security administrator and 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.
Change 457007: The update to Lucene 10.1.0 removes support for the complement search operator ~ which was removed for performance reasons in Lucene commit 22bbc603b4.
Change 451223: Added a new MigrateLabelFunctions site program for helping with the migration from label functions to Submit Requirements.
Change 472521: Render markdown in check run description.
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.
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:
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
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
Change 473702: Prevent Duplicate Replies When Applying Fix.
Resolves an issue where applying a fix to a comment unexpectedly created two draft replies instead of one, which was leading to two identical comments being published.
Change 469725: Fix incorrect cherryPickOf value when using the REST API to cherry-pick a non-current patchset.
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.
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 473723: Prioritize and display all reviewers with votes or attention.
Change 473722: Fix header layout for very long subjects.
The reviewers list UI component was hiding a reviewer who had voted (e.g., +2) if they were without attention and there was another 6 reviewers with attention. Now all reviewers who have cast a vote or are in the attention set are displayed.
Change 473701 Fixed the display of removeLabel permission in access section UI.
Change 471321: Enable keyboard shortcut for “Reset To” command in the download dialog.
The initial implementation was limited to 5 shortcuts, but with the current default configuration, there are 6 commands (Branch, Checkout, Cherry Pick, Format Patch, Pull, Reset To). This update ensures that all commands, including Reset To have a keyboard shortcut.
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
Change 437803: Script providing extended git gc functionality
Change 438123: Add python-based CLI to maintain Gerrit sites
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
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>
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.
git log --no-merges --oneline e328d203f..7a46fa6f8
Notable changes are:
numberOfPackFilesAfterBitmap to RepoStatisticsConstants#encode by JDK implementationUpdate 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
Bug Fixes
Change 495501: sequence set SSH command now enforces strictly increasing sequence values.
Attempts to set a sequence (for changes, accounts, or groups) to a value lower than its current value are now rejected immediately.
Issue 439435039: Check for account existence with username scheme for HTTP and HTTP_LDAP only.
Previously, when LDAP authentication was enabled, user lookups were incorrectly performed using the username external ID scheme, which could lead to failed logins. This change restricts username-based lookups to HTTP and HTTP_LDAP authentication protocols only, ensuring LDAP uses the correct gerrit scheme.
Issue 439859126: Return HTTP 401 for any incoming authentication request with a password longer than 71 chars
Fixed password validation to explicitly fail when a password is longer than 71 characters, matching the Bcrypt limitation. This prevents internal errors and ensures clients receive a proper HTTP 401 (Unauthorized) response instead of an internal exception.
Issue 444049514: Prevent blocking HTTP calls to wait indefinitely.
Fixed an issue where, under heavy concurrent Git/HTTP load, some worker threads could remain stuck indefinitely due to unbounded blocking in synchronous write callbacks. Blocking callbacks are now properly capped by the configured httpd.idleTimeout, ensuring idle or stalled Git/HTTP requests are terminated and threads are released as expected.
Issue 397701289: Notify reviewers on change edit in UI.
Restored reviewer notifications when a change is edited through the web UI. This makes notification behavior consistent with other change updates, ensuring reviewers are informed when an edit may require another review.
Change 510442: Allow WorkQueue to be used with the failsafe.dev library in the high-availability plugin to schedule retryable tasks.
Issue 446941362: Fixed git-upload-pack errors on replicas by skipping unloadable changes.
Fixed an issue where corrupted or unloadable changes could cause Internal Server Errors during git-upload-pack on replicas.
Issue 456521736: Avoid “change N missing from ChangeSet[][]” error when submitting a change with a stale index entry.
Fixed an issue where submitting a change could fail if its index entry was out of sync with the underlying NoteDb data. Gerrit can now backfill missing change information directly from the repository when the index is stale, ensuring that valid changes can still be submitted without repeated retries.
A new configuration option, change.backfillMergeSuperSet, controls this behavior. When enabled, Gerrit reloads change data from the repository instead of failing due to a stale index, making change submissions more reliable in setups that use asynchronous indexing or multiple primaries.
Change 497281: Fixed the name of the operations endpoint latency metric to ensure accurate per-endpoint performance tracking.
Corrected the name of the operations endpoint latency metric, which was previously using the same name as the general performance/operations metric.
Issue 440670678: Introduce listener hook for project-wide change index deletions.
Previously, when all changes for a project were deleted from the index, no listener notifications were triggered. This prevented plugins such as high-availability and multi-site from detecting these deletions and cleaning up related state.
A new listener hook, onAllChangesDeletedForProject, has been added and is now invoked whenever a project’s indexed changes are removed in bulk. This ensures that dependent plugins are notified consistently and can react reliably to project-wide deletions.
Documentation Updates
Change 500401: Document the HTTP password limit of 71 chars.
Change 520901: Document the REST API Get Patch parent parameter.
Change 515462: Remove instructions to build with Java 17.
UI Fixes
Change 511981: gr-access-section: Fix bug with deleting permissions in handleAddedPermissionRemoved.
Resolved an issue where removing a permission (e.g., Delete Own Changes) could also unintentionally remove another permission (e.g., Delete Changes) and incorrectly display an undo option. The UI now correctly tracks and removes only the selected permission, and the undo button appears only for previously saved permissions.
Change 515221: Allow Change Owners to suggest edits in comments.
Change owners can now propose suggested edits directly in comments, even if they are not the original authors of the change.
Change 517961: gr-permission: Fix deleting rule in gr-rule-editor.
Resolved a UI issue where deleting a rule could affect the wrong entry due to DOM node reuse.
Change 512922: Fix rendering of multiple suggested edits when comments contain tabs.
Previously, only the first suggested edit was shown when a comment contained multiple suggestions. Now, all suggestions are displayed correctly, allowing users to view and apply each one individually.
Change 509501: gr-textarea: Fix getSelection() on Safari.
Resolved an issue in the text area component where pressing Option + Right Arrow on Safari did not move the cursor or update the text selection as expected.
Change 509463: Fix bug with disabledMenuActions in gr-change-actions.
Fixed a UI issue where menu actions were not properly disabled when disabledMenuActions was set, allowing users to trigger actions multiple times while one was still running.
Issue 445614699: Fix deleting text under Firefox when selecting all text.
Resolved a compatibility issue in the text area component where deleting all selected text did not work correctly in Firefox.
Issue 440874371: Avoid hacking the GitRepositoryManager on init, which broke the initialisation of a Gerrit site with Zookeeper.
Resolved an issue that caused Gerrit site initialization to fail when using a global ref database such as Zookeeper.
Enhancements
Issue 440798012: Add scheduled reindexing of accounts.
Add scheduled reindexing of accounts. Previously scheduling reindexing was possible only for Changes, Projects and Groups.
Dependency Updates
Issue 442989229: Update Jetty to 9.4.57.v20241219.
Please refer to the jetty.project changelog for details.
Plugin changes
delete-project updated to b1a05c0c2ef2d5fe60f0c4c5863576707540dbbf
Notable changes are:
Issue 440670678: Use centralized change index deletion when removing a project.
Updated project deletion to use the higher-level ChangeIndexer.deleteAllForProject() API instead of calling low-level index operations directly. This ensures that all project changes are removed from the index in bulk and it triggers the appropriate deletion notifications.
You can retrieve the full list of changes with:
git log --no-merges --oneline 08035f1ef90258629346ab033af27c454a7fcc2d..b1a05c0c2ef2d5fe60f0c4c5863576707540dbbf
Bug Fixes
Issue 437141693: Fix an issue introduced in Gerrit 3.12.1 where plugins' persisted caches weren't persisted anymore.
Issue 437005987: Prevent creation of tag via rest-api if project is in read only state.
Change 498181 Fix Submit Requirements that used ownerin:group_name with Gerrit internal group names. Groups with external subgroups were unaffected.
Issue 435230894 Fix instances where changes sequence ref is rewind
Enforced strictly increasing ref sequence values to prevent rare stale-read issues on NFS.
Frontend changes
Issue 433273946 gr-edit-controls: Fix alignement issue with autocomplete on mobile
Change 497461: Inline link on branches and tags on a repository's branch and tag lists now respect gerrit.primaryWeblinkName configuration.
Change 464281: “Browse” link on a repository's General page now respect gerrit.primaryWeblinkName configuration.
Enhancements
Change 486062 Remove index-only entries after (re)index with --reuse option
Added a post-reindex cleanup step for the --reuse option to remove index entries without corresponding NoteDb changes. Cleanup runs per project, starting as soon as indexing for that project completes.
Change 486081 Enabled setNoLimit in the InternalQuery API, allowing the AllChangesIndexer to exponentially increase page size when scanning large result sets. This can significantly reduce the number of index queries (e.g., 200 pages down to 4 for 100K results).
Other dependency changes
Documentation
Known issues
Issue 437141693: Plugins' persisted caches aren‘t persisted anymore, due to the removal of the lazy initialization of the H2Cache’s bloomfilter.
The introduction of the performance improvement in Change 473682 has removed the lazy initialization of the H2Cache's bloomfilter which is needed for enabling the persistence of the cache keys. The consequence is that the plugins that were declaring a persistent cache would not be able to persist their cached values anymore.
JGit changes
Change 491146: Bump JGit to 010858e24
This includes a fix for races that could occur when deleting refs and another actor tries to pack refs.
You can retrieve the full list of changes with:
git log --no-merges --oneline 7a46fa6...010858
Notable changes are:
Bug Fixes
Issue 430336832: Align delete refs to the rest of Gerrit
The ChangeEditUtil.deleteRef() and StarredChangesUtilNoteDbImpl.deleteRef() failed to set the new object id in the RefUpdate, causing a situation where other parts of the code are expecting a non-null SHA1 and therefore causing potential NPEs.
Change 486742: Fixed project list cache data race due to Caffeine issue
Change 473701: Fixed removeLabel permission not being displayed in access section UI
Issue 412679366: Fixed an issue with a comment's resolved flag not updating
When PostReview.comments is set, they are supposed to replace the value of the draft with the same id (if one exists). The logic were replacing the message, but not the resolved bit. Leading to the update being lost.
Change 482026: Fixed reindexing stale changes in projects with encoded characters
Without this fix, any project with characters in its name that must be encoded would fail staleness checks with a “repository not found: Invalid name” message
Change 473802: Fix wrong column sort in change list
Change 478326: Fix paper-toggle-button for iOS
Change 486743: Fix a special case for preview/apply fix
Change 487821: Use ASM9 opcodes to avoid plugin Jar scan warning
Change 473682: Do not wait for H2 bloomfilter building to respond to requests
Enhancements
Change 481621: Checks: Display hovercard for previous run attempts
Change 481583: Add ‘shift+h’ keyboard shortcut to hide check code pointers in the diff view
Change 474701: Prompt users before becoming the change uploader
Change 462141: Improve error message when failing a submission for FAST_FORWARD_ONLY projects, avoiding also an NPE on the error_log
Documentation Updates
Plugins
Update codemirror-editor to 6a33a4
You can retrieve the full list of changes with:
git log --no-merges --format=oneline 5248349...6a33a4
Update replication to b0e7aa63c
You can retrieve the full list of changes with:
git log --oneline --no-merges --no-decorate ede3010e..b0e7aa63c