Marian Harbach | ebeb154 | 2019-12-13 10:42:46 +0100 | [diff] [blame] | 1 | :linkattrs: |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 2 | = Gerrit Code Review - Accounts |
| 3 | |
| 4 | == Overview |
| 5 | |
Edwin Kempin | 7a16bee | 2021-09-07 15:24:18 +0200 | [diff] [blame] | 6 | Gerrit accounts are stored in link:note-db.html[NoteDb]. |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 7 | |
| 8 | The account data consists of a sequence number (account ID), account |
Ben Rohlfs | 9c960cb | 2020-02-02 22:12:30 +0100 | [diff] [blame] | 9 | properties (full name, display name, preferred email, registration |
| 10 | date, status, inactive flag), preferences (general, diff and edit |
| 11 | preferences), project watches, SSH keys, external IDs, starred changes |
| 12 | and reviewed flags. |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 13 | |
| 14 | Most account data is stored in a special link:#all-users[All-Users] |
| 15 | repository, which has one branch per user. Within the user branch there |
| 16 | are Git config files for the link:#account-properties[ |
| 17 | account properties], the link:#preferences[account preferences] and the |
| 18 | link:#project-watches[project watches]. In addition there is an |
| 19 | `authorized_keys` file for the link:#ssh-keys[SSH keys] that follows |
| 20 | the standard OpenSSH file format. |
| 21 | |
| 22 | The account data in the user branch is versioned and the Git history of |
| 23 | this branch serves as an audit log. |
| 24 | |
| 25 | The link:#external-ids[external IDs] are stored as Git Notes inside the |
| 26 | `All-Users` repository in the `refs/meta/external-ids` notes branch. |
| 27 | Storing all external IDs in a notes branch ensures that each external |
| 28 | ID is only used once. |
| 29 | |
| 30 | The link:#starred-changes[starred changes] are represented as |
| 31 | independent refs in the `All-Users` repository. They are not stored in |
| 32 | the user branch, since this data doesn't need versioning. |
| 33 | |
| 34 | The link:#reviewed-flags[reviewed flags] are not stored in Git, but are |
| 35 | persisted in a database table. This is because there is a high volume |
| 36 | of reviewed flags and storing them in Git would be inefficient. |
| 37 | |
| 38 | Since accessing the account data in Git is not fast enough for account |
| 39 | queries, e.g. when suggesting reviewers, Gerrit has a |
| 40 | link:#account-index[secondary index for accounts]. |
| 41 | |
| 42 | [[all-users]] |
| 43 | == `All-Users` repository |
| 44 | |
| 45 | The `All-Users` repository is a special repository that only contains |
| 46 | user-specific information. It contains one branch per user. The user |
| 47 | branch is formatted as `refs/users/CD/ABCD`, where `CD/ABCD` is the |
| 48 | link:access-control.html#sharded-user-id[sharded account ID], e.g. the |
| 49 | user branch for account `1000856` is `refs/users/56/1000856`. The |
| 50 | account IDs in the user refs are sharded so that there is a good |
| 51 | distribution of the Git data in the storage system. |
| 52 | |
| 53 | A user branch must exist for each account, as it represents the |
| 54 | account. The files in the user branch are all optional. This means |
| 55 | having a user branch with a tree that is completely empty is also a |
| 56 | valid account definition. |
| 57 | |
| 58 | Updates to the user branch are done through the |
| 59 | link:rest-api-accounts.html[Gerrit REST API], but users can also |
| 60 | manually fetch their user branch and push changes back to Gerrit. On |
| 61 | push the user data is evaluated and invalid user data is rejected. |
| 62 | |
| 63 | To hide the implementation detail of the sharded account ID in the ref |
| 64 | name Gerrit offers a magic `refs/users/self` ref that is automatically |
| 65 | resolved to the user branch of the calling user. The user can then use |
| 66 | this ref to fetch from and push to the own user branch. E.g. if user |
| 67 | `1000856` pushes to `refs/users/self`, the branch |
| 68 | `refs/users/56/1000856` is updated. In Gerrit `self` is an established |
| 69 | term to refer to the calling user (e.g. in change queries). This is why |
| 70 | the magic ref for the own user branch is called `refs/users/self`. |
| 71 | |
| 72 | A user branch should only be readable and writeable by the user to whom |
| 73 | the account belongs. To assign permissions on the user branches the |
| 74 | normal branch permission system is used. In the permission system the |
| 75 | user branches are specified as `refs/users/${shardeduserid}`. The |
| 76 | `${shardeduserid}` variable is resolved to the sharded account ID. This |
| 77 | variable is used to assign default access rights on all user branches |
| 78 | that apply only to the owning user. The following permissions are set |
| 79 | by default when a Gerrit site is newly installed or upgraded to a |
| 80 | version which supports user branches: |
| 81 | |
| 82 | .All-Users project.config |
| 83 | ---- |
| 84 | [access "refs/users/${shardeduserid}"] |
| 85 | exclusiveGroupPermissions = read push submit |
| 86 | read = group Registered Users |
| 87 | push = group Registered Users |
| 88 | label-Code-Review = -2..+2 group Registered Users |
| 89 | submit = group Registered Users |
| 90 | ---- |
| 91 | |
| 92 | The user branch contains several files with account data which are |
| 93 | described link:#account-data-in-user-branch[below]. |
| 94 | |
| 95 | In addition to the user branches the `All-Users` repository also |
| 96 | contains a branch for the link:#external-ids[external IDs] and special |
| 97 | refs for the link:#starred-changes[starred changes]. |
| 98 | |
| 99 | Also the next available value of the link:#account-sequence[account |
| 100 | sequence] is stored in the `All-Users` repository. |
| 101 | |
| 102 | [[account-index]] |
| 103 | == Account Index |
| 104 | |
| 105 | There are several situations in which Gerrit needs to query accounts, |
| 106 | e.g.: |
| 107 | |
| 108 | * For sending email notifications to project watchers. |
| 109 | * For reviewer suggestions. |
| 110 | |
| 111 | Accessing the account data in Git is not fast enough for account |
| 112 | queries, since it requires accessing all user branches and parsing |
| 113 | all files in each of them. To overcome this Gerrit has a secondary |
| 114 | index for accounts. The account index is either based on |
| 115 | link:config-gerrit.html#index.type[Lucene or Elasticsearch]. |
| 116 | |
| 117 | Via the link:rest-api-accounts.html#query-account[Query Account] REST |
| 118 | endpoint link:user-search-accounts.html[generic account queries] are |
| 119 | supported. |
| 120 | |
| 121 | Accounts are automatically reindexed on any update. The |
| 122 | link:rest-api-accounts.html#index-account[Index Account] REST endpoint |
| 123 | allows to reindex an account manually. In addition the |
| 124 | link:pgm-reindex.html[reindex] program can be used to reindex all |
| 125 | accounts offline. |
| 126 | |
| 127 | [[account-data-in-user-branch]] |
| 128 | == Account Data in User Branch |
| 129 | |
| 130 | A user branch contains several Git config files with the account data: |
| 131 | |
| 132 | * `account.config`: |
| 133 | + |
| 134 | Stores the link:#account-properties[account properties]. |
| 135 | |
| 136 | * `preferences.config`: |
| 137 | + |
| 138 | Stores the link:#preferences[user preferences] of the account. |
| 139 | |
| 140 | * `watch.config`: |
| 141 | + |
| 142 | Stores the link:#project-watches[project watches] of the account. |
| 143 | |
| 144 | In addition it contains an |
| 145 | link:https://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fauthorized_keys[ |
Marian Harbach | 3425337 | 2019-12-10 18:01:31 +0100 | [diff] [blame] | 146 | authorized_keys,role=external,window=_blank] file with the link:#ssh-keys[SSH keys] of the account. |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 147 | |
| 148 | [[account-properties]] |
| 149 | === Account Properties |
| 150 | |
| 151 | The account properties are stored in the user branch in the |
| 152 | `account.config` file: |
| 153 | |
| 154 | ---- |
| 155 | [account] |
| 156 | fullName = John Doe |
Ben Rohlfs | 9c960cb | 2020-02-02 22:12:30 +0100 | [diff] [blame] | 157 | displayName = John |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 158 | preferredEmail = john.doe@example.com |
| 159 | status = OOO |
| 160 | active = false |
| 161 | ---- |
| 162 | |
| 163 | For active accounts the `active` parameter can be omitted. |
| 164 | |
| 165 | The registration date is not contained in the `account.config` file but |
| 166 | is derived from the timestamp of the first commit on the user branch. |
| 167 | |
| 168 | When users update their account properties by pushing to the user |
| 169 | branch, it is verified that the preferred email exists in the external |
| 170 | IDs. |
| 171 | |
| 172 | Users are not allowed to flip the active value themselves; only |
| 173 | administrators and users with the |
| 174 | link:access-control.html#capability_modifyAccount[Modify Account] |
| 175 | global capability are allowed to change it. |
| 176 | |
| 177 | Since all data in the `account.config` file is optional the |
| 178 | `account.config` file may be absent from some user branches. |
| 179 | |
| 180 | [[preferences]] |
| 181 | === Preferences |
| 182 | |
| 183 | The account properties are stored in the user branch in the |
| 184 | `preferences.config` file. There are separate sections for |
| 185 | link:intro-user.html#preferences[general], |
| 186 | link:user-review-ui.html#diff-preferences[diff] and edit preferences: |
| 187 | |
| 188 | ---- |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 189 | [diff] |
| 190 | hideTopMenu = true |
| 191 | [edit] |
| 192 | lineLength = 80 |
| 193 | ---- |
| 194 | |
| 195 | The parameter names match the names that are used in the preferences REST API: |
| 196 | |
| 197 | * link:rest-api-accounts.html#preferences-info[General Preferences] |
| 198 | * link:rest-api-accounts.html#diff-preferences-info[Diff Preferences] |
| 199 | * link:rest-api-accounts.html#edit-preferences-info[Edit Preferences] |
| 200 | |
| 201 | If the value for a preference is the same as the default value for this |
David Pursehouse | 6d2ae28 | 2019-01-09 11:00:27 +0900 | [diff] [blame] | 202 | preference, it can be omitted in the `preferences.config` file. |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 203 | |
Edwin Kempin | 1e01692e | 2018-01-17 11:01:00 +0100 | [diff] [blame] | 204 | Defaults for preferences that apply for all accounts can be configured |
| 205 | in the `refs/users/default` branch in the `All-Users` repository. |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 206 | |
| 207 | [[project-watches]] |
| 208 | === Project Watches |
| 209 | |
| 210 | Users can configure watches on projects to receive email notifications |
| 211 | for changes of that project. |
| 212 | |
| 213 | A watch configuration consists of the project name and an optional |
| 214 | filter query. If a filter query is specified, email notifications will |
| 215 | be sent only for changes of that project that match this query. |
| 216 | |
| 217 | In addition, each watch configuration can contain a list of |
| 218 | notification types that determine for which events email notifications |
| 219 | should be sent. E.g. a user can configure that email notifications |
| 220 | should only be sent if a new patch set is uploaded and when the change |
| 221 | gets submitted, but not on other events. |
| 222 | |
| 223 | Project watches are stored in a `watch.config` file in the user branch: |
| 224 | |
| 225 | ---- |
| 226 | [project "foo"] |
| 227 | notify = * [ALL_COMMENTS] |
| 228 | notify = branch:master [ALL_COMMENTS, NEW_PATCHSETS] |
| 229 | notify = branch:master owner:self [SUBMITTED_CHANGES] |
| 230 | ---- |
| 231 | |
| 232 | The `watch.config` file has one project section for all project watches |
| 233 | of a project. The project name is used as subsection name and the |
| 234 | filters with the notification types, that decide for which events email |
| 235 | notifications should be sent, are represented as `notify` values in the |
| 236 | subsection. A `notify` value is formatted as |
| 237 | "<filter> [<comma-separated-list-of-notification-types>]". The |
| 238 | supported notification types are described in the |
| 239 | link:user-notify.html#notify.name.type[Email Notifications documentation]. |
| 240 | |
| 241 | For a change event, a notification will be sent if any `notify` value |
| 242 | of the corresponding project has both a filter that matches the change |
| 243 | and a notification type that matches the event. |
| 244 | |
| 245 | In order to send email notifications on change events, Gerrit needs to |
| 246 | find all accounts that watch the corresponding project. To make this |
| 247 | lookup fast the secondary account index is used. The account index |
| 248 | contains a repeated field that stores the projects that are being |
| 249 | watched by an account. After the accounts that watch the project have |
| 250 | been retrieved from the index, the complete watch configuration is |
| 251 | available from the account cache and Gerrit can check if any watch |
| 252 | matches the change and the event. |
| 253 | |
| 254 | [[ssh-keys]] |
| 255 | === SSH Keys |
| 256 | |
| 257 | SSH keys are stored in the user branch in an `authorized_keys` file, |
| 258 | which is the |
| 259 | link:https://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#.7E.2F.ssh.2Fauthorized_keys[ |
Marian Harbach | 3425337 | 2019-12-10 18:01:31 +0100 | [diff] [blame] | 260 | standard OpenSSH file format,role=external,window=_blank] for storing SSH keys: |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 261 | |
| 262 | ---- |
| 263 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCgug5VyMXQGnem2H1KVC4/HcRcD4zzBqSuJBRWVonSSoz3RoAZ7bWXCVVGwchtXwUURD689wFYdiPecOrWOUgeeyRq754YWRhU+W28vf8IZixgjCmiBhaL2gt3wff6pP+NXJpTSA4aeWE5DfNK5tZlxlSxqkKOS8JRSUeNQov5Tw== john.doe@example.com |
| 264 | # DELETED |
| 265 | # INVALID ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDm5yP7FmEoqzQRDyskX+9+N0q9GrvZeh5RG52EUpE4ms/Ujm3ewV1LoGzc/lYKJAIbdcZQNJ9+06EfWZaIRA3oOwAPe1eCnX+aLr8E6Tw2gDMQOGc5e9HfyXpC2pDvzauoZNYqLALOG3y/1xjo7IH8GYRS2B7zO/Mf9DdCcCKSfw== john.doe@example.com |
| 266 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCaS7RHEcZ/zjl9hkWkqnm29RNr2OQ/TZ5jk2qBVMH3BgzPsTsEs+7ag9tfD8OCj+vOcwm626mQBZoR2e3niHa/9gnHBHFtOrGfzKbpRjTWtiOZbB9HF+rqMVD+Dawo/oicX/dDg7VAgOFSPothe6RMhbgWf84UcK5aQd5eP5y+tQ== john.doe@example.com |
| 267 | ---- |
| 268 | |
| 269 | When the SSH API is used, Gerrit needs an efficient way to lookup SSH |
| 270 | keys by username. Since the username can be easily resolved to an |
| 271 | account ID (via the account cache), accessing the SSH keys in the user |
| 272 | branch is fast. |
| 273 | |
| 274 | To identify SSH keys in the REST API Gerrit uses |
| 275 | link:rest-api-accounts.html#ssh-key-id[sequence numbers per account]. |
| 276 | This is why the order of the keys in the `authorized_keys` file is |
David Pursehouse | 0da65cf | 2019-05-27 16:25:27 +0900 | [diff] [blame] | 277 | used to determine the sequence numbers of the keys (the sequence |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 278 | numbers start at 1). |
| 279 | |
| 280 | To keep the sequence numbers intact when a key is deleted, a |
| 281 | '# DELETED' line is inserted at the position where the key was deleted. |
| 282 | |
| 283 | Invalid keys are marked with the prefix '# INVALID'. |
| 284 | |
| 285 | [[external-ids]] |
| 286 | == External IDs |
| 287 | |
David Pursehouse | f7f400c | 2019-05-27 20:22:08 +0900 | [diff] [blame] | 288 | External IDs are used to link identities, such as the username and email |
| 289 | addresses, and external identies such as an LDAP account or an OAUTH |
| 290 | identity, to an account in Gerrit. |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 291 | |
| 292 | External IDs are stored as Git Notes in the `All-Users` repository. The |
| 293 | name of the notes branch is `refs/meta/external-ids`. |
| 294 | |
Han-Wen Nienhuys | 37a1cab | 2021-04-01 12:46:00 +0200 | [diff] [blame] | 295 | As note key the SHA-1 of the external ID key is used, for example the key |
David Pursehouse | 05c4cba | 2019-05-27 16:25:58 +0900 | [diff] [blame] | 296 | for the external ID `username:jdoe` is `e0b751ae90ef039f320e097d7d212f490e933706`. |
| 297 | This ensures that an external ID is used only once (e.g. an external ID can |
| 298 | never be assigned to multiple accounts at a point in time). |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 299 | |
Thomas Draebing | 29595cd | 2021-03-24 15:23:35 +0100 | [diff] [blame] | 300 | By default, the SHA-1 sum is computed preserving the case of the external ID. If |
| 301 | auth.userNameCaseInsensitive` is set to `true`, the SHA-1 sum of external IDs |
| 302 | in the `gerrit:` and `username:` schemes are computed from the all lowercase |
| 303 | external ID. This enables case insensitive username handling. The case of the |
| 304 | external ID is however preserved by using the original capitalization in the |
| 305 | note content. |
| 306 | |
Han-Wen Nienhuys | 37a1cab | 2021-04-01 12:46:00 +0200 | [diff] [blame] | 307 | The following commands show how to find the SHA-1 of an external ID: |
Saša Živkov | 7bc2542 | 2019-12-13 12:20:44 +0100 | [diff] [blame] | 308 | |
| 309 | ---- |
| 310 | $ echo -n 'gerrit:jdoe' | shasum |
| 311 | 7c2a55657d911109dbc930836e7a770fb946e8ef - |
| 312 | |
| 313 | $ echo -n 'username:jdoe' | shasum |
| 314 | e0b751ae90ef039f320e097d7d212f490e933706 - |
| 315 | ---- |
| 316 | |
Edwin Kempin | 7ff264d | 2018-09-20 09:48:03 +0200 | [diff] [blame] | 317 | [IMPORTANT] |
| 318 | If the external ID key is changed manually you must adapt the note key |
Han-Wen Nienhuys | 37a1cab | 2021-04-01 12:46:00 +0200 | [diff] [blame] | 319 | to the new SHA-1, otherwise the external ID becomes inconsistent and is |
Edwin Kempin | 7ff264d | 2018-09-20 09:48:03 +0200 | [diff] [blame] | 320 | ignored by Gerrit. |
| 321 | |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 322 | The note content is a Git config file: |
| 323 | |
| 324 | ---- |
| 325 | [externalId "username:jdoe"] |
| 326 | accountId = 1003407 |
| 327 | email = jdoe@example.com |
| 328 | password = bcrypt:4:LCbmSBDivK/hhGVQMfkDpA==:XcWn0pKYSVU/UJgOvhidkEtmqCp6oKB7 |
| 329 | ---- |
| 330 | |
Han-Wen Nienhuys | 37a1cab | 2021-04-01 12:46:00 +0200 | [diff] [blame] | 331 | Once SHA-1 of an external ID is known the following command can be used to |
Saša Živkov | 3c6b3c8 | 2019-12-13 12:27:42 +0100 | [diff] [blame] | 332 | show the content of the note: |
| 333 | |
| 334 | ---- |
| 335 | $ echo -n 'gerrit:jdoe' | shasum |
| 336 | 7c2a55657d911109dbc930836e7a770fb946e8ef - |
| 337 | |
| 338 | $ git show refs/meta/external-ids:7c/2a55657d911109dbc930836e7a770fb946e8ef |
| 339 | [externalId "username:jdoe"] |
| 340 | accountId = 1003407 |
| 341 | email = jdoe@example.com |
| 342 | password = bcrypt:4:LCbmSBDivK/hhGVQMfkDpA==:XcWn0pKYSVU/UJgOvhidkEtmqCp6oKB7 |
| 343 | ---- |
| 344 | |
David Pursehouse | 0da65cf | 2019-05-27 16:25:27 +0900 | [diff] [blame] | 345 | The config file has one `externalId` section. The external ID key, which |
| 346 | consists of scheme and ID in the format '<scheme>:<id>', is used as |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 347 | subsection name. |
| 348 | |
David Pursehouse | 0da65cf | 2019-05-27 16:25:27 +0900 | [diff] [blame] | 349 | The `accountId` field is mandatory. The `email` and `password` fields |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 350 | are optional. |
| 351 | |
Clark Boylan | a888eec | 2020-11-23 13:10:41 -0800 | [diff] [blame] | 352 | Note that git will automatically nest these notes at varying levels. If |
| 353 | refs/meta/external-ids:7c/2a55657d911109dbc930836e7a770fb946e8ef is not |
| 354 | found then check |
| 355 | refs/meta/external-ids:7c/2a/55657d911109dbc930836e7a770fb946e8ef and |
| 356 | so on. |
| 357 | |
David Pursehouse | 0da65cf | 2019-05-27 16:25:27 +0900 | [diff] [blame] | 358 | The external IDs are maintained by Gerrit. This means users are not |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 359 | allowed to manually edit their external IDs. Only users with the |
Edwin Kempin | 47dd7ba | 2017-08-31 11:33:44 +0200 | [diff] [blame] | 360 | link:access-control.html#capability_accessDatabase[Access Database] |
| 361 | global capability can push updates to the `refs/meta/external-ids` |
| 362 | branch. However Gerrit rejects pushes if: |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 363 | |
| 364 | * any external ID config file cannot be parsed |
| 365 | * if a note key does not match the SHA of the external ID key in the |
| 366 | note content |
| 367 | * external IDs for non-existing accounts are contained |
| 368 | * invalid emails are contained |
| 369 | * any email is not unique (the same email is assigned to multiple |
| 370 | accounts) |
| 371 | * hashed passwords of external IDs with scheme `username` cannot be |
| 372 | decoded |
| 373 | |
Clark Boylan | f53508e | 2021-07-14 08:57:38 -0700 | [diff] [blame] | 374 | Users can edit some external IDs via the user settings page or the |
| 375 | REST API. Note that email addresses cannot be deleted if they are |
| 376 | associated with the user's login credentials external ID, for |
| 377 | example the email address associated with an OpenId or OAUTH external |
| 378 | ID. If users wish to remove these email addresses from Gerrit they must |
| 379 | first update the external authentication record in that system, |
| 380 | log in to Gerrit, then Gerrit will update the external ID record with |
| 381 | the new email address. |
| 382 | |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 383 | [[starred-changes]] |
| 384 | == Starred Changes |
| 385 | |
| 386 | link:dev-stars.html[Starred changes] allow users to mark changes as |
| 387 | favorites and receive email notifications for them. |
| 388 | |
| 389 | Each starred change is a tuple of an account ID, a change ID and a |
| 390 | label. |
| 391 | |
| 392 | To keep track of a change that is starred by an account, Gerrit creates |
| 393 | a `refs/starred-changes/YY/XXXX/ZZZZZZZ` ref in the `All-Users` |
| 394 | repository, where `YY/XXXX` is the sharded numeric change ID and |
| 395 | `ZZZZZZZ` is the account ID. |
| 396 | |
| 397 | A starred-changes ref points to a blob that contains the list of labels |
| 398 | that the account set on the change. The label list is stored as UTF-8 |
| 399 | text with one label per line. |
| 400 | |
| 401 | Since JGit has explicit optimizations for looking up refs by prefix |
| 402 | when the prefix ends with '/', this ref format is optimized to find |
| 403 | starred changes by change ID. Finding starred changes by change ID is |
| 404 | e.g. needed when a change is updated so that all users that have |
| 405 | the link:dev-stars.html#default-star[default star] on the change can be |
| 406 | notified by email. |
| 407 | |
| 408 | Gerrit also needs an efficient way to find all changes that were |
| 409 | starred by an account, e.g. to provide results for the |
| 410 | link:user-search.html#is-starred[is:starred] query operator. With the |
| 411 | ref format as described above the lookup of starred changes by account |
| 412 | ID is expensive, as this requires a scan of the full |
| 413 | `refs/starred-changes/*` namespace. To overcome this the users that |
| 414 | have starred a change are stored in the change index together with the |
| 415 | star labels. |
| 416 | |
| 417 | [[reviewed-flags]] |
| 418 | == Reviewed Flags |
| 419 | |
| 420 | When reviewing a patch set in the Gerrit UI, the reviewer can mark |
| 421 | files in the patch set as reviewed. These markers are called ‘Reviewed |
| 422 | Flags’ and are private to the user. A reviewed flag is a tuple of patch |
| 423 | set ID, file and account ID. |
| 424 | |
| 425 | Each user can have many thousands of reviewed flags and over time the |
| 426 | number can grow without bounds. |
| 427 | |
| 428 | The high amount of reviewed flags makes a storage in Git unsuitable |
| 429 | because each update requires opening the repository and committing a |
| 430 | change, which is a high overhead for flipping a bit. Therefore the |
| 431 | reviewed flags are stored in a database table. By default they are |
| 432 | stored in a local H2 database, but there is an extension point that |
| 433 | allows to plug in alternate implementations for storing the reviewed |
| 434 | flags. To replace the storage for reviewed flags a plugin needs to |
| 435 | implement the link:dev-plugins.html#account-patch-review-store[ |
Matthias Sohn | d8182ba | 2019-12-09 14:50:23 +0100 | [diff] [blame] | 436 | AccountPatchReviewStore] interface. E.g. to support a cluster setup with |
| 437 | multiple primary servers handling write operations where reviewed flags should |
| 438 | be replicated between the primary nodes one could implement a store for the |
| 439 | reviewed flags that is based on MySQL with replication. |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 440 | |
| 441 | [[account-sequence]] |
| 442 | == Account Sequence |
| 443 | |
| 444 | The next available account sequence number is stored as UTF-8 text in a |
| 445 | blob pointed to by the `refs/sequences/accounts` ref in the `All-Users` |
| 446 | repository. |
| 447 | |
| 448 | Multiple processes share the same sequence by incrementing the counter |
| 449 | using normal git ref updates. To amortize the cost of these ref |
| 450 | updates, processes increment the counter by a larger number and hand |
| 451 | out numbers from that range in memory until they run out. The size of |
| 452 | the account ID batch that each process retrieves at once is controlled |
| 453 | by the link:config-gerrit.html#notedb.accounts.sequenceBatchSize[ |
| 454 | notedb.accounts.sequenceBatchSize] parameter in the `gerrit.config` |
| 455 | file. |
| 456 | |
Edwin Kempin | d97ec6c | 2017-10-05 14:20:28 +0200 | [diff] [blame] | 457 | [[replication]] |
| 458 | == Replication |
| 459 | |
| 460 | To replicate account data the following branches from the `All-Users` |
| 461 | repository must be replicated: |
| 462 | |
| 463 | * `refs/users/*` (user branches) |
| 464 | * `refs/meta/external-ids` (external IDs) |
| 465 | * `refs/starred-changes/*` (star labels) |
| 466 | * `refs/sequences/accounts` (account sequence numbers, not needed for Gerrit |
Han-Wen Nienhuys | 348a603 | 2019-09-24 19:44:57 +0200 | [diff] [blame] | 467 | replicas) |
Edwin Kempin | d97ec6c | 2017-10-05 14:20:28 +0200 | [diff] [blame] | 468 | |
Edwin Kempin | 311d570 | 2017-07-28 15:10:24 +0200 | [diff] [blame] | 469 | GERRIT |
| 470 | ------ |
| 471 | Part of link:index.html[Gerrit Code Review] |
| 472 | |
| 473 | SEARCHBOX |
| 474 | --------- |