|  | Gerrit Code Review - Uploading Changes | 
|  | ====================================== | 
|  |  | 
|  | Gerrit supports three methods of uploading changes: | 
|  |  | 
|  | * Use `repo upload`, to create changes for review | 
|  | * Use `git push`, to create changes for review | 
|  | * Use `git push`, and bypass code review | 
|  |  | 
|  | All three methods rely on SSH public key authentication, which must | 
|  | first be configured by the uploading user. | 
|  |  | 
|  | SSH | 
|  | --- | 
|  |  | 
|  | Each user uploading changes to Gerrit must configure one or more SSH | 
|  | public keys.  The per-user SSH key list can be accessed over the web | 
|  | within Gerrit by `Settings`, and then accessing the `SSH Keys` tab. | 
|  |  | 
|  | [[configure_ssh]] | 
|  | Configuration | 
|  | ~~~~~~~~~~~~~ | 
|  |  | 
|  | To register a new SSH key for use with Gerrit, paste the contents of | 
|  | your `id_rsa.pub` or `id_dsa.pub` file into the text box and click | 
|  | the add button.  Gerrit only understands SSH version 2 public keys. | 
|  | Keys may be supplied in either the OpenSSH format (key starts with | 
|  | `ssh-rsa` or `ssh-dss`) or the RFC 4716 format (file starts with | 
|  | `---- BEGIN SSH2 PUBLIC KEY ----`). | 
|  |  | 
|  | Typically SSH keys are stored in your home directory, under `~/.ssh`. | 
|  | If you don't have any keys yet, you can create a new one and protect | 
|  | it with a passphrase: | 
|  |  | 
|  | ==== | 
|  | ssh-keygen -t rsa | 
|  | ==== | 
|  |  | 
|  | Then copy the content of the public key file onto your clipboard, | 
|  | and paste it into Gerrit's web interface: | 
|  |  | 
|  | ==== | 
|  | cat ~/.ssh/id_rsa.pub | 
|  | ==== | 
|  |  | 
|  | [TIP] | 
|  | Users who frequently upload changes will also want to consider | 
|  | starting a `ssh-agent`, and adding their private key to the list | 
|  | managed by the agent, to reduce the frequency of entering the | 
|  | key's passphrase.  Consult `man ssh-agent`, or your SSH client's | 
|  | documentation, for more details on configuration of the agent | 
|  | process and how to add the private key. | 
|  |  | 
|  | [[test_ssh]] | 
|  | Testing Connections | 
|  | ~~~~~~~~~~~~~~~~~~~ | 
|  |  | 
|  | To verify your SSH key is working correctly, try using an SSH client | 
|  | to connect to Gerrit's SSHD port.  By default Gerrit is running on | 
|  | port 29418, using the same hostname as the web server: | 
|  |  | 
|  | ==== | 
|  | $ ssh -p 29418 sshusername@hostname | 
|  | gerrit: no shell available | 
|  | Connection to hostname closed. | 
|  | ==== | 
|  |  | 
|  | In the command above, `sshusername` was configured on the `SSH Keys` | 
|  | tab of the `Settings` screen.  If it is not set, propose a name | 
|  | and use `Change Username` to select the name. | 
|  |  | 
|  | To determine the port number Gerrit is running on, visit the special | 
|  | information URL `http://'hostname'/ssh_info`, and copy the port | 
|  | number from the second field: | 
|  |  | 
|  | ==== | 
|  | $ curl http://hostname/ssh_info | 
|  | hostname 29418 | 
|  | ==== | 
|  |  | 
|  | If you are developing an automated tool to perform uploads to Gerrit, | 
|  | let the user supply the hostname or the web address for Gerrit, | 
|  | and obtain the port number on the fly from the `/ssh_info` URL. | 
|  | The returned output from this URL is always `'hostname' SP 'port'`, | 
|  | or `NOT_AVAILABLE` if the SSHD server is not currently running. | 
|  |  | 
|  |  | 
|  | git push | 
|  | -------- | 
|  |  | 
|  | [[push_create]] | 
|  | Create Changes | 
|  | ~~~~~~~~~~~~~~ | 
|  |  | 
|  | To create new changes for review, simply push into the project's | 
|  | magical `refs/for/'branch'` ref using any Git client tool: | 
|  |  | 
|  | ==== | 
|  | git push ssh://sshusername@hostname:29418/projectname HEAD:refs/for/branchname | 
|  | ==== | 
|  |  | 
|  | E.g. `john.doe` can use git push to upload new changes for the | 
|  | `experimental` branch of project `kernel/common`, hosted at the | 
|  | `git.example.com` Gerrit server: | 
|  |  | 
|  | ==== | 
|  | git push ssh://john.doe@git.example.com:29418/kernel/common HEAD:refs/for/experimental | 
|  | ==== | 
|  |  | 
|  | Each new commit uploaded by the `git push` client will be | 
|  | converted into a change record on the server.  The remote ref | 
|  | `refs/for/experimental` is not actually created by Gerrit, even | 
|  | though the client's status messages may say otherwise. | 
|  |  | 
|  | Other users (e.g. project owners) who have configured Gerrit to | 
|  | notify them of new changes will be automatically sent an email | 
|  | message when the push is completed. | 
|  |  | 
|  | To include a short tag associated with all of the changes in the | 
|  | same group, such as the local topic branch name, append it after | 
|  | the destination branch name.  In this example the short topic tag | 
|  | 'driver/i42' will be saved on each change this push creates or | 
|  | updates: | 
|  |  | 
|  | ==== | 
|  | git push ssh://john.doe@git.example.com:29418/kernel/common HEAD:refs/for/experimental/driver/i42 | 
|  | ==== | 
|  |  | 
|  | If you are frequently uploading changes to the same Gerrit server, | 
|  | consider adding an SSH host block in `~/.ssh/config` to remember | 
|  | your username, hostname and port number.  This permits the use of | 
|  | shorter URLs on the command line, such as: | 
|  |  | 
|  | ==== | 
|  | $ cat ~/.ssh/config | 
|  | ... | 
|  | Host tr | 
|  | Hostname git.example.com | 
|  | Port 29418 | 
|  | User john.doe | 
|  |  | 
|  | $ git push tr:kernel/common HEAD:refs/for/experimental | 
|  | ==== | 
|  |  | 
|  | Specific reviewers can be requested and/or additional ``carbon | 
|  | copies'' of the notification message may be sent by including these | 
|  | as arguments to `git receive-pack`: | 
|  |  | 
|  | ==== | 
|  | git push --receive-pack='git receive-pack --reviewer=a@a.com --cc=b@o.com' tr:kernel/common HEAD:refs/for/experimental | 
|  | ==== | 
|  |  | 
|  | The `\--reviewer='email'` and `\--cc='email'` options may be | 
|  | specified as many times as necessary to cover all interested | 
|  | parties.  Gerrit will automatically avoid sending duplicate email | 
|  | notifications, such as if one of the specified reviewers or CC | 
|  | addresses had also requested to receive all new change notifications. | 
|  |  | 
|  | If you are frequently sending changes to the same parties and/or | 
|  | branches, consider adding a custom remote block to your project's | 
|  | `.git/config` file: | 
|  |  | 
|  | ==== | 
|  | $ cat .git/config | 
|  | ... | 
|  | [remote "for-a-exp"] | 
|  | url = tr:kernel/common | 
|  | receivepack = git receive-pack --reviewer=a@a.com --cc=b@o.com | 
|  | push = HEAD:refs/for/experimental | 
|  |  | 
|  | $ git push for-a-exp | 
|  | ==== | 
|  |  | 
|  |  | 
|  | [[push_replace]] | 
|  | Replace Changes | 
|  | ~~~~~~~~~~~~~~~ | 
|  |  | 
|  | To add an additional patch set to a change, ensure Change-Id | 
|  | lines were created in the original commit messages, and just use | 
|  | `git push URL HEAD:refs/for/...` as <<push_create,described above>>. | 
|  | Gerrit Code Review will automatically match the commits back to | 
|  | their original changes by taking advantage of the Change-Id lines. | 
|  |  | 
|  | If Change-Id lines are not present in the commit messages, consider | 
|  | amending the message and copying the line from the change's page | 
|  | on the web, and then using `git push` as described above. | 
|  |  | 
|  | If Change-Id lines are not available, then the user must use the | 
|  | manual mapping technique described below. | 
|  |  | 
|  | For more about Change-Ids, see link:user-changeid.html[Change-Id Lines]. | 
|  |  | 
|  | Manual Replacment Mapping | 
|  | ^^^^^^^^^^^^^^^^^^^^^^^^^ | 
|  |  | 
|  | .Deprecation Warning | 
|  | **** | 
|  | The remainder of this section describes a manual method of replacing | 
|  | changes by matching each commit name to an existing change number. | 
|  | End-users should instead prefer to use Change-Id lines in their | 
|  | commit messages, as the process is then fully automated by Gerrit | 
|  | during normal uploads. | 
|  |  | 
|  | See above for the preferred technique of replacing changes. | 
|  | **** | 
|  |  | 
|  | To add an additional patch set to a change, replacing it with an | 
|  | updated version of the same logical modification, send the new | 
|  | commit to the change's ref.  For example, to add the commit whose | 
|  | SHA-1 starts with `c0ffee` as a new patch set for change number | 
|  | `1979`, use the push refspec `c0ffee:refs/changes/1979` as below: | 
|  |  | 
|  | ==== | 
|  | git push ssh://sshusername@hostname:29418/projectname c0ffee:refs/changes/1979 | 
|  | ==== | 
|  |  | 
|  | This form can be combined together with `refs/for/'branchname'` | 
|  | (above) to simultaneously create new changes and replace changes | 
|  | during one network transaction. | 
|  |  | 
|  | For example, consider the following sequence of events: | 
|  |  | 
|  | ==== | 
|  | $ git commit -m A                    ; # create 3 commits | 
|  | $ git commit -m B | 
|  | $ git commit -m C | 
|  |  | 
|  | $ git push ... HEAD:refs/for/master  ; # upload for review | 
|  | ... A is 1500 ... | 
|  | ... B is 1501 ... | 
|  | ... C is 1502 ... | 
|  |  | 
|  | $ git rebase -i HEAD~3               ; # edit "A", insert D before B | 
|  | ; # now series is A'-D-B'-C' | 
|  | $ git push ... | 
|  | HEAD:refs/for/master | 
|  | HEAD~3:refs/changes/1500 | 
|  | HEAD~1:refs/changes/1501 | 
|  | HEAD~0:refs/changes/1502         ; # upload replacements | 
|  | ==== | 
|  |  | 
|  | At the final step during the push Gerrit will attach A' as a new | 
|  | patch set on change 1500; B' as a new patch set on change 1501; C' | 
|  | as a new patch set on 1502; and D will be created as a new change. | 
|  |  | 
|  | Ensuring D is created as a new change requires passing the refspec | 
|  | `HEAD:refs/for/branchname`, otherwise Gerrit will ignore D and | 
|  | won't do anything with it.  For this reason it is a good idea to | 
|  | always include the create change refspec when uploading replacements. | 
|  |  | 
|  |  | 
|  | Bypass Review | 
|  | ~~~~~~~~~~~~~ | 
|  |  | 
|  | Changes (and annotated tags) can be pushed directly into a | 
|  | repository, bypassing the review process.  This is primarily useful | 
|  | for a project owner to create new branches, create annotated tags | 
|  | for releases, or to force-update a branch whose history needed to | 
|  | be rewritten. | 
|  |  | 
|  | Gerrit restricts direct pushes that bypass review to: | 
|  |  | 
|  | * `refs/heads/*`: any branch can be updated, created, deleted, | 
|  | or rewritten by the pusher. | 
|  | * `refs/tags/*`: annotated tag objects pointing to any other type | 
|  | of Git object can be created. | 
|  |  | 
|  | To push branches, the `Push Branch` project right must be granted | 
|  | to one (or more) of the user's groups.  The allowed levels within | 
|  | this category are: | 
|  |  | 
|  | * Update: Any existing branch can be fast-forwarded to a new commit. | 
|  | This is the safest mode as commits cannot be discarded.  Creation | 
|  | of new branches is rejected. | 
|  | * Create: Implies Update, but also allows creation of a new branch | 
|  | if the name does not not already designate an existing branch name. | 
|  | * Delete: Implies Create and Update, but also allows an existing | 
|  | branch to be deleted.  Since a force push is effectively a delete | 
|  | followed by a create, but performed atomically on the server and | 
|  | logged, this also permits forced push updates to branches. | 
|  |  | 
|  | To push annotated tags, the `Push Annotated Tag` project right must | 
|  | be granted to one (or more) of the user's groups.  There is only | 
|  | one level of access in this category. | 
|  |  | 
|  | Project owners may wish to grant themselves `Push Annotated Tag` | 
|  | only at times when a new release is being prepared, and otherwise | 
|  | grant nothing at all.  This ensures that accidental pushes don't | 
|  | make undesired changes to the public repository. | 
|  |  | 
|  |  | 
|  | repo upload | 
|  | ----------- | 
|  |  | 
|  | repo is a multiple repository management tool, most commonly | 
|  | used by the Android Open Source Project.  For more details, see | 
|  | link:http://source.android.com/download/using-repo[using repo]. | 
|  |  | 
|  | [[repo_create]] | 
|  | Create Changes | 
|  | ~~~~~~~~~~~~~~ | 
|  |  | 
|  | To upload changes to a project using `repo`, ensure the manifest's | 
|  | review field has been configured to point to the Gerrit server. | 
|  | Only the hostname or the web address needs to be given in the | 
|  | manifest file. During upload `repo` will automatically determine the | 
|  | correct port number by reading `http://'reviewhostname'/ssh_info` | 
|  | when its invoked. | 
|  |  | 
|  | Each new commit uploaded by `repo upload` will be converted into | 
|  | a change record on the server.  Other users (e.g. project owners) | 
|  | who have configured Gerrit to notify them of new changes will be | 
|  | automatically sent an email message.  Additional notifications can | 
|  | be sent through command line options. | 
|  |  | 
|  | For more details on using `repo upload`, see `repo help upload`. | 
|  |  | 
|  | [[repo_replace]] | 
|  | Replace Changes | 
|  | ~~~~~~~~~~~~~~~ | 
|  |  | 
|  | To replace changes, ensure Change-Id lines were created in the | 
|  | commit messages, and just use `repo upload` without the `\--replace` | 
|  | command line flag.  Gerrit Code Review will automatically match | 
|  | the commits back to their original changes by taking advantage of | 
|  | their Change-Id lines. | 
|  |  | 
|  | If Change-Id lines are not present in the commit messages, consider | 
|  | amending the message and copying the line from the change's page | 
|  | on the web. | 
|  |  | 
|  | If Change-Id lines are not available, then the user must use the much | 
|  | more manual mapping technique offered by `repo upload \--replace`. | 
|  |  | 
|  | For more about Change-Ids, see link:user-changeid.html[Change-Id Lines]. | 
|  |  | 
|  |  | 
|  | Gritty Details | 
|  | -------------- | 
|  |  | 
|  | As Gerrit implements the entire SSH and Git server stack within its | 
|  | own process space, Gerrit maintains complete control over how the | 
|  | repository is updated, and what responses are sent to the `git push` | 
|  | client invoked by the end-user, or by `repo upload`.  This allows | 
|  | Gerrit to provide magical refs, such as `refs/for/\*` for new | 
|  | change submission and `refs/changes/\*` for change replacement. | 
|  | When a push request is received to create a ref in one of these | 
|  | namespaces Gerrit performs its own logic to update the database, | 
|  | and then lies to the client about the result of the operation. | 
|  | A successful result causes the client to believe that Gerrit has | 
|  | created the ref, but in reality Gerrit hasn't created the ref at all. | 
|  |  | 
|  | By implementing the entire server stack, Gerrit is also able to | 
|  | perform project level access control checks (to verify the end-user | 
|  | is permitted to access a project) prior to advertising the available | 
|  | refs, and potentially leaking information to a snooping client. | 
|  | Clients cannot tell the difference between 'project not found' and | 
|  | 'project exists, but access is denied'. | 
|  |  | 
|  | Gerrit can also ensure users have completed a valid Contributor | 
|  | Agreement prior to accepting any transferred objects, and if an | 
|  | agreement is required, but not completed, it aborts the network | 
|  | connection before data is sent.  This ensures that project owners | 
|  | can be certain any object available in their repository has been | 
|  | supplied under at least one valid agreement. | 
|  |  | 
|  | GERRIT | 
|  | ------ | 
|  | Part of link:index.html[Gerrit Code Review] |