TCG has a number of long running projects. Some of them are still using the CVS revision control system because it is working well for our particular use case and the scope of the project doesn’t justify the cost in moving to something more modern.
Recently though, I ran into a little problem. I wanted to pull in a large open source code base into our CVS repository. Because of the size, I thought it would be best if I did the commit from our development Linux box sitting close to the CVS server. This meant doing the commit from the command line using the old fashioned cvs command…and cvs doesn’t have, as far as I know, a simple way to do a recursive addition of a large directory structure.
To make things a little more complicated, a few of the files are binary files like image files and compressed archives. That means we have to use the ‑kb modified when adding them to make sure CVS knows not to mess with the file during checkouts.
After some trial and error, I was able to write a short script using a few key Unix commands to make this work:
find . -type d -print | grep -v CVS | xargs cvs add
find . -type f -print | grep -v CVS | grep -v -E "\.psd$|\.zip$|\.jar$|\.jpg$|\.gif$|\.png$" | xargs cvs add
find . -type f -print | grep -v CVS | grep -E "\.psd$|\.zip$|\.jar$|\.jpg$|\.gif$|\.png$" | xargs cvs add -kb
If you want an explanation of what’s going on up there, here it is: I’m using the find command to print out the file and directory names. That is passed to grep which uses the ‑v option to prune out any files/directories that I don’t want to process. Finally the xargs command is used to take all those files/directories and put them on the end of a cvs add command.
You can see on the first line I pass in the “-type d” parameter so that only the directories are piped to the next command. You want to do that because you can’t add a file until its containing directory has been added. In the second line, I’m using grep to kick out all the files with binary extensions and using a simple cvs add on them. In the last line, I“m only using the binary file and calling cvs add ‑kb on them.
Obviously, you would want to make sure you include all the binary file extensions you have in your particular source tree. I found the ones I needed by:
- Dumping all the file names into emacs.
- Running a regular expression search and replace to prune each line down to just it’s file extension.
- Using the Unix sort and uniq commands on the resulting file to get a list with a single copy of each extension type in my list.
Hope this can save you some time.