This tutorial explains how to install Git and use it to create and modify change requests in Gerrit.
- For reference documentation on specific tasks, check Gerrit/Advanced usage instead.
- If you want to practise how to use Gerrit without write a patch to a "real" Wikimedia software project, use our Gerrit test instance instead.
In this tutorial, commands to enter start with a dollar sign in a box, like this: command
.
Do not enter the $
prefix.
If a command also includes a variable which you must change yourself, then the variable is shown in red: command variable
.
What is Git?
Git is a free and open source distributed version control system. “Distributed” means that there is no central copy of the repository. With Git, once you’ve cloned the repository, you have a fully functioning copy of the source code, with all the branches and tagged releases at your disposal.
Create a Wikimedia developer account
If you do not have a Wikimedia developer account yet, create an account. The same username and password will be used to log into Gerrit below.
Set up Git
These instructions explain how to install Git as a command-line (terminal window) tool. If you prefer a graphical user interface (GUI) instead of the command line, then check the list of clients maintained by the Git project. For alternate installation instructions see the official documentation.
Installation
Follow Installing Git to learn how to install git on your operating system.
Configure Git
git config -l
.Now that you have Git installed, it’s time to configure your personal information. You should have to do this only once. You can also change your personal information at any time by running these commands again.
Git tracks who makes each commit by checking the user’s name and email. In addition, this info is used to associate your commits with your Gerrit account.
Enter the two commands below to set your username and email address. Replace Gerrituser with your Wikimedia Developer account username (this was previously known as "Wikitech", "Gerrit", or "LDAP" username, these are all the same thing). Replace gerrituser@example.com with your own email address. And, replace shell_user with the shell username (chosen when you created the Wikimedia Developer account):
git config --global user.email "gerrituser@example.com"
git config --global user.name "Gerrituser"
git config --global url."ssh://shell_user@gerrit.wikimedia.org:29418/".insteadOf "https://gerrit.wikimedia.org/r/"
Set Up SSH Keys in Gerrit
We use an SSH key to establish a secure connection between your computer and Gerrit.
The Wikimedia Security Team recommends, as of August 2021, that users creating SSH Keys use the ed25519
type for optimum security and performance.
Get your SSH key
Follow SSH keys#Generating a new SSH key.
Add SSH Public key to your Gerrit account
- Log into the web interface for Gerrit. The username and password for your Gerrit are the same as for your Wikimedia Developer account.
- Click on your username in the top right corner, then choose "Settings".
- Click "SSH Keys" in the menu on the left.
- Paste your SSH Public Key into the corresponding field and click "ADD NEW SSH KEY".
Test Gerrit SSH connection
Connect to the Gerrit server via ssh
to check if everything works as expected.
Replace shell_user by your shell username as shown in your Gerrit settings:
ssh -p 29418 shell_user@gerrit.wikimedia.org
- Be mindful and compare that the "ed25519 key fingerprint" is the same as the SSH fingerprint for gerrit.wikimedia.org:29418. If it is the same, answer "Yes" to "Are you sure you want to continue connecting?". Then enter the passphrase for your key.
- You should get a message "Welcome to Gerrit Code Review". The last line should show "Connection to gerrit.wikimedia.org closed."
- If you run into problems, use
ssh -p 29418 -v shell_user@gerrit.wikimedia.org
(replace shell_user by your shell username). The-v
will provide verbose output to help find problems. Then read Gerrit Troubleshooting.
An example Gerrit SSH connection success message looks like this:
gerrituser@machine:/mw/sandbox$ ssh -p 29418 gerrituser@gerrit.wikimedia.org The authenticity of host '[gerrit.wikimedia.org]:29418 ([208.80.154.85]:29418)' can't be established. ed25519 key fingerprint is dc:e9:68:7b:99:1b:27:d0:f9:fd:ce:6a:2e:bf:92:e1. Are you sure you want to continue connecting (yes/no)? yes Warning permanently added '[gerrit.wikimedia.org]:29418 ([208.80.154.85]:29418)' (ed25519) to the list of known hosts. Enter passphrase for key '/home/gerrituser/.ssh/id_ed25519': **** Welcome to Gerrit Code Review **** Hi gerrituser, you have successfully connected over SSH. Unfortunately, interactive shells are disabled. To clone a hosted Git repository, use: git clone ssh://gerrit.wikimedia.org:29418/REPOSITORY_NAME.git Connection to gerrit.wikimedia.org closed. gerrituser@machine:/mw/sandbox$
Download code using Git
Sandbox
If you would like to practise using Gerrit you can download (also called "cloning") the repository this tutorial uses called "sandbox".
Run the following on the Git Bash command line:
git clone https://gerrit.wikimedia.org/r/sandbox
This will copy the entire history and the code base of the "sandbox" extension repository into your machine.
You will have a working directory of the extension's main branch (usually also called "git master").
Enter the new directory (via the command cd sandbox
).
Now you can look at the code and start editing it.
Existing repositories
Cloning the Sandbox repository will not give you a development environment setup or a running MediaWiki installation. (Running will require MediaWiki Core and placing the code you checked out in a location expected by your web server.) See Download from Git for how to download MediaWiki Core, extensions, skins, or any other project repository hosted at gerrit.wikimedia.org from Git.
Vagrant
If you have downloaded MediaWiki or extensions using Vagrant, make sure you have configured Git to push code using SSH instead of HTTPS.
Prepare to work with Gerrit
Gerrit requires that your commit message must have a "change ID".
They look like Change-Id: Ibd3be19ed1a23c8638144b4a1d32f544ca1b5f97
starting with an I (capital i).
Each time you amend a commit to improve an existing patch in Gerrit, this change ID stays the same, so Gerrit understands it as a new "patch set" to address the same code change.
There's a git add-on called git-review that adds a Change-Id
line to your commits.
Using git-review is recommended.
It makes it easier to configure your Git clone, to submit a change or to fetch an existing one.
Installing git-review
Note that Wikimedia Gerrit requires git-review version 1.27 or later.
For more details, please see Gerrit/git-review#Installation.
- Use the graphical software package management tool of your Linux distribution to install the
git-review
package. - If git-review has not been packaged by your distribution, check git-review for other options such as installing git-review by using the pip Python package installer.
- If you use FreeBSD, install git-review through ports.
- Please see git-review Windows.
- For OS X 10.11 El Capitan and later, follow Method 1.
- On versions prior to 10.11, use the pip Python package installer by following Method 2.
Configuring git-review
Git's default remote host name is "origin". This name is also used by Wikimedia projects. We need to tell git-review to use that host. Replace gerrituser with your Gerrit username:
git config --global gitreview.remote origin
git config --global gitreview.username gerrituser
Setting up git-review
After downloading ("cloning") a repository, you need to set it up for git-review. This will automatically happen the first time you try to submit a commit, but it's generally better to do it right after cloning. Make sure that you are in the directory of the project that you cloned (otherwise you will get an error "fatal: Not a git repository"). Then run this command:
git review -s --verbose
Towards the end of the output, you should see something like this:
Found origin Push URL: ssh://gerrit.wikimedia.org:29418/PROJECT Fetching commit hook from: scp://gerrit.wikimedia.org:29418/hooks/commit-msg 2019-02-19 12:40:16.712892 Running: scp -P29418 gerrit.wikimedia.org:hooks/commit-msg .git/hooks/commit-msg
This may ask you for your git username, if it's different from the shell username you're using.
git-review
, then you could use the Gerrit patch uploader or Gerrit/Web tutorial to submit a patch.By default git-review
uses the branch master
.
If the repo you're working on uses another branch, e.g. main
, you need to set the config variable gitreview.branch
.
This can be done with the following command (where main
is the branch name):
git config --add gitreview.branch main
Submit a patch
Make sure that you cloned the code repository that you are interested in (see Download code using Git above).
Make sure that you are in the directory of the code repository (the command pwd
tells you where exactly you are).
Update the main development branch
Make sure that the main development branch (the branch created when you initially cloned the repository) is up to date:
git pull origin master
However, note that some repositories use a different name for their main development branch (for example main
instead of master
, or the operations/puppet
repository has a production
instead of a master
branch).
Create a branch
First, create a local branch for your new change.
Replace BRANCHNAME below by a short but reasonably descriptive name (e.g. T1234
if a corresponding Phabricator task exists for your changes, cleanup-something
, or badtitle-error
).
Other people will also use this name to identify your branch.
git checkout -b BRANCHNAME origin/master
gerrituser@example:~/dev/mw$ git checkout -b cleanup-something origin/master # Switched to a new branch 'cleanup-something' gerrituser@example:~/dev/mw$ git branch * cleanup-something master
This will create a new branch (called BRANCHNAME) from the latest 'master' and check it out for you.
In the example above, we called that new branch cleanup-something
.
Make your changes
Make changes to your local code.
Use your preferred text editor and modify a file.
In the example below, we edit the file README.md
and add a word.
Then close your text editor and check the changes you have made since the last commit, within the file(s) and within the directory:
git diff
gerrituser@machine:/mw/sandbox$ git diff diff --git a/README.md b/README.md index 1d25b27..bc54021 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Hello world! -You can make test changes and experiment with Gerrit in this repository! +You can make test changes and experiment with Wikimedia Gerrit in this repository! Don't worry about messing this repository up; it is meant for testing. gerrituser@machine:/mw/examples$
git diff
displays your changes in unified diff format: Removed lines have a minus (-
) prefix and added lines have a plus (+
) prefix.
These changes are not yet "staged" (via git add
) for the next commit.
Stage your changes for a commit
Run git status
to decide which of your changes should become part of your commit.
It will display a list of all file(s) that you have changed within the directory.
At this point, the output will display "no changes added to commit" as the last line.
Use git add
to make your changed file(s) become part of your next commit.
In the example above we modified the file README.md
, so the command would be:
git add README.md
Any files you've changed that you have not passed to git add
will be ignored when running git commit
in the next step.
git status
.
After you ran git add
, git status
will not show the line "no changes added to commit" anymore.git diff --cached
to see which changes are staged and will go into the next commit.
The output will look the same as for the git diff
command above.Commit your staged changes
Once you are happy with the list of changes added via git add
, you can turn these changes into a commit in your local repository by using
git commit
Short subject line More details. The blank line between the subject and body is mandatory. The subject line is used to represent the commit in code-review emails, search results, git-rebase, and more. Bug: T999999 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch cleanup-something # Your branch is up to date with 'origin/master'. # # Changes to be committed: # modified: README.md
You will then be asked in your text editor to add a descriptive summary for your commit. You must follow the Commit message guidelines. This is what other people will see when looking at the history of changes in the code repository.
Save the commit message and close your text editor. A summary (the commit ID, your subject line, the files and lines changed) will be displayed.
When you git commit
, you are committing to your local copy.
Prepare to push your commit to Gerrit
Synchronise your changeset with any changes that may have occurred in the master branch while you've been working ("rebasing"). From within your branch, run:
git pull --rebase origin master
gerrituser@machine:/mw/sandbox$ git pull --rebase origin master From ssh://gerrit.wikimedia.org:29418/sandbox * branch master -> FETCH_HEAD Current branch cleanup-something is up to date. gerrituser@machine:/mw/sandbox$
git pull --rebase origin master
will fetch new commits from the remote and then rebase your local commits on top of them.
It will temporarily set aside the changes you've made in your branch, apply all of the changes that have happened in master to your working branch, then merge (recommit) all of the changes you've made back into the branch. Doing this will help avoid future merge conflicts.
Plus, it gives you an opportunity to test your changes against the latest code in master.Now you are ready to push your code to Gerrit for review. If you made several related commits, consider merging them into one single commit for review.
Push your commit to Gerrit
If you followed #Prepare to work with Gerrit above and installed git-review
and ran git review -s
, then the command to push changes to Gerrit is:
git review
gerrituser@machine:/mw/sandbox$ git review Creating a git remote called 'gerrit' that maps to: ssh://gerrit.wikimedia.org:29418/sandbox.git Your change was committed before the commit hook was installed. Amending the commit to add a gerrit change id. remote: remote: Processing changes: new: 1, done remote: remote: New Changes: remote: https://gerrit.wikimedia.org/r/#/c/sandbox/+/563720 Test for https://www.mediawiki.org/wiki/Gerrit/Tutorial remote: To ssh://gerrit.wikimedia.org:29418/sandbox.git * [new branch] HEAD -> refs/for/master%topic=cleanup-something gerrituser@machine:/mw/examples$
Upon success, you'll get a confirmation and a link to the changeset in Gerrit. In the example above, that link is: https://gerrit.wikimedia.org/r/#/c/sandbox/+/563720
Congratulations! Your patch is in Gerrit and hopefully will get reviewed soon!
If git review
fails
If you are asked to enter your username and password credentials when running git review
, it means Git has not yet been configured to use SSH.
Review the steps at #Set up Git. In particular, run the following command:
git config --global url."ssh://shell_user@gerrit.wikimedia.org:29418/".insteadOf "https://gerrit.wikimedia.org/r/"
This is okay to run again if you're not sure whether you did it already. Replace shell_user with the shell username for your Wikimedia Developer account.
If you get a Permission denied (publickey). fatal: Could not read from remote repository.
, review the instructions at SSH keys to make sure your ssh agent is running and your identity is added. If you close your Git Bash shell, you will be signed out and need to re-follow these instructions each time.
View the Change / Next Steps
Open the link to your Gerrit changeset in a web browser.
Under "Files", after you clicked the down arrow at the very right of any file in the list, you can see a diff of your changes per file: The old lines are shown in red color and your new lines are shown in green color.
If your commit addresses a ticket in Phabricator, a comment will be automatically added in the Phabricator task if you followed the Commit message guidelines. If you did not, you could either fix your commit message (by creating an updated patchset), or manually add a comment on that Phabricator ticket which includes a link to your changeset in Gerrit.
Other common situations
Also see Gerrit Advanced usage if your situation is not covered here.
Squash several commits into one single commit via rebase
If you made several related commits to your local repository prior to wanting to submit for review, you should squash (merge) those commits into one single commit.
The --interactive
or -i
option allows you to change (rewrite) your commit history.
For each commit, you can modify and change the commit message, add or remove files, or perform other modifications.
First you need to tell git how far back you want to pull. To get a list of all changes in your branch:
git rebase -i origin/master
You can also limit the displayed list of recent changes. HEAD~3
means pull the last three commits:
git rebase -i HEAD~3
After you type this command, your text editor will display your commits in reverse order and a list of available commands:
pick aa8cf1d Adding method customFilterFunctionGetRiskyCountryCodeScore() to GatewayAdapter. pick 38828e2 Adding $wgDonationInterfaceCustomFiltersFunctionsRiskyCountries to donationinterface.php pick be33007 Fix a typo # Rebase 95ccd28..be33007 onto 95ccd28 # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # If you remove a line here THAT COMMIT WILL BE LOST. # However, if you remove everything, the rebase will be aborted. #
Since we only want to send one commit to review, we will squash the last two commits into the first.
Hence change all but the first pick
to squash
:
pick aa8cf1d Adding method customFilterFunctionGetRiskyCountryCodeScore() to GatewayAdapter. squash 38828e2 Adding $wgDonationInterfaceCustomFiltersFunctionsRiskyCountries to donationinterface.php squash be33007 Fix a typo
When you finished picking and squashing and saved the file, another file will open in your text editor to allow you get to edit and merge your commit messages.
Be careful to only keep one of the Change-Id
lines and have it be at bottom of the message after one empty line.
Your messages from your previous commits will automatically be placed in this message:
# This is a combination of 3 commits. # The first commit's message is: (mingle-fr-2012-69) Adding a custom filter for risky countries. Adding method customFilterFunctionGetRiskyCountryCodeScore() to GatewayAdapter. # This is the 2nd commit message: Adding $wgDonationInterfaceCustomFiltersFunctionsRiskyCountries to donationinterface.php # This is the 3rd commit message: Fix a typo Change-Id: I33e44ec0d93628d9a53c15e08eb89f352b7d5fe0 # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # Not currently on any branch. # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: donationinterface.php # modified: gateway_common/gateway.adapter.php #
Remember to put your (updated) summary message in the commit. In this case the new summary message will be:
(mingle-fr-2012-69) Adding a custom filter for risky countries.
Change-Id
you choose.If all goes well, you should see a successful rebase message:
[detached HEAD 02f5e63] (mingle-fr-2012-69) Adding a custom filter for risky countries. 2 files changed, 92 insertions(+), 3 deletions(-) Successfully rebased and updated refs/heads/mingle-fr-2012-69.
Afterwards, submit your patch for review:
git review
You should see a message like this showing your git review went to Gerrit (in this example, to https://gerrit.wikimedia.org/r/7187):
remote: Resolving deltas: 100% (4/4) remote: (W) 02f5e63: commit message lines >70 characters; manually wrap lines remote: remote: New Changes: remote: https://gerrit.wikimedia.org/r/7187 remote: To ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface.git * [new branch] HEAD -> refs/for/master/mingle-fr-2012-69
Amending a change (your own or someone else's)
Sometimes, you might need to amend a submitted change. You can amend a change as long as the change hasn't been merged yet.
You can amend your own changes. To amend changes submitted by someone else, you need to be a member of Gerrit's Trusted-Contributors group. To become a member of Trusted-Contributors, find someone who is a member and ask them to add you. The group is viral in that members can add new members, use your powers responsibly.
First, checkout the change with this command:
git review -d changeNumber
For example: git review -d 1814356
You can look in Gerrit to figure out the changeNumber. It is the number in the URL of your code review page.
Next, make some changes with your favorite text editor.
git add
the files as needed, then commit the change (ensuring you are amending the commit):
git add Example/Example.body.php
git commit --amend
-m
flag to specify a commit summary: that will override the previous summary and regenerate the Change-Id.
Instead, use your text editor to change the commit summary (in the file .git/COMMIT_EDITMSG
) if needed, and keep the Change-Id line intact.Push the change:
git review
Rebasing (updating the patch to include other changes)
Sometimes you might want to update your patch to include all of the changes in the repository that have happened since you submitted it. This is called "rebasing". There's usually no need to do it, unless the review has been taking a long time and you want to make sure your changes still work with the latest version of the software, or if Gerrit reports a merge conflict in your change.
You can do it locally using the git rebase
command with the right options, but Gerrit's web interface provides a more convenient way to do it.
In the simplest scenario, just click "Rebase", keep the default selection of "Rebase on top of the master branch", and click "Rebase" again to confirm.
If your patch has a merge conflict, you will get an error. You can then check the "Allow rebase with conflicts" option and try again, which will amend your patch with conflict markers, similar to those generated by Git commands. You will then need to amend it yourself, editing the files manually to resolve the conflicts.
Sometimes you might also want update your patch to include changes proposed in another patch (adding a dependency on that patch), but which have not been merged yet. In this case, select "Rebase on a specific change, ref, or commit" instead and provide the change in the input field.
If your patch already has such a dependency, you will also get the option to select "Rebase on top of the master branch (breaks relation chain)" in order to remove it. You will also get the option to check "Rebase all ancestors", which will rebase the patch together with the dependency.
If you use the git rebase
command, it's best to make rebase updates a separate patch, so that your code reviewers have an easier time seeing what changes you've made and which changes have happened in other patches.
Troubleshooting
For problems and how to solve them, see Gerrit/Troubleshooting .
See also
Also useful are these pages:
Third party guides to Git
- Video tutorials how to use Git (on Wikimedia Commons)
- Try Git (interactive demo)
- GitMagic A git guide with translations
- Git Community Book will take you gently into Git internals. (It is hard to "get" git until knowing something about how it works internally.)
- Git's website with documentation
- Another useful OpenStack Git guide (if you subtract away GitHub stuff)
- Understanding the Git Workflow by Benjamin Sandofsky
- Using Git in Eclipse