You should read through GettingStarted and ThingsToKnow before you read this document. It involves some complicated usage of CVS, but the instructions are kept as simple as possible. The document describes how we use CVS branching and merging to do our work safely, and how developers are expected to use it.
This gets confusing when the CVS manuals start talking about HEAD, and MAIN as branches, but they are not. They are just a way to refer to the "trunk" of the source tree vs. a branch such as Begin-MS2-2003-02-24. Here's how we use branches in Obversive:
1. At any one time, there is only a HEAD and milestone branch which we are dealing with. The milestone branch is labeled as Begin-MS#-DATE (like Begin-MS2-2003-02-24) to indicate the date it was begun, and what milestone it is a start of for the project.
cvs -d <cvsroot> co -r <current_branch_name> obversive -d <target_dir>.
cvs -d :ext:myname@cvs.obversive.sf.net:/cvsroot/obversive co -r Begin-MS2-2003-02-24 -d obversive_MS2.
3. As you work in your obversive_MS2 directory (called a sandbox), you are checking your changes into our development branch (called Begin-MS2-2003-02-24 in example above).
4. When everyone thinks it's time to make a release, the configuration guru (currently ZedShaw) starts coordinating it. This involves everyone getting their changes in, verifying that everything is stable, and making sure all goals for the milestone are met.
5. Assuming everything is good, the configuration guru then closes off any further development into that development branch, and announces a CVS freeze. This is necessary so that the configuration guru can make the release and do some tagging magic to set things up for the next milestone's development.
6. When all is done, and everything is released, the configuration guru announces the name of the new milestone development branch (in our example, it would be something like Begin-MS3-2003-04-30 or so).
7. It is then the developers responsibility to check-out the code again into a new work directory (preferrably something like obversive_MS3) and then work commences on the next milestone.
Couldn't be any simpler. When you first do this, you will probably screw it up, but that's OK. Remember, it's not your fault as CVS is a really hard to use tool in this case. Make sure that you do a test commit of something useless (like write a test message to a comment or something...don't create a file) and make sure the other developers pick it up. If they see it in their sandbox, then you're good. Otherwise, you would just do your work like normal.
Developers will not have to do this, so you can skip this part if you are not doing the configuration guru's job. The merging portion of this document is just for future reference to document the procudure the current configuration guru uses. It is as simple as possible to fit the above CVS model.
The merging process only happens when there is a release, and releases only happen off the HEAD. The summary of what happens is that the configuration guru calls a CVS freeze, tags the HEAD with Merge-MS#-DATE, then takes the changes from the current development branch and merges them into that tag. Notice I said tag not branch in that last sentence. Merge-MS#-DATE is a tag since it is intended to just mark the place where changes from MS# were merged in to HEAD. If all goes well, then another tag is applied to HEAD with the name Release-MS#-DATE to indicate the end of the merging and the place where the release was made. Again, it's a tag not a branch. Finally, the configuration guru packages up the release and ships it out. When that's all done, a new branch (yep, you can use a branch now) is created for the developers to work on with the name Begin-MS#-DATE.
For this example, let's say we are on Begin-MS2-DATE, and we want to do a release to start working on a new branch called Begin-MS3-DATE. Here's that same information in procedural form:
1. Announce CVS freeze. Punish all evil doers who violate it.
3. Tag the obversive_Merge-MS2 directory with the Merge-MS2-DATE tag. Do a commit just to be safe. There is now a marker indicating the point in HEAD just before you tried to merge.
cvs tag Merge-MS2-DATE
cvs commit
4. Create another sandbox with the latest HEAD for merging in the Begin-MS#-DATE branch that development is on.
cvs -d <cvsroot> co obversive -d obversive_HEAD
5. Merge in the changes from the current development branch into our newly tagged obversive_HEAD directory.
cvs -q update -d -j Begin-MS2-DATE
6. Fix any conflicts (shouldn't be any really) and commit the changes so they are part of HEAD.
cvs commit
7. HEAD now has the changes from Begin-MS2-DATE. In the same directory, do a tag of the contents to add a Release-MS2-DATE tag for future reference.
cvs tag Release-MS2-DATE
8. Finally, create another sandbox for the new Begin-MS#-DATE branch for the next round of development by checking out the new HEAD and making a branch with the new name.
cvs -d <cvsroot> co obversive -d obversive_MS3
cd obversive_MS3
cvs -q tag -b Begin-MS3-DATE
9. Tell everyone the name of the new branch (Begin-MS3-DATE) so they can start developing on it. They should create a new directory to work in either abandon the old one, or keep it around for future reference.
That's all for the merging process. It's more complicated than regular development, but it is kept fairly simple and designed to eliminate the problem of merge conflicts (which are really nasty). It also lets you back up to a previous release, go to a release to add bugfixes on a new branch (a bugfix branch), or just see what the source was like at previous tags.