Sunday, November 21, 2004

Copy one CVS branch over another

I ran into a little CVS problem the other day at work. We had a branch on which we had our stable production codebase. We were starting the next phase of the project and we decided that the new code should be developed in the trunk. Normally in a situation like this one would merge the Production branch into the trunk and tag the trunk as "NEW_DEVELOPMENT_STARTS_HERE" or some such and start developing from there. But the problem was the trunk was in a sort of messed up state from even earlier and the code in the trunk wasn't even compiling. So our decision was to copy over everything from the Production branch and make the trunk an exact copy of the Production branch. We were not interested in retaining the files in the Trunk.

We attempted to do this with the Eclipse CVS repository plugin - with disastrous results, that too after several hours of frustrating merges and compares! Fortunately for us the trunk was messed up from even before the operations. I decided to finally ditch Eclipse and do this from Unix. My personal opinion is that Eclipse just sucks for something like this, but I will vent about that some other time.

Here is how I accomplished it finally:

First login to a Unix box that has access to your CVS repository.

1. Export your production branch to a folder (say prodBranch) with the following command:
$ cvs export -r -d prodBranch
Export ensures that you don't get the CVS subfolders under each folder. You could also, equivalently, checkout your production branch and manually delete the CVS directories.

2. Now checkout the Trunk to another folder (say trunk :-))
$ cvs checkout -d trunk

3. Find all the files in the trunk that are not present in prodBranch.
$ cd trunk; find . -print | sort > ../trunkFiles
$ cd ../prodBranch; find . -print | sort > ../prodFiles
$ comm -23 trunkFiles prodFiles > ./filesInTrunkNotInProd

The entries in filesInTrunkNotInProd (other than the CVS files/dirs) are files that you had either deleted in the Production branch or had added to the trunk after you had branched off your Production branch. Anyway, you are going to have to get rid of these files from the Trunk, since your purpose to make the Trunk an exact copy of the Production branch.

4. Now do a recursive copy of all files from your prodBranch to your trunk. This will give you everything you have in your stable production branch and retains the CVS information for any of those files that you copied over that may have existed in the trunk previously.
$ cd trunk; cp -r ../prodBranch/* .

To make the Trunk an exact copy of Production, the only thing left to do is to delete all those files that you have in your trunk that are not present in your production branch - i.e. the files in the list that you made above filesInTrunkNotInProd (other than the CVS admin files). We will do that in just a little bit.

5. No go into your trunk directory and do:
$ cvs -nq update
This will give you a list of files that are new in your trunk (indicated by a '?') as a result of your recursive copy from Production and the list of files that were modified because of your copy (indicated by an 'M')

6. Do a "cvs add" for all the files indicated by '?'. (if you saved the output from the previous command it would be a lot easier. Jus replace the '?' with 'cvs add')

7. Grep out all the lines in filesInTrunkNotInProd that don't have the word CVS in them (those are the CVS admin files and folder). Save the output in filesToRemove.

8. Do a "cvs remove -f" for all the files in filesToRemove.

9. Now do a "cvs commit".

You should be done.


Post a Comment

<< Home