如何搜索CVS注释历史记录

8

我知道这个命令:

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

不幸的是,它生成了一个格式化的报告,其中有很多换行符,因此文件路径、文件版本和注释文本都在不同的行上。因此,很难扫描所有注释文本的出现情况(例如grep),并将匹配项与文件/版本相关联。

(请注意,如果cvs可以本地执行过滤操作,则日志输出将是完全可接受的。)

编辑:样本输出。每个存储库文件都会报告类似于此的文本块:

RCS文件:/data/cvs/dps/build.xml,v
工作文件:build.xml
head:1.49
branch:
锁定:严格
访问列表:
关键字替换:kv
总修订次数:57;选择的修订次数:1
描述:
----------------------------
修订版1.48
日期:2008/07/09 17:17:32;作者:noec;状态:Exp;行:+2 -2
修复src.jar引用
----------------------------
修订版1.47
日期:2008/07/03 13:13:14;作者:noec;状态:Exp;行:+1 -1
修复common-src.jar引用。
=============================================================================
7个回答

9
-w选项似乎与-S选项更加兼容。否则会出现一些与用户ID无关的额外结果。也许有人可以解释一下。
cvs log -N -S -w<userid> -d"1 day ago"

我一直在使用管道将其传输到grep,并取得了不错的成功:

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

由于cvs日志很嘈杂,我希望将输出重定向到文件中,但我不确定如何使其静音。我想另一种选择是将stderr重定向到/dev/null


1
太棒了,史蒂夫。我不知道-B grep选项:“打印NUM行前导上下文”。因此,对于cvs log为每个文件生成的15行报告(注释为第15行),-B14会为每个匹配文件给我整个块。 - Chris Noe
显然,当你要搜索的文本在第一行时,这是最有效的方法,但这只是一个开始。 - s_t_e_v_e
1
顺便说一下,cvs log -N -S -w -d“1 day ago”默认会查找早于1天前的条目。我认为你想要的是这个-d“>1 day ago”。 - s_t_e_v_e
1
我也从来没有理解为什么 -S 选项的行为不是默认的...而且想想那个选项只是在游戏很晚的时候才被添加的... - Oliver Giesen
@s_t_e_v_e - 我不确定 -S 如何使 -w “更好”。从文档中可以看出,-S 会移除未明确指定的修订版本,而不会显示它们。它们是两个独立的、非关联的开关。 - user66001

4
您需要 cvsps - 它可以从CVS历史记录生成补丁集。然后,在cvsps输出中,您应该只有一个实例的评论,并在其下面整洁地列出文件。

2

我的第一反应是使用egrep(或grep -E,我想)搜索多个模式,例如:

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

但后来我意识到你想要更智能地过滤。
为此,我会使用awk(或perl)逐行处理输出,并在找到感兴趣的部分时设置一个echo变量;伪代码如下:
# 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

后处理解决方案的棘手之处在于感兴趣的内容在文本块的后部分。因此,需要缓存每个块,然后丢弃或输出它。我相信awk可以做到这一点,但这可能需要我花费几天时间来完成。 - Chris Noe

1

这个命令和gawk脚本可以帮助我找到每个日志条目的文件名、日期和评论行。

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;}'

1
这是我所做的 - 一个简单的Java脚本:
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();
        }
    }
}

这是我如何使用它的方法:

cvs log -N -S -washamsut | java ParseCVSLog GS-242

0
这可能有点过头了,但你可以使用git-cvsimport将CVS历史导入到Git存储库中,并使用Git的工具进行搜索。你不仅可以搜索提交消息中的文本,还可以搜索已添加或删除的代码,以及存储库中文件的任何更改。

0

CVSSearch可能会有所帮助,但它是一个CGI应用程序 :'(


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接