Using Git

Git is a distributed version control/source code management system. This document explains how we're using Git, how you can obtain the source code using git, and how developers can push code.

Obtaining the source

We have a 'central' git repository which you can clone to get the latest version of the source code. Simply clone it like so:

git clone git://dmdirc.com/~dmdirc/client dmdirc

You will then have a copy of DMDirc checked out in the dmdirc directory. All future git commands will need to be run from under this directory.

DMDirc uses several submodules for various components, so you'll need to tell git to initialise and update the submodules:

git submodule init
git submodule update

Once that's done, you will have a working checkout of the DMDirc source.

Keeping up to date

Your checkout will need to be kept up to date regularly. The best way to do this is to fetch the latest changes and then rebase your work on top of them:

git fetch
git rebase origin/master

You can also merge your changes instead of rebasing them, but this is generally messier and makes your code harder to review later. You can fetch and merge in one go (by default) with a single command:

git pull

Because of the way submodules in git work these also need to be kept up to date. If you have no changes made to your submodules, the easiest way to do update them is to run

git submodule update

If you have changes to a submodule that have not yet been incorporated into the main repositories, you can switch to the individual submodule's directory and perform a git fetch/rebase as you would with the main client. Newer versions of git allow you to pass a --rebase argument to the submodule update command to do this in one go.

If a new submodule is added, you will need to tell git to initialise the submodule before updating, as you did initially after cloning:

git submodule init
git submodule update

Pulling branches from developers

The three main DMDirc developers have their own repositories containing branches for features they're working on. You can add these repositories to git and pull branches from them:

git remote add chris git://dmdirc.com/~chris/dmdirc
git remote add shane git://dmdirc.com/~shane/dmdirc
git remote add greg git://dmdirc.com/~greboid/dmdirc

You can then issue git fetch commands for each developer:

git fetch chris
git fetch shane
git fetch greg

And list all the branches available to you:

git branch -r

If you see something you like the look of, you can pull it into a local branch with:

git checkout -b local_branch_name remote_name/remote_branch_name

For example, if you see a 'smilie-support' branch in Chris's repository, you can pull it into a local branch named 'smileys' like so:

git checkout -b smileys chris/smilie-support

Other developers also have their own branches repositories that may be of some interest:

git remote add michael git://dmdirc.com/~michael/dmdirc
git remote add niall git://git.soren.co.uk/river/dmdirc.git/

Submitting changes for review

Introducing Gerrit

All commits to the central repository should now be made via Gerrit. To do this, you first need to configure SSH access to Gerrit:

  1. Click 'Sign in', and sign in a DMDirc LDAP account
  2. After you sign in, you will be prompted to add an ssh key, if you skip this step or want to change it at a later time then:
    1. Click 'Settings'
    2. Click 'SSH Keys'
  3. Paste your SSH public key into the text box
  4. Click 'Add'

Configuring your user details

You need to configure Git to use the same e-mail address as you specified in Gerrit. We also require that all committers use their real name in commits. To do this, you can use the following two commands:

git config user.name "Firstname Lastname"
git config user.email "username@dmdirc.com"

You will also need to do this from any submodules you want to commit from

Committing

Once you've made your changes, you need to commit them to your local repository. You do this using the git commit command. Standard git commit messages have a short synopsis on the first line, then a blank line, then any additional details. If your commit is related to a DMDirc issue, you should reference the issue ID, for example “CLIENT-123”. If your commit fixes the issue, you should say “fixes CLIENT-123”. A typical commit message may look like this:

Introduce some functionality to some component

This allows such and such to do new and exciting things. It requires
some conditions to hold. Fixes CLIENT-123.

Pushing changes

When you have a change to be submitted for review, you push it to Gerrit using the git push command:

git push ssh://USERNAME@dmdirc.com:29418/client HEAD:refs/for/master

This will push your local HEAD to Gerrit for review. If it passes review, it will be committed to the master branch (determined by the pathspec at the end of the command). You can view the status of the review at http://gerrit.dmdirc.com/.

Useful extras

To aid in development, there are certain things we recommend that you do that will help when using Gerrit.

Adding Gerrit as a git remote

To save typing out the large git push command every time you wish to submit something to Gerrit, you can add it to your git config file. Simply open .git/config in your favourite text editor and add:

[remote "review"]
        url = ssh://USERNAME@dmdirc.com:29418/client
        push = HEAD:refs/for/master

Then when pushing you can simply do:

git push review

You will also need to do this from any submodules you want to commit from (replacing “client” in the url, with the name of the submodule)

Automatic Change-Id: Lines

Gerrit stores changes using Change-Ids theses are similar to commit hashes, but with an “I” prepended to them.

The Gerrit server can automatically generate these for you when you push a change, or you can have them automatically added to all your commit messages by running the following command:

scp -p -P 29418 USERNAME@dmdirc.com:hooks/commit-msg .git/hooks/

The advantage to this is that if you need to edit a commit in future to resubmit (either it needs rebasing or there is a bug in it), the Change-Id will be already in the commit message and gerrit will know which change your commit is associated with, otherwise you would need to look for the Change-Id and add it yourself else gerrit would think the commit was a new changeset.

You will also need to do this from any submodules you want this functionality for.