如何搜索整个 CVS 存储库(所有分支/历史记录/评论)?

发布于 2024-08-03 02:24:00 字数 199 浏览 5 评论 0原文

如果我想基本上 grep 存储库中的每一行,有没有办法做到这一点?我知道对于大型项目来说这需要很长时间。

如果不是全部包括在内,至少只是当前分支及其整个源历史记录?

编辑:我应该更明确。 如果我无法直接访问 CVS 存储库所在的服务器怎么办?因此我无法直接 grep 具有 CVS 存储库的文件系统。

If I want to essentially grep every line ever in the repository, is there a way to do it? I know this would take a long time for large projects.

If not all inclusive, at least just the current branch and its entire source history?

Edit: I should have been more explicit. What if I don't have direct access to the server that the CVS repository is on? So I couldn't directly grep the filesystem that has the CVS repository.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

稀香 2024-08-10 02:24:00

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

There is no way to do this with standard CVS tools without access to the repository. A third party tool out there may do it (I don't know of one, although CS-CVS seems to claim to), but to do it programatically, you would have to do CVS logs on all the relevant files, and then retrieve and search each version reported by cvs in the logs (cvs log is a command line option in CVS that shows you the revision history of any file, but it doesn't show you the contents).

遗弃M 2024-08-10 02:24:00

这是我最近在无法访问服务器的情况下使用的。那个时候好像有用了。从工作副本内部调用它,并在 PATH 中使用 cvs。请注意,这不会搜索提交消息,但您可以简单地 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.="e_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 "."e_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";

Here's what I recently used, in a case where I didn't have access to the server. It seemed to work that time. Call it from inside a working copy, with cvs in the PATH. Note that this doesn't search commit messages, but you can simply grep 'cvs log' for that.

#!/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.="e_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 "."e_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";
计㈡愣 2024-08-10 02:24:00

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

如果您要查找包含这些单词的特定版本,那么您将必须从存储库中提取版本,这是昂贵的。但是,如果您可以通过 grep 存储库来限制文件集,那么情况还不错。

It depends on what you're looking for. CVS version files contain all of the edits that have ever happened to the file, in plaintext. So if you're simply looking for all files that contain a particular word, do a recursive grep on the repository.

If you're looking to find specific versions that contain those words, then you're going to have to extract the versions from the repository, which is expensive. However, if you can limit the set of files by grepping the repository, then it's not so bad.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文