How to search cvs comment history
Asked Answered
L

7

8

I am aware of this command: cvs log -N -w<userid> -d"1 day ago"

Unfortunately this generates a formatted report with lots of newlines in it, such that the file-path, the file-version, and the comment-text are all on separate lines. Therefore it is difficult to scan it for all occurrences of comment text, (eg, grep), and correlate the matches to file/version.

(Note that the log output would be perfectly acceptable, if only cvs could perform the filtering natively.)

EDIT: Sample output. A block of text like this is reported for each repository file:


RCS file: /data/cvs/dps/build.xml,v
Working file: build.xml
head: 1.49
branch:
locks: strict
access list:
keyword substitution: kv
total revisions: 57;    selected revisions: 1
description:
----------------------------
revision 1.48
date: 2008/07/09 17:17:32;  author: noec;  state: Exp;  lines: +2 -2
Fixed src.jar references
----------------------------
revision 1.47
date: 2008/07/03 13:13:14;  author: noec;  state: Exp;  lines: +1 -1
Fixed common-src.jar reference.
=============================================================================
Leslee answered 23/9, 2008 at 0:6 Comment(0)
H
9

The -w options seems to work better with the -S option. Otherwise there are additional results which don't seem related to the userid. Perhaps someone can explain it.

cvs log -N -S -w<userid> -d"1 day ago"

With that I have been getting reasonable success piping it to grep:

cvs log -N -S -w<userid> -d"1 day ago" | grep -B14 "some text" > afile

I'm redirecting output to a file since the cvs log is noisy and I'm not sure how to make it quiet. I suppose an alternative is to redirect the stderr to /dev/null.

Horrorstruck answered 19/12, 2008 at 19:32 Comment(5)
That's awesome Steve. I wasn't aware of the -B grep option: "print NUM lines of leading context". So with the 15-line report that cvs log generates for each file (the comment being the 15th), -B14 gives me the whole block for each matching file.Leslee
Obviously this works best when the text you are searching for is in the first line, but its a start.Horrorstruck
by the way, cvs log -N -S -w -d"1 day ago" will look for entries older thatn 1 day ago by default. I think what you want is this -d">1 day ago"Horrorstruck
I also never understood why the -S option behaviour wasn't the default to begin with... and to think that that option was only added very late in the game...Startling
@Horrorstruck - I am not sure how -S makes -w "better". From the docs, -S removes the prevents the revisions from displaying, if they aren't explicitly specified. They are two separate, non-relational switches.Specie
B
4

You want cvsps - which will generate patchsets from CVS history. Then, you should only have one instance of your comment in the cvsps output, with the files listed neatly below it

Backbencher answered 17/11, 2009 at 22:55 Comment(0)
B
2

My first thoughts were to use egrep (or grep -E, I think) to search for multiple patterns such as:

<Cmd> | egrep 'Filename:|Version:|Comment:'

but then I realised you wanted to filter more intelligently.

To that end, I would use awk (or perl) to process the output line-by-line, setting an echo variable when you find a section of interest; pseudocode here:

# Assume the sections are of the format:
#   Filename: <filename>
#   Version:  <version>
#   Comment:  <comment>
#             <more comment>

Set echo to false
While more lines left
    Get line
    If line starts with "Filename: " and <filename> is of interest
        Set echo to true
    If line starts with "Filename: " and <filename> is not of interest
        Set echo to false
    If echo is true
        Output line
End while
Bombshell answered 23/9, 2008 at 0:25 Comment(1)
The tricky part of a post-processing solution is that the content-of-interest is in the later part of the text blocks. Therefore it would be necessary to buffer up each block, then discard or output it. I believe awk can do this, but it would probably involve a multi-day project for me.Leslee
M
1

Here is what I did - a simple Java script:

import java.io.IOException;


public class ParseCVSLog
{

    public static final String CVS_LOG_FILE_SEPARATOR = "=============================================================================";
    public static final String CVS_LOG_REVISION_SEPARATOR = "----------------------------";
    public static final String CVS_LOG_HEADER_FILE_NAME = "Working file";
    public static final String CVS_LOG_VERSION_PREFIX = "revision";

    public static void main(String[] args) throws IOException
    {
        String searchString = args[0];

        System.out.println( "SEARCHING FOR: " + searchString );

        StringBuffer cvsLogOutputBuffer = new StringBuffer();
        byte[] bytes = new byte[1024];
        int numBytesRead = 0;
        while( (numBytesRead = System.in.read( bytes )) > 0 )
        {
            String bytesString = new String(bytes, 0,  numBytesRead);
            cvsLogOutputBuffer.append( bytesString );
        }

        String cvsLogOutput = cvsLogOutputBuffer.toString();

        String newLine = System.getProperty("line.separator");
        String[] fileArray = cvsLogOutput.split( CVS_LOG_FILE_SEPARATOR );


        for ( String fileRecord : fileArray )
        {
            if ( !fileRecord.contains( searchString ) )
            {
                continue;
            }

            String[] revisionArray = fileRecord.split( CVS_LOG_REVISION_SEPARATOR );
            String[] fileHeaderLineArray = revisionArray[ 0 ].split( newLine );
            String fileName = "";
            for ( String fileHeadeLine : fileHeaderLineArray )
            {
                if ( fileHeadeLine.contains( CVS_LOG_HEADER_FILE_NAME ) )
                {
                    fileName = fileHeadeLine.split( ": " )[ 1 ];
                    break;
                }
            }
            System.out.print( fileName );
            for ( int i = 1; i < revisionArray.length; i++ )
            {
                String versionRecord = revisionArray[ i ];
                if ( !versionRecord.contains( searchString ) )
                {
                    continue;
                }
                String[] versionLineArray = versionRecord.split( newLine );
                for ( String versionLine : versionLineArray )
                {
                    if ( versionLine.contains( CVS_LOG_VERSION_PREFIX ) )
                    {
                        System.out.print( " " + versionLine.split( " " )[ 1 ] );
                    }
                }

            }
            System.out.println();
        }
    }
}

And here is how I used it:

cvs log -N -S -washamsut | java ParseCVSLog GS-242
Methodology answered 23/9, 2008 at 0:6 Comment(0)
U
1

This command and gawk script helps me to find only the filename, date and comment line of each log entry.

cvs log -N -S -b -w<userid> -d ">1 day ago" 2>/dev/null | gawk 'BEGIN{out=0;} /^Working file:/ { print $0; } /^date:/ { out=1; } /^===/ { print ""; out=0; } (out==1){print $0;}'
Uproar answered 17/12, 2015 at 16:5 Comment(0)
B
0

This might be way overkill, but you could use git-cvsimport to import the CVS history to a Git repository and search it using Git's tools. Not only can you search for text within commit messages, but you can also search for code that has ever been added or removed from files in your repository.

Bola answered 23/9, 2008 at 0:17 Comment(0)
G
0

CVSSearch might help, but it's a CGI application :'(

Gentle answered 23/9, 2008 at 0:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.