davidlt
davidlt

Reputation: 1007

How to get CVS/* files without checking out the actual files?

My scripts depends on CVS/* files, but does not require actually having all the files. Would it be possible just to get CVS/* files without actually checking out all files from the repository? Checkout of all the files costs a lot of time.

Upvotes: 1

Views: 1322

Answers (2)

Burhan Ali
Burhan Ali

Reputation: 2229

currently it only does comparison between two Entries files from different tags and output XML/JSON or human readable information with the difference between tags: deleted, new, revision down, revision up. – davidlt

There are a few problems with your approach. You already know about the first: needing to check out the tags, even though you don't care about the actual files.

Another problem is that the CVS/* files are local and can be edited and/or corrupted. Also if you do a partial checkout, the Entries file will only contain the content you checked out rather than everything associated with teh tag. This file therefore can't be guaranteed as a source of "truth".

If you are just after what files have changed, you can use the rdiff -s option.

The rdiff options documentation says:

-s

Create a summary change report instead of a patch. The summary includes information about files that were changed or added between the releases. It is sent to the standard output device. This is useful for finding out, for example, which files have changed between two dates or revisions.

The documentation also contains this example:

Suppose you have made release 1.3, and forked a branch called R_1_3fix for bug fixes. R_1_3_1 corresponds to release 1.3.1, which was made some time ago. Now, you want to see how much development has been done on the branch. This command can be used:

$ cvs patch -s -r R_1_3_1 -r R_1_3fix module-name
cvs rdiff: Diffing module-name
File ChangeLog,v changed from revision 1.52.2.5 to 1.52.2.6
File foo.c,v changed from revision 1.52.2.3 to 1.52.2.4
File bar.h,v changed from revision 1.29.2.1 to 1.2

I ran it myself and here is what the new and deleted messages look like:

cvs rdiff -s -r v5_8_0_1 -r v5_8_0_2 <module>

File abc is new; v5_8_0_2 revision 1.1.2.2
File xyz is removed; v5_8_0_1 revision 1.1.4.1

EDIT:

You don't specify what platform you are on, but the non-uniform output from the cvs command could certainly be passed through a cleansing command to make it easier to manage. eg. The following awk would turn it into CSV output with only the four pieces of information you are interested in.

cvs rdiff -s -r <tag1> -r <tag2> <module> | awk '
    / new; /     { print "NEW, \"" $2 "\", , " $7 }
    /changed /   { print "CHANGED, \"" $2 "\", " $6 ", " $8 }
    / removed; / { print "REMOVED, \"" $2 "\", " $7 ", " }
'

Upvotes: 1

Keith Thompson
Keith Thompson

Reputation: 263247

You mean these files:

CVS/Entries
CVS/Repository
CVS/Root
CVS/Tag

This is a partial solution:

cvs ... checkout -D 1970-01-01 ...

This checks out the most recent revisions no later than January 1, 1970, of which there are almost certainly none.

But it only checks out the top-level directory. If you want to recursively get all subdirectories, things get a little tricky. The key is that cvs checkout prints out the names of the subdirectories on stderr even though it doesn't create them.

So this shell script seems to do the trick (replace the ...s with whatever you need):

#!/bin/bash

export CVSROOT=...
module=...

for dir in $(cvs checkout -D 1970-01-01 $module 2>&1 | sed 's/.* //')
do
    cvs checkout -D 1970-01-01 $dir
done

I'm not entirely happy with this solution, since it's based on observed behavior, not on documented behavior. It's also likely to break if any module or directory name contains whitespace.

EDIT : As Clare Macrae points out in a comment, this creates nearly empty CVS/Entries files (the contain entries only for directories), so this might not suit your purposes.

There may not be a way to do what you want. CVS is freeware; you might be able to hack the sources.

Upvotes: 0

Related Questions