3

リポジトリ内のすべての行を基本的にgrepしたい場合、それを行う方法はありますか?大規模なプロジェクトでは、これには長い時間がかかることを私は知っています。

すべてを網羅しているわけではないにしても、少なくとも現在のブランチとそのソース履歴全体だけですか?

編集:私はもっと明確にすべきだった。CVSリポジトリが存在するサーバーに直接アクセスできない場合はどうなりますか?そのため、CVSリポジトリを持つファイルシステムを直接grepすることはできませんでした。

4

3 に答える 3

1

リポジトリにアクセスせずに、標準のCVSツールでこれを行う方法はありません。そこにあるサードパーティのツールがそれを行うかもしれませんが(CS-CVSが主張しているようですが、私はそれを知りません)、プログラムでそれを行うには、関連するすべてのファイルに対してCVSログを実行してから取得する必要がありますそして、ログでcvsによって報告された各バージョンを検索します(cvs logは、ファイルのリビジョン履歴を表示するCVSのコマンドラインオプションですが、内容は表示されません)。

于 2009-08-27T21:29:05.453 に答える
1

サーバーにアクセスできなかった場合に、最近使用したものを次に示します。その時はうまくいったようです。PATHにcvsを入れて、作業コピーの中から呼び出します。これはコミットメッセージを検索しないことに注意してください、しかしあなたは単にそれのために'cvslog'をgrepすることができます。

#!/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";
于 2012-11-01T00:23:06.620 に答える
0

それはあなたが探しているものに依存します。CVSバージョンのファイルには、ファイルに対してこれまでに行われたすべての編集がプレーンテキストで含まれています。したがって、特定の単語を含むすべてのファイルを単に探している場合は、リポジトリで再帰的なgrepを実行します。

それらの単語を含む特定のバージョンを探している場合は、リポジトリからバージョンを抽出する必要がありますが、これはコストがかかります。ただし、リポジトリをgrepすることでファイルのセットを制限できる場合は、それほど悪くはありません。

于 2009-08-27T18:50:05.633 に答える