Git for Gnome

This is not a “let’s use git” post. This is a “here’s how we’d use git, if we did” post. With all the recent git talk, I decided I’d try learning it with one of my on-again-off-again projects, Pulse. Caveat: I am not an SCM geek. I don’t enjoy learning SCM systems for the fun of it. I just want to be sure that whatever we use fits our needs. (Further disclaimer: I actually like CVS more than I like SVN. Infer what you will from that.)

If you go looking for documentation on git, you’ll find information on how to set up your own repository, how to clone other people’s repositories, how to make your own little personal branches (and why you should), and how to push/pull/merge. What they generally don’t discuss is how to work with a central repository.

So here’s my day-to-day Gnome SCM activities, translated into git. These instructions assume that Yelp is stored in the mythical git repository ssh:// If any git people spot something braindead, point it out.

Checking Out

git clone ssh://

This will clone the entire Yelp repository into a new directory called yelp. Initially, that directory will be working on a local branch called master, which is branched from the master branch on the server. The alias origin is created to refer to the repository on the server.

To get updates from the remote repository (the analog to cvs|svn update), run

git pull origin

If you’re using lots of remote branches, you may need to run somethinng like

git pull origin master


So you’ve made some changes to some files. To see what’s been changed, run

git diff

Without any options, this shows the differences between the data on your file system and the data in the index. The index is basically all those local changes that you’ve told git you want to commit. Let’s say you’ve modified yelp-document.[ch]. To add your changes to the index, run

git add src/yelp-document.c src/yelp-document.h

Now git diff shows no changes, because all the changes are in the index. But they haven’t actually been committed to the repository yet. To see the differences between the index and the repository, run

git diff --cached

To commit these changes, run

git commit

If you’re thinking there must be a way to skip the git add step, you’re right.

git commit -a

This will find all the differences between your local files and the repository, add them to the index, and commit them. Of course, you still need to use git add to add new files.

Committing Remotely

All you’ve done in the steps above is commit to your local repository. Git people will tell you you should do this early and often, and then push your local changes when a suitable chunk of work has been done. So to commit your work to the central repository, there’s one more step to take.

git push origin

Remember that git clone set up origin as an alias for the remote repository you cloned. Without any extra options, this will merge the changes on your local branch (master) to the branch of the same name on the remote repository.


Git people will tell you to create a new local branch for any set of changes you’re working on. If you’re working on fixing some bug, make a branch for that bug fix. If you’re implementing some whizbang feature, make another branch for that. You can easily switch between these branches. To create a new branch, run

git branch whizbang-feature

This creates a local branch, branched from whatever you currently have checked out. If you currently have the stupid-bug branch checked out, and you want whizbang-feature to branch from master instead, run

git branch whizbang-feature master

This just creates the branch. Your local copy is still a checkout of whatever it was before you called git branch. To start working on the new branch, you’ll want to check it out from your local repository:

git checkout whizbang-feature

You can always see your local branches by running

git branch

Remote Branches

If you check out Yelp and run git branch, you’ll only see your own local branch, master. But Yelp has lots of branches in the central repository. We make them for every stable release series. So where are they?

git branch -r

The -r argument causes git to show the branches on the remote repository you cloned from. You refer to the remote branches by prefixing them with origin/, which you’ll recall is the alias for the remote repository. If you want to look at the stable gnome-2-18 branch, you could run

git checkout origin/gnome-2-20

But if you want to make changes, you should really create your own local branch instead.

git branch gnome-2-20 origin/gnome-2-20

Now you can commit your changes to your local branch, then git push them to the remote branch.

Creating Remote Branches

In Gnome, we create branches for each stable release series. As a maintainer, you need to create branches in the central repository. So you can create a branch like this

git branch gnome-2-20

But that branch is just in your local repository. To push the branch to the central repository, run

git push origin gnome-2-20

Now other users will see this branch when they run git branch -r.

In Gnome, we tag our central repository for releases. So if you release Yelp 2.20.0, you need to create the tag YELP_2_20_0. Creating a tag in your local repository is simple:

git tag YELP_2_20_0

But we need this tag to be in the central repository. To do this, we git push the tag up:

git push origin tag YELP_2_20_0

When you clone a repository, you get all its tags. To see all the tags in the repository, run

git tag -l

And So On

Obviously, there’s a lot more to learn to make really effective use of git. But most of that information is readily available elsewhere. I mosty wanted to address how to work with (and maintain) a central repository, because most git documentation doesn’t. Comments welcome.

8 thoughts on “Git for Gnome”

  1. Shaun, thanks for posting this; it helps to clarify how a normal GNOME project would use git. I’m glad I managed to read past the heretic statement of “I actually like CVS more than I like SVN.” 🙂

    It would be cool to see this on l.g.o, similar to (which focuses on using git-svn on existing GNOME infrastructure).

  2. Hi,

    Excellent writeup from our Editor-in-Chief, thanks!

    Couple comments:

    “git checkout -b new-branch” comes handy. That creates the branch and switches to it.

    Instead of git-pull, many of us use git-fetch followed by “git-rebase origin/master”. That ports your changes to the latest upstream development instead of leaving you with one of those useless “merge” commits.

  3. I agree, I haven’t seen much written on using git with central repositories. Excellent intro, this one goes into my collection of git-references!

  4. To me it is not clear in your post whether it is necessary to do ‘git add’ before committing – it certainly isn’t and… why would you want to do it?

    ‘git status’ is also useful of course.

    It is necessary to do ‘git gc’ occasionally to “reduce disk space and increase performance” – eg running ‘git log’ and ‘gitk’ will always be fast.

    You only need to push the tag if you’ve tagged a commit that has already been pushed in the repository, otherwise it goes along with the commits with ‘git push’.

    ‘git rebase’ is important because it makes your local commits in sync with the updated upstream head, ie the local commits are moved forward to start from the new head.

  5. -git pull
    +git fetch && git rebase origin

    so you don’t end up with 10000000 merge changesets

  6. The index is now called the staging area. It stages the pending commit. This is what it should have been called all along!

    @Marko: Why ‘git add’ when you’ve already added a file? Because, in git’s opinion, svn’s policy of automatically committing every change it can find is reckless. It’s easy to explicitly add files to the commit each time, and it cuts down on mistakes (like checking important passwords into the repository, oops). Personally, I much prefer this approach.

    But, as Shaun says, if you don’t like creating each changeset by hand, you can just use ‘git commit -a’ to just use the shotgun approach.

Comments are closed.

Creative Commons Attribution 3.0 United States
This work by Shaun McCance is licensed under a Creative Commons Attribution 3.0 United States.