如何搜索整个CVS代码库(所有分支/历史记录/注释)?

3
如果我想搜索代码库中的每一行代码,有没有方法可以做到?我知道对于大型项目来说这可能需要很长时间。
如果不是全部包含,至少可以搜索当前分支及其整个源代码历史记录吗?
编辑:我应该更清楚地表达。如果我没有直接访问CVS存储库的服务器怎么办?因此,我不能直接搜索包含CVS存储库的文件系统。

没有访问存储库是一个相当大的遗漏,你不觉得吗?但是,除非您使用pserver,或者您的IT部门已经采取了极端措施,否则您可能确实可以访问存储库 - 只是没有方便的访问方式。请编辑您的问题并添加CVS / Root文件的内容(您可以在工作树中的任何目录中找到它)。如果您不希望其他人了解有关您的网络的任何信息,请将任何主机名引用替换为foo.example.com,并在需要时替换目录名称。但不要更改其他任何内容。 - kdgregory
抱歉,我不知道标准的CVS设置是什么。我已经使用Subversion很长时间了,上一次使用CVS已经超过8年了。我正在使用pserver。我尝试在主机上进行ssh连接,但没有成功。我会询问如何设置一个账户,因为这似乎是最好的方法。 - Keith Bentrup
3个回答

1

这是我最近在没有服务器访问权限的情况下使用的方法。那时它似乎起作用了。从工作副本中调用它,确保cvs在PATH中。请注意,这不会搜索提交消息,但您可以通过简单地grep 'cvs log'来实现。

#!/usr/bin/perl

# Searches CVS diffs and first revisions behind the current working
# directory for an expression (perlre syntax).

# Synopsis: cvsgrep [-n] <search-expression> [<file_1> ... <file_n>]

# -n means that contents of matching files should not be printed to stdout.

use Getopt::Std;

my %options=();
getopts("n",\%options);
my $no_content_dump=$options{"n"};

my $search_term=shift
    or die "Error: usage is: cvsgrep [-n] <search-expression>".
    " [<file_1> ... <file_n>]";

sub quote_fn
{
    my $fn=shift;
    $fn =~ s/\'/\'\"\'\"\'/g;
    "'".$fn."'";
}

my $args_str;
while(@ARGV)
{
    my $arg=shift;
    $args_str.=' ' if $args_str;
    $args_str.=&quote_fn($arg);
}

print 
    "Searching for term: $search_term",
    ($args_str?" in: $args_str":""),
    "\n";

open CVSLOGH,"cvs log -N $args_str|" or die "Cannot execute cvs log: $!";

my @files_revisions=();

my $cur_file;
my $cur_revision;

while(<CVSLOGH>)
{
    chop;
    if(/^Working file\:\s*(.*)$/)
    {
        $cur_file=$1;
        $cur_revision='';
    }
    elsif(/^revision\s+(.*)$/)
    {
        $cur_revision=$1;
    }
    elsif((/^\=\=\=\=/ || /^\-\-\-\-/) && $cur_revision)
    {
        push @files_revisions,{file=>$cur_file,rev=>$cur_revision};
    }
}

close CVSLOGH;

my $matchcount=0;
my $count=0;
my $progress_msg="Scanned %d out of %d commit(s)\r";
my $erase_ln=(" " x (length($progress_msg)+20)) . "\r";

foreach my $file_revision(@files_revisions)
{
    printf($progress_msg,$count++,scalar(@files_revisions));

    my($file,$rev) = ($file_revision->{file},$file_revision->{rev});

    $rev =~ /^(.*\.)([0-9]+)/;
    my $revbase=$1;
    my $revlastdigit=$2;
    my $rev1=$revbase.($revlastdigit - 1);
    my $diffcommand = "cvs diff -N -r $rev1 -r $rev ".&quote_fn($file);
    open CVSDIFFH,"$diffcommand|" or die "Cannot execute cvs diff: $!";

    my $diffresult;
    while(<CVSDIFFH>)
    {
        if(/^[\<\>]/)
        {
            s/^.//;
            $diffresult.=$_;
        }
    }
    close CVSDIFFH;

    if($diffresult =~ /$search_term/s)
    {
        print "${erase_ln}FOUND: in diff for $file $rev1:$rev\n";
        $matchcount++;
        system($diffcommand) unless $no_content_dump;
    }
}

print "${erase_ln}Done ($matchcount match(es)).\n";

1

如果没有访问存储库的权限,使用标准CVS工具无法完成此操作。可能有第三方工具可以实现(我不知道是否有这样的工具,尽管CS-CVS似乎声称可以),但要以编程方式实现,您需要对所有相关文件执行CVS日志记录,然后检索和搜索cvs在日志中报告的每个版本(cvs log是CVS中的一个命令行选项,它显示任何文件的修订历史记录,但不显示内容)。


0

这取决于你要找什么。CVS版本文件包含了文件的所有编辑历史,以纯文本形式呈现。因此,如果你只是想查找包含特定单词的所有文件,请在存储库上进行递归grep。

如果你想找到包含这些单词的特定版本,则需要从存储库中提取版本,这是比较耗费资源的。但是,如果你可以通过在存储库上进行grep来限制文件集合,则不会那么麻烦。


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