When I first got into source control, it was with a team who had no experience with any form of source control. We initially chose CVS, but over the past year, we eventually migrated to Subversion due to it’s more elegant setup with branches, tags and revisions. In this time, we have four main projects on Subversion: corporate intranet, main website, client software, Septuro. The last two are pretty traditional setups, where our file tree looks something like this:
/software /trunk /releases /1.0 /1.1 /branches /restructuring /tags /1.0.0 /1.0.1 /1.1.0 /1.1.1
Anyone familiar with Subversion will recognize this setup as a very normal setup. We use trunk to add new features, branches to do major work that will destabilize the project for awhile, releases for maintenance work and tags for snapshots of individual releases. This system works fine when you are actively maintaining multiple releases – where the software is being deployed to a large number of sites.
However, our intranet and main website repositories have to be laid out differently, due to them not having multiple releases. Each system is deployed to exactly one location – the local web server. This has caused some issues with how we should lay out our repository. As of right now, it looks like this:
/intranet /trunk /release /branches /front-eod
This system ditches the traditional releases folder setup and uses a single folder called release in its place. This folder is where we keep our maintenance, and at any time, the web server is updated to the newest revision of this folder. This system works okay, until it comes time for releasing new content – unlike a traditional releases setup, we don’t simply clone trunk to a new folder and label it, since the previous folders would be completely unneeded as they are never being used. Instead, we try to merge changes on the trunk over to release, but this is sometimes problematic.
The big problem, however, is how to deal with large projects that should go on a branch. When dealing with branches, you want to make sure they don’t stray too far from one another, or from the trunk, so later merges are as painless as possible. You lay out your milestones (points where it is convenient to merge back into trunk without breaking trunk) and make sure you periodically merge from trunk back into the branch. This gives you time to make sure the branches play nicely, as well as get bug fixes from your maintenance branch onto your feature branches.
What happens when you are working on a large feature change, and halfway through the project, a smaller feature must be quickly pushed through and made live? You can’t just do a new release, because it may have some milestones from that incomplete project! How do you make sure that each branch never strays far, yet there is no sign of a new feature until it is done and approved? That dilemma is what my team is trying to sort through.
Our current idea is to get rid of the release branch and make all milestones disabled by default. Instead of using a release branch, just keep the webserver running from trunk and put all new features in branches. We will lay out milestones out as usual, but all of the new features will be disabled in these milestones – new menu options are hidden, changes in processing is not implemented, etc. The final milestone will be a change that will enable all of these new features. This will allow each branch to keep up to date with each other, but keep incomplete features from being put on the webserver.
I hope this system works. It is our current attempt, but far from our first attempt. I ‘ll keep you updated on what happens.