Branches are resources and need to be managed like anything else. Before you make a branch you should coordinate with others and consider alternatives. Branches create multiple copies of source code. Each of these copies then needs to be maintained; which rarely happens. More likely branched code becomes stale and is discarded.
If branched code is not merged back into the main Borealis trunk then the benefit of the branched development can't be shared. Often the hassle of merging branched code by the developer exceeds the benefits of sharing the code with the group. This dynamic can be avoided by using alternatives to branching.
Branches are required to manage software releases. In this case we want a permanent copy of a complete system associated with a version of the software released to the public. After creating a release branch, fixes are applied separately to each branch. While this is duplicated effort, the released version will remain stable while development on the trunk continues. After the next release fixes will usually no longer be applied to the prior releases. Consequently the number of places where a fix needs to be applied is limited.
A few developers may want to work on some code utilizing CVS and then merge the code back. Afterwards the branch is stale and discarded. The stale branch will clutter the repository. There are times when branching is the best option; especially when developers are working at different sites.
Alternatively developers can work out of a common sandbox. They can each have their own sandbox to work on their code and then integrate files by copying them to the common sandbox. When done they can merge the common sandbox into the Borealis trunk.
A developer may want to write a demo program from a snapshot of the system. The intent is to make a branch that can be reliably revisited later for a demonstration. Over time this demo will become less interesting and will no longer be used. Also the demo will not work with current code so the demo will become even less interesting over time.
Ideally a demo would be maintained to continue to work with the mainstream code base. This also would make it easier to extend the demo or to reuse common demo code. As new demos are written programmers can extract common code that may be useful for future application and demo developers. Even if the demo was to get stale it would not conflict with other code.
Demos can be developed in a sandbox representing a snapshot of the system. Initially an originating copy of the sandbox should be made for reference. As code changes it is sometimes useful to see what the original code looked like. This approach avoids branching, but may be inconvenient when several people at remote sites need to work on the same demo.
A developer may want to make one or more alternative experimental versions of a component. While branches could be used is usually better to manage component versions through the build process. Build parameters can be used to select which component version to use or to enable and disable the use of an experimental component.
Each alternative version of a component can be contained in a separate subdirectory. Code common to versions can be stored in a common subdirectory. This way the least code needs to be maintained and all versions of a component are included when the mainstream branch is checked out.
Branch names should be indicative of their usage. By convention temporary branches should begin with WORK_, demos should begin with DEMO_, and releases should be named BOREALIS_ followed by a release number. Dots aren't allow in branch tag names. A dash can be used instead.
BOREALIS_100A DEMO_DBCONFERENCE_2004 WORK_STORAGEMGR_JUNE_2004
This is useful when creating a snapshot for a release or demo. Full branches are usually not intended to be merged back into the trunk. Instead they need to be maintained separately, so the amount of maintenance should be kept to a minimum.
> checkout # Check out all of borealis. > cvs tag -b <BRANCH_NAME> borealis # Tag the whole tree with the branch name.
Developers generally need to create temporary branches. After the code is merged the branch is unlikely to be revisited. Usually the branch can be isolated to a subdirectory of the Borealis tree. This allows any changes outside the directory to be picked up while working on the branch. Instead if you want to freeze changes outside the directory then create a branch over all of Borealis.
# Recursively create a branch version for a directory. # In this example we are making a branch of only the admin/ directory. # borealis/src/modules> cvs tag -b <BRANCH_NAME> admin T admin/Admin.cc T admin/Admin.h T admin/Makefile.am T admin/PendingQuery.h cvs.exe tag: Tagging directory # Make the branched version current. # borealis/src/modules> cvs update -r <BRANCH_NAME> admin
Now you can make changes and test them. When you check in your changes they will go into the branch and not the trunk. You can check out a fresh copy of your branch with:
> checkout # Check out all of borealis. > cd borealis/src/modules borealis/src/modules> cvs update -r <BRANCH_NAME> admin
By the time you are ready to merge your branched code into the trunk it is likely that some of the same files have changed in the repository. You need to find out which files have been changed before you can check them in. The "cvs diff" and "cvs rdiff" commands may be helpful.
The checkin utility will scan one directory at a time and see if any files in the repository have been changed. If not your changes will be committed. Otherwise none of the files in the direcotry will be committed. In this case you'll need to merge the changes in your sandbox, retest it, and then try and check them in again.
# Get your updated files into your sandbox. # borealis/src/modules> cvs update -r <BRANCH_NAME> admin # Copy the branched directory to a temporary location. # borealis/src/modules> cp -r admin /tmp/admin # Copy your changed files into the sandbox. # > checkout # Checkout the Borealis trunk. > cd borealis/src/modules borealis/src/modules> rm -r admin borealis/src/modules> cp -r /tmp/admin admin # Now you can commit the changes if they look good. # borealis/src/modules> cd admin borealis/src/modules/admin> checkin -m "replacement files"
Alternatively you can use the automatic merge feature of CVS. The risk here is that the merges may not be done quite the way you want them or conflicts may arise.
# Merge updated files into the trunk. # > checkout # Checkout the Borealis trunk. > cd borealis/src/modules borealis/src/modules> cvs update -j <BRANCH_NAME> admin # Now you can commit the changes if they look good. # borealis/src/modules> cd admin borealis/src/modules/admin> checkin -m "replacement files"