A couple weeks ago I ended up doing some digging around in CVS because of an issue a coworker was having with Eclipse (it turned out that he was running an older version of Eclipse under Windows, which was broken by our move to CVS 1.12.x, when he moved to Eclipse 3.0, his problems went away). In the process, I finally found the command that Eclipse was issuing to generate a top level listing of the CVS tree. I'd wanted this as a basic CVS command for quite some time.
The next day, Herb (another coworker) and I talked about it and he did some fiddling around. The result was his finding that the current directory needs a CVS directory (as all directories checked out from CVS normally have) containing both an Entries and Repository file, each with a blank line. Armed with that information, I eventually got around to creating a basic shell script to dump the top level CVS repository information and posted it internally on Sunday evening. When I mentioned it on Monday, Herb said he'd already seen it, and found a way to get a listing in any directory (in retrospect it was obvious both times, but I didn't see it).
I then passed it along to a couple other coworkers with a vested interest in CVS. Sudish wrote back at the end of the day with a fix for cygwin and shortly afterward, with a better way to deal with the output and perform a single pass against awk (I wasn't aware that you could do that).
The 1.0 script, can be downloaded here (the code is below). In general, directory names end in "/" and files don't; hardly unique, and a lot of people understand it.
#!/bin/sh
#
# Dave Ely, Herb Hrowal and Sudish Joseph
# Monday, August 9, 2004
#
# cvsDump [some/cvs/directory/]
#
if [ -z $CVSROOT ] ; then
echo "CVSROOT must be set."
exit 1
else
cvsDir="$1"
if [ ! -z $cvsDir ] ; then
if [ "/" = $cvsDir ] ; then
cvsDir=""
fi
fi
echo "CVS dump for $CVSROOT/$cvsDir"
tempDir=`mktemp -d /tmp/cvs-list-XXXXXXXXXXX` || exit 1
oldDir=`pwd`
cd $tempDir
mkdir CVS
echo > CVS/Entries
echo $cvsDir > CVS/Repository
echo
cvs -n update -d 2>&1 \
| awk '/^U/ { print $2 } \
/New directory/ { print substr( $5, 2, length( $5 )-2 ) "/" }' \
| sort
echo
cd "$oldDir"
rm -r $tempDir
fi
exit 0
As an example, here's a partial top level dump from cvs.apache.org...
dely@bigal $ cvsDump / CVS dump for :pserver:anoncvs@cvs.apache.org:/home/cvspublic/ CVSROOT/ ant-antidote/ ant/ apache-1.2/ apache-1.3/ apache-apr/ apache-devsite/ apache-nspr/ apache-search-site/ apache-site/ apmail/ apr-dist/ apr-iconv/ apr-prngd/ apr-site/ apr-util/ apr/ asf-site/ avalon-components/ avalon-excalibur/ avalon-logkit/ .. and so on ...
Followed by a dump of asf-site/ (also from cvs.apache.org).
dely@bigal $ cvsDump asf-site/ CVS dump for :pserver:anoncvs@cvs.apache.org:/home/cvspublic/asf-site/ .htaccess FAQ.html Y2K.html board/ bylaws.html committers.html conferences.html contact.html contributing.html credits.html docs/ donations.html hardware-notes.html images/ index.html left-cell.html mail-response.html mailinglists.html members-projects.html members.html news.html preFAQ.html press/ projects.html records/ svc-name-template.htmlPosted by Dave at August 10, 2004 01:26 AM