How to add CVS directories recursively

Viewed 70558

I've played with CVS a little bit and am not the most familiar with all of its capabilities, but a huge annoyance for me is trying to add new directories that contain more directories in them. Running "cvs add" only adds the contents of the current directory, and using "cvs import" didn't look like the right thing either since it's still all code I'm producing (this howto claimed import is for 3rd party sources)

Do you guys know any way to recursively add everything in a given directory to the current CVS project (or if SVN or git makes this notably easier)?

14 Answers

Ah, spaces. This will work with spaces:

find . -type f -print0| xargs -0 cvs add

cvs import is not just for 3rd-party sources. In fact, directories are not versioned by CVS, so they are not a subject to branch policies. As long as you import empty directories, it is fine.

Note that you can only use cvs add on files and folders that are located inside an already checked out working copy, otherwise you will get the "Cannot open CVS/Entries for reading" message. A technique for creating a new "root module" using cvs add is explained in this WinCVS FAQ item: http://cvsgui.sourceforge.net/newfaq.htm#add_rootmodule

If you are on Windows, both TortoiseCVS and WinCVS support recursive addition (and optional commit) of multiple files in a single operation. In WinCvs look for the macro Add>Recursive Add (auto-commit)... In Tortoise use the Add Contents command on a directory. Both will allow you to select which files to add and what keyword expansion modes to use for them (mostly used for defining which files are binary).

For further info about recursive add in WinCvs look here: http://cvsgui.sourceforge.net/newfaq.htm#cvs-add_recursive


Apart from that cvs import is well suited for mass-additions. However, the way cvs import is implemented in vanilla CVS has two drawbacks (because it was originally written for third-party code):

  • it creates a mandatory branch with special semantics.
  • it does not create the repository meta-data (i.e. the hidden CVS directories) needed to establish the imported code as a checked out working copy, which means that in order to actually work with the imported files you first have to check them out of the repository

If you are using CVSNT you can avoid both drawbacks by specifying the -nC option on import. -n is for avoiding the "vendor" branch and -C is for creating the CVS directories.

I think this is what I did back in my CVS days:

find . -type f | xargs cvs add

First add all directories to CVS

find . -type d -print0| xargs -0 cvs add

Then add all the files in the directories to CVS

find . -type f -print0| xargs -0 cvs add

I'm using this simple shell script, which should be started from an already checked-out CVS directory. It will stupidly try to add/commit any files and directories it finds upon its recursive search, so in the end you should end up with a fully commit tree.

Simply save this as something like /usr/bin/cvsadd and don't forget to chmod +x /usr/bin/cvsadd.

#!/bin/sh
# @(#) add files and directories recursively to the current CVS directory
# (c) 2009 by Dirk Jagdmann 

if [ -z "$1" ] ; then
    echo "usage: cvsadd 'import message'"
    exit 1
fi

if [ -d "$2" ] ; then
    cvs add "$2"
    cd "$2" || exit 1
fi

if [ ! -d CVS ] ; then
    echo "current directory needs to contain a CVS/ directory"
    exit 1
fi

XARGS="xargs -0 -r -t -L 1"

# first add all files in current directory
find . -maxdepth 1 -type f -print0 | $XARGS cvs add
find . -maxdepth 1 -type f -print0 | $XARGS cvs ci -m "$1"

# then add all directories
find . -maxdepth 1 -type d -not -name CVS -a -not -name . -print0 | $XARGS "$0" "$1"

Mark's solution resolves the spaces issue, but produces this issue:

cvs add: cannot open CVS/Entries for reading: No such file or directory
cvs [add aborted]: no repository

To fix it, the actual command to use is:

find . -type f -exec cvs add {} \;
Related