|
Contents
Git for GNOME svn developers
Git is the revision control system used for the Linux kernel, Xorg, Freedesktop projects, Cairo, and many other projects. This page documents how you can use Git to do GNOME development.
DISCLAIMER: This page is NOT about switching GNOME to use Git instead of Subversion. Do not even comment about that here; it's not the right place to do it. This is about using Git in conjunction with GNOME's existing infrastructure.
See also Shaun's basic Git workflow: part 1 and part 2.
Why Git?
Roughly in order of importance / convenience:
- Offline operation. You can commit, create branches, merge branches, etc., without having to be online. This is a huge benefit for hackers with laptops.
Fast! Since git operates locally unless instructed to go to the network, operations are very fast. Most operations take less than 10 seconds, even for huge projects like the Mozilla tree (confirmed by FedericoMenaQuintero).
- Distributed. There is no central point of control (except if you use Git to mirror SVN, of course), and all the cool kids are doing it anyway.
- Merging branches is very pleasant. CVS and SVN always made this hard.
- Repository size. A git-svn repository with dozens of branches still "weights" like the original SVN checkout (if not slightly less).
- Full history. When you clone a repository you have the entire history available, so you can roll back, diff or check out to any point in time without ever hitting the original repository.
- Fully scriptable. Many of the commands available are scripts or combinations of basic commands. You are encouraged in creating scripts and aliases to ease your workflow, once you find out that you're repeating certain sets of operations.
How do I use Git to hack on an existing GNOME project?
As of January 2007, GNOME uses Subversion as its revision control system. Fortunately, Git has good tools to let you use a SVN repository as the "mothership" while you enjoy most of Git's features on your own computer.
Please use Git 1.5 or later.
Cloning a GNOME repository
The easiest way is to use GNOME's own git-mirror. You can start working on a repository like this:
git clone git://git-mirror.gnome.org/git/modulename cd modulename
Since all gnome modules have a common url prefix, it can be convenient to set up an alias:
git config --global url.git://git.gnome.org/git/.insteadof gnome:
Then modules can be grabbed by doing this:
git clone gnome:modulename cd modulename
To be able to use the git checkout to also interact with the current subvesion trees, you need to setup the git tree to use git-svn. For write access to the current subversion setup, you can run:
git svn init -s svn+ssh://svn.gnome.org/svn/modulename --prefix=origin/svn/ git svn rebase
If your username is not the same as the one used to login to your computer, you will need to change the SVN URL like this:
git svn init -s svn+ssh://username@svn.gnome.org/svn/modulename --prefix=origin/svn/
If you do not have write access to the subversion repositories or want a readonly interface to the subversion repositories, run:
git svn init -s http://svn.gnome.org/svn/modulename --prefix=origin/svn/ git svn rebase
This gets the initial clone from GNOME's git-mirror, and then uses git-svn to quickly populate all the information required by git-svn.
Getting updates
Once you have cloned a repository, you'll want to update it periodically from upstream's changes. You can simply do this:
cd modulename git svn fetch git svn rebase
You can of course do "git fetch" on individual branches, or use Git's features normally.
Doing local development
The cardinal rule of doing development with Git is: don't use the master branch. Think of the master branch as the "pristine copy" of upstream's sources.
Create a branch:
cd modulename git checkout -b mybranch
This creates a branch starting from wherever you are, which at this point usually means "HEAD in the master branch".
With Git it is customary to do many small, logical commits, instead of big commits which modify many things at once.
Modify some files:
emacs file1.c file2.c ChangeLog
Mark them and commit them:
git add file1.c file2.c ChangeLog git commit -m "Colorize the frobs in funny ways"
Note you need to tell Git what to commit: the "add" and "commit" steps are separate. This is useful when you need to keep a modified file around but not commit it just yet.
Merging your branch and committing to SVN
Once you are finished with your work in mybranch, you'll want to merge it to your master branch (remember, that's the one which tracks the upstream SVN repository) and then actually push the changes to SVN.
Switch to your master branch:
git checkout master
Merge the changes from your branch:
git merge --squash mybranch
IMPORTANT: The --squash option is important. Git keeps information about what got merged where, but SVN doesn't. Git-svn cannot handle "normal" merges as done with Git; the --squash option tells "git merge" to act as if this were a manual commit, not a merge (more info). Notice that in the upstream Git repo some patches which would allow git-svn to use a real merge instead of the faked one with --squash are already included (Link to Git commit).
Commit the changes:
git commit -a -m "Merge mybranch into the master branch to implement feature X"
Finally, send the changes to the SVN repository:
git svn dcommit
Using git with jhbuild
JHBuild has support for using git to manage svn and cvs repositories. To enable this support add the following to your .jhbuildrc file:
svn_program = git svn cvs_program = git cvsimport
This will then cause jhbuild to check out cvs and svn repositories using git, from the current revision. If you want the full development history you need to checkout the module as described above.
Note: This will not convert existing cvs/svn checkouts to use git and thus requires you to manually delete any existing svn/cvs checkouts before using this feature
Sending patches
Git encourages you to do many small, self-contained commits. For example, say you want to add a feature to a program, but first you need to refactor the code a bit to allow your feature to fit in. A first patch would do just the refactoring. A second patch would actually add your feature. A third patch would update the documentation. If your feature is very complex, you may want to add stub functions in a commit, then actually fill them in in further commits, etc.
The idea is to submit small patches for review by maintainers, instead of burdening them with the information overload of a single mega-patch.
Let's say you created a branch mybranch off the master branch. Hopefully this is not your original work branch, but instead a "cleaned up" branch with actual logical commits, which you would be proud to show to your mom, instead of experimental / "fix whitespace" / "remove debug printf" commits that you had in the work branch. You have several commits in that branch. If you are in mybranch, you could generate a patchset like this:
mkdir ~/patchset git format-patch -n -o ~/patchset master
This will create ~/patchset/0001-xxx.patch, ~/patchset/0002-yyy.patch, etc., for all the commits in your branch. Each file is intended to be a separate mail message which contains your commit message, a diffstat, and the actual patch. These files are in Unix MBOX format; you can import them into Evolution or your mailer of choice to send them out to the maintainer. If you import them in Evolution, you can then select "Edit as new message" from the context menu of one of those mails to enter the To: header and actually send out the mail.
If you want to attach a patch or an entire patchset to GNOME's Bugzilla, you can use the most excellent git-send-bugzilla script written by Steve Frécinaux. This Perl script will attach a set of commits as single patches, complete with commit message and diffstat, to a bug given its number.
Full repository checkouts
Git-mirror.gnome.org (this is the easiest and most complete option)
libwnck or git clone http://git.jsharpe.net/libwnck.git
gnome-control-center or git clone http://git.jsharpe.net/gnome-control-center.git
gnome-settings-daemon or git clone http://git.jsharpe.net/gnome-settings-daemon.git
gnome-desktop or git clone http://git.jsharpe.net/gnome-desktop.git
