Using Git to track the Firefox CVS repository
Git is a distributed version control system that was written for managing the Linux kernel. I've been using it recently to make it easier to manage my code changes against a CVS repository for which I don't have write access.
The CVS repository is the codebase Firefox. Usually I'd check out a copy of the CVS repository, make my local changes, generate a patch and attach it to a Bugzilla entry for review. When it passes this then gets committed by someone with write access.
What becames hard to manage is dealing with checkouts that require a number of patches, keeping track of what has been applied, keeping patches around to be able to reverse them out and handling multiple copies of trees.
An even bigger issue is how to create patches that add directories or files when you don't have write access to CVS. 'cvs diff' only includes new files if they have been added via 'cvs add'. This requires write access to CVS. You can work around this by manually editing the local CVS files, or using a utility like 'cvsdo'. Unfortunately this still doesn't work for directories. The only way to add a directory to CVS, to have it picked up with 'cvs diff', is with 'cvs add' and write access to the repository. This issue and workarounds is described in the Mozilla documentation.
This problem will go away as Mozilla migrates to a new version control system, but in the meantime I decided to try tracking things with Git after reading an article by Diane Trout who is doing something similar.
I did a standard checkout of the sources for Firefox, following the Mozilla Build instructions. Within the checkout directory I created a git repository containing all the files, with relevant .gitignore instructions to not include CVS directories, etc. Something like this did the trick:
Periodically I update the main git repository with the latest changes from CVS. I have a script that I run that does something like this:
Now that the main repository is updated I can merge in the changes with my 'patches in progress' easily. Here is a commented example of some workflow:
By adding a .mozconfig file in the 'mozilla' directory and doing 'make -f client.mk build' you can build your own trunk version of Firefox. A simple .mozconfig that will work on most platforms is:
If you're keen to try playing around with the code, I wrote a short post on how to add a new DOM element a while back that may give a bit of a start.
If you have any additional git tips or suggestions, please post a comment.
Categories: firefox
The CVS repository is the codebase Firefox. Usually I'd check out a copy of the CVS repository, make my local changes, generate a patch and attach it to a Bugzilla entry for review. When it passes this then gets committed by someone with write access.
What becames hard to manage is dealing with checkouts that require a number of patches, keeping track of what has been applied, keeping patches around to be able to reverse them out and handling multiple copies of trees.
An even bigger issue is how to create patches that add directories or files when you don't have write access to CVS. 'cvs diff' only includes new files if they have been added via 'cvs add'. This requires write access to CVS. You can work around this by manually editing the local CVS files, or using a utility like 'cvsdo'. Unfortunately this still doesn't work for directories. The only way to add a directory to CVS, to have it picked up with 'cvs diff', is with 'cvs add' and write access to the repository. This issue and workarounds is described in the Mozilla documentation.
This problem will go away as Mozilla migrates to a new version control system, but in the meantime I decided to try tracking things with Git after reading an article by Diane Trout who is doing something similar.
I did a standard checkout of the sources for Firefox, following the Mozilla Build instructions. Within the checkout directory I created a git repository containing all the files, with relevant .gitignore instructions to not include CVS directories, etc. Something like this did the trick:
cvs -d ... checkout mozilla/client.mkI keep this repository as the main repository linked to CVS. When I work on a bug or some functionality I can clone this repository and use git's branch management functionality to work on different things.
cd mozilla
make -f client.mk checkout MOZ_CO_PROJECT=browser
cd ..
git init
git add .
git commit -m "Initial import"
Periodically I update the main git repository with the latest changes from CVS. I have a script that I run that does something like this:
cvs update mozilla/client.mkThis does a 'bulk commit'. It doesn't import the individual CVS checkins with comments but for my purposes I don't need this. I just need something quick that works.
cd mozilla
make -f client.mk checkout
git add .
git commit -a -m "Update to CVS"
Now that the main repository is updated I can merge in the changes with my 'patches in progress' easily. Here is a commented example of some workflow:
This workflow works quite well. At any time I can create additional branches very cheaply to try things out, reverting back to the original branch if I change my mind, or to pull in the changes if I want to keep them:
# Clone the firefox repository for working on a bug
git clone /git/firefox.git bugfixes
cd bugfixes
# I like to leave the 'master' branch created by the clone
# as being a pure copy of the original repository and work
# on a branch. The following creates a branch to work on.
git checkout -b bug_123
# Now I make changes, add files, remove files, etc. I commit
# to the branch frequently with:
git add some_file_i_added.txt
git commit -a -m "Some message"
# At some point I want to update the 'master' branch with the
# recent CVS updates.
git checkout master
git pull /git/firefox.git
# When in the bug_123 branch I can merge in the changes I
# got from the latest CVS that I keep in 'master'
git checkout bug_123
git pull . master
# In branch bug_123 at the momentTo generate a patch that can be applied to the original CVS checkout, I can generate a 'git diff' in my branch with committed changes, against the 'master' branch containing the up to date CVS:
git checkout -b try_something
# Make changes
git commit -a -m "My changes"
# Go to the original branch and pull in those changes to keep them
git checkout bug_123
git pull . try_something
# In branch bug_123I can also generate a patch against a specific git commit:
git diff master >~/bug_123.patch
git diff d889a66ff046f3737b87bd3e4098dcb156b9836f >~/bug_123.patchSome miscellaneous commands that are also helpfull:
# What has been changed since last commitI've published my regularly updated git repository of the Firefox CVS tree on my server. It can be retrieved using the 'git' or 'http' protocols using:
git status
# A diff of my recent edits
git diff
# A log of commits
git log
# Push my bug_123 changes to the 'master' branch in a remote repository
git push user@server.com/git/changes.git bug_123:master
# Git protocolNote that you can't browse the repository using the HTTP URL due to me having directory browsing turned off, but 'git clone' or 'git pull', etc works. You can browse the repository using gitweb via http://www.double.co.nz/cgi-bin/gitweb.cgi. This is actually an excellent way to view recent changes made to the Firefox CVS.
git clone git://double.co.nz/git/firefox.git
# HTTP protocol
git clone http://double.co.nz/git/firefox.git
By adding a .mozconfig file in the 'mozilla' directory and doing 'make -f client.mk build' you can build your own trunk version of Firefox. A simple .mozconfig that will work on most platforms is:
. $topsrcdir/browser/config/mozconfigFor Mac OS X users, add the following line:
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-@CONFIG_GUESS@
mk_add_options MOZ_CO_PROJECT=browser
ac_add_options --enable-debug
ac_add_options --with-macosx-sdk=/Developer/SDKs/MacOSX10.4u.sdkYou can run the new build on Linux or Windows with:
obj-dir/dist/bin/firefoxOr on Mac OS X:
obj-dir/dist/MinefieldDebug.app/Contents/MacOS/firefoxReplace 'obj-dir' with the object directory created during the build, and I recommend using -ProfileManager or something similar to do your testing a profile separate from your main Firefox profile.
If you're keen to try playing around with the code, I wrote a short post on how to add a new DOM element a while back that may give a bit of a start.
If you have any additional git tips or suggestions, please post a comment.
Categories: firefox
Labels: mozilla

11 Comments:
Pretty interesting - permit me to ask a stupid question. Git's website offers RPM's and Debian packages... what would you suggest for the MozillaBuild users on Windows, and for the Mac users?
On the Mac I use git-core from Macports.
On windows I built from source on cygwin. It's not the most user friendly way of doing things but I do the clones, commits, etc in cygwin then switch to the MozillaBuild msys environment to do the builds.
Hopefully git-mingw will eventually be usable (if it's not already - I didn't go into great detail looking at it).
I do switch from Mac to Windows often, sharing code to test the Video stuff, and it's worked quite well.
Is there any web access to firefox git repository ?
Since how long do you have your git repository and how closely do you follow the cvs changes ? I wonder if it would be convenient to use it to track some recent regressions.
fx, I've provided web access via:
git clone http://www.double.co.nz/git/firefox.git
Eventually I'll get gitweb going. Note that you can't browse that URL using a browser as I've got directory listings turned off. You can use git to get it though.
jmdesp, June 6th was when I first imported things but I didn't start doing regular updates until about 3-4 days ago. It now updates every 6 hours in a cron job.
Because I get a bulk update of all the cvs commits it that 6 hour period it may not make it easy to track down issues. Although I guess having it down to a 6 hour window is useful. I could lower the update time too.
If you want to move backwards through the commits you can do:
git checkout HEAD~1
This will move you one checkout back. Doing it again will move you back a second. You can move it back more by replacing ~1 with the number of checkouts.
To get back to the original top checkout:
git checkout master
I've set up Gitweb. You can access it here:
http://www.double.co.nz/cgi-bin/gitweb.cgi
It's actually a very cool way of browsing the changes made to Firefox CVS!
thanx !!
(would it be possible to have the same thing with xulrunner ?)
fx, I've done a quick import of the xulrunner trunk code. You can get it from either of these commands:
git clone git://double.co.nz/git/xulrunner.git
git clone http://double.co.nz/git/xulrunner.git
It also shows up in the gitweb listing. I haven't tested building it from that source yet. I'll do that when I'm next on a grunty enough machine. Can you let me know if that's what you wanted?
Unfortunately it doesn't share any commits between firefox.git and xulrunner.git so they are are essentially separate projects. I don't think that'll be a problem though - it would hard to work out a cvs import routine that was able to get around that.
jmdesp, I see there is a git bisect command which will probably automate a lot of the tracking down of regressions since it does a binary search of commits within a range and takes user input indicating whether an individual commit was 'good' or 'bad'. That might prove useful.
why not mercurial I wonder - same methodology, built on python (with a fast C-core). But it also runs on different OSes.
Just in case, you want to try it out - there is a git-to-mercurial converter (which is pretty fast).
I use mercurial for some projects. Mozilla actually uses mercurial for it's next generation version control system. I wanted to try git out and get a feel for it which is why I'm using it for this.
Have you tried using git-cvsimport?
- JH
Post a Comment
<< Home