Using bzr as a VCS for GCC
The most common workflow for bzr is to have a different directory for each branch of ours. This doesn't work well with GCC which has a huge tree, and duplicating it every time we want to add a feature is both slow and disk-space expensive.
So the best approach is to keep all our branches in a single directory, and the following steps are needed to achieve this with bzr. Notice that since there is no official bzr hosting for GCC we use the lp:gcc mirror at Launchpad, which is usually up-to date within 3-4 hours from SVN trunk.
Initialise local repo
We 'll be keeping various feature branches of the gcc tree so we need a repository somewhere mirroring the lp:gcc repo. We'll create this in a local dir, just make sure this location is backed-up often. This is a no-trees branch so it doesn't contain any code, only metadata related to our changes.
cd ~/src mkdir gcc-repo/ cd gcc-repo/ bzr init-repo --no-trees . bzr branch lp:gcc
In case we are behind strict firewall or proxy, instead of lp:gcc use http://bazaar.launchpad.net/~vcs-imports/gcc/trunk for direct HTTP access to launchpad. Expect some slowness when pulling trunk from remote.
Create a local checkout to work on
cd ~/src mkdir gcc-co/ cd gcc-co/ bzr checkout --lightweight ../gcc-repo/trunk
gcc-co is the directory where the actual code is, and we code our changes in there.
Workflow
When we first created the checkout there were no branches besides trunk, so we checked out that one. All of our changes should be put in appropriate feature branches so we need to create one:
bzr switch -b bugfix-NNNN [ ... hack hack ... ] bzr status bzr commit
What if we made changes in trunk before actually creating the new branch? It's OK, all uncommitted changes are silently migrated to the branch we switch to.
This serves also as a big fat WARNING for the case where we used bzr switch when we had uncommitted changes. What happens is that all of these changes are merged with the branch we are switching to, bringing conflicts and other profanities...
Just make sure (with bzr status) that all changes are commited before switching branches. If you don't want to commit, you can temporarily put your changes in a shelf to clean the status:
bzr shelve -m "short description" [files]
Pulling from latest trunk
bzr switch trunk # Make sure that there are no changes from other branches accidentally migrated into trunk when switching. bzr status bzr pull bzr switch mybranch bzr merge
Good luck resolving conflicts! Use a good tool OS like emacs for this.
Pushing changes to a remote bzr repo
Useful commands
Generate a diff of your branch against trunk:
bzr diff -rbranch:../gcc-repo/trunk > ~/mypatch.diff
Various commands:
bzr info bzr revno
Notes
- WARNING: don't store your repo or working dir over NFS. NFS slows bzr down unnacceptably for huge projects like GCC!
WARNING: Shelve is a very handy tool but don't use it too much, actually never put things on a shelf for more than 15 minutes or so! Shelves, as implemented in 2.5.0, are not stored inside the gcc-repo directory which means that if we make a checkout in another dir or another PC all shelves are lost!