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://git.gnome.org/yelp.git. If any git people spot something braindead, point it out.
git clone ssh://git.gnome.org/yelp.git
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
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
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
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.
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
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
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
-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.