如果我想搜索代码库中的每一行代码,有没有方法可以做到?我知道对于大型项目来说这可能需要很长时间。
如果不是全部包含,至少可以搜索当前分支及其整个源代码历史记录吗?
编辑:我应该更清楚地表达。如果我没有直接访问CVS存储库的服务器怎么办?因此,我不能直接搜索包含CVS存储库的文件系统。
如果不是全部包含,至少可以搜索当前分支及其整个源代码历史记录吗?
编辑:我应该更清楚地表达。如果我没有直接访问CVS存储库的服务器怎么办?因此,我不能直接搜索包含CVS存储库的文件系统。
这是我最近在没有服务器访问权限的情况下使用的方法。那时它似乎起作用了。从工作副本中调用它,确保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.="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";
如果没有访问存储库的权限,使用标准CVS工具无法完成此操作。可能有第三方工具可以实现(我不知道是否有这样的工具,尽管CS-CVS似乎声称可以),但要以编程方式实现,您需要对所有相关文件执行CVS日志记录,然后检索和搜索cvs在日志中报告的每个版本(cvs log是CVS中的一个命令行选项,它显示任何文件的修订历史记录,但不显示内容)。
这取决于你要找什么。CVS版本文件包含了文件的所有编辑历史,以纯文本形式呈现。因此,如果你只是想查找包含特定单词的所有文件,请在存储库上进行递归grep。
如果你想找到包含这些单词的特定版本,则需要从存储库中提取版本,这是比较耗费资源的。但是,如果你可以通过在存储库上进行grep来限制文件集合,则不会那么麻烦。