【问题标题】:How do I search all revisions of a file in a SubVersion repository?如何在 SubVersion 存储库中搜索文件的所有修订版?
【发布时间】:2010-11-10 05:21:08
【问题描述】:

我想grep 字符串的文件的所有修订。例如查找添加或删除功能的时间。

有没有“简单”的方法来做到这一点? (即单个 bash 命令行会很好。)通过检查修订和单独测试来进行手动二进制搜索似乎太乏味且容易出错。

如果我足够聪明,可以通过有用的描述提交更改,那么我可以grep 使用类似以下内容的日志:

svn log myfile.c | grep my_func

虽然这并没有提供修订号,所以我怀疑还有更好的方法来做到这一点。

【问题讨论】:

    标签: svn


    【解决方案1】:

    我写了一个脚本来做这件事

    典型用法:

    perl searchrev.pl Import.php setImportStatus
    
    ----------------------------------------------------------------------
    r19565 | johnf | 2009-06-24 14:33:00 +0100 (Wed, 24 Jun 2009) | 1 line
    ----------------------------------------------------------------------
    line 60 $this->setImportStatus($entity_id, $entity_attr_id);
    ---------------------------------------------------------------------
    r13722 | john | 2008-03-10 17:06:14 +0000 (Mon, 10 Mar 2008) | 1 line
    ---------------------------------------------------------------------
    line 70 $this->setImportStatus($entity_id, $entity_attr_id);
    ---------------------------------------------------------------------
    r11692 | paul | 2007-05-23 10:55:45 +0100 (Wed, 23 May 2007) | 1 line
    ---------------------------------------------------------------------
    Not found
    ---------------------------------------------------------------------
    r11691 | paul | 2007-05-23 10:36:26 +0100 (Wed, 23 May 2007) | 1 line
    ---------------------------------------------------------------------
    Not found
    ---------------------------------------------------------------------
    r11683 | paul | 2007-05-23 09:04:29 +0100 (Wed, 23 May 2007) | 1 line
    ---------------------------------------------------------------------
    Not found
    

    这是脚本,很容易为自己的目的破解

    #!/usr/bin/perl -w
    
    my $file=$ARGV[0];
    my $pattern=$ARGV[1];
    
    my @history=`svn log "$file"`;
    foreach (@history)
    {
        chomp;
        if (m/^r(\d+)/)
        {
            my $revision=$1;
            my $sep='-' x length($_);
    
            print "$sep\n$_\n$sep\n";
    
            my @code=`svn cat -r $revision "$file"`;
            my $lineno=0;
            my $found=0;
            foreach my $line (@code)
            {
                $lineno++;
                if ($line=~m/$pattern/)
                {
                    $line=~s/^\s+//;
                    print "line $lineno $line";
                     $found=1;
                }
            }
    
            print "Not found\n" unless ($found);
        }
    }
    

    【讨论】:

    • 如何从当前版本开始,然后只在差异中查找?
    • 几天内第二次,搜索让我想到了几年前我问过的一个 SO 问题!再次感谢您的回答:)
    • 如果你没有安装perl,这里只使用egrepgist.github.com/lapo-luchini/8666153
    • 非常棒的脚本,非常感谢!我们为 MacProgrammingWorkshop 提供了一个类似且非常常用的功能(MPW - 古老的!),这个工具可能很好地表明“这个新的 svn 东西”毕竟不是那么糟糕......
    • 我发现这个脚本非常有用,并用--until-found --until-lost 扩展了它(在最高匹配/不匹配的版本处停止)--diff(显示找到的最低版本和以前的差异,如果停止--until-*) 和--firstline(仅显示修订中的第一个匹配行)。
    【解决方案2】:

    "annotate/blame" command 并不完全符合您的要求,但它可以提供帮助:

    svn blame — 显示指定文件或 URL 的内嵌作者和修订信息。

     $ svn blame http://svn.red-bean.com/repos/test/readme.txt
     3      sally This is a README file.
     5      harry You should read this.
    

    因此,您应该能够找出谁添加了功能。至于找出谁删除了功能,不知道。

    【讨论】:

      【解决方案3】:

      这是一个搜索包含字符串的文件的修订版本的命令:

      svn log -l 30 -q FILENAME | grep ^r | cut -d ' ' -f 1 | while read rev; do
          svn cat -$rev FILENAME | grep -c PATTERN && svn info FILENAME@$rev
      done
      

      【讨论】:

        【解决方案4】:

        使用 Subversion 1.6 服务器及其mod_dav_svn,您可以通过 GET 参数指定修订号:

        http://host/repos/path?r=20
        

        因此,您可以轻松地wget 您的所有修订文件,然后diff 它们。

        来源:SVN 1.6 changelog

        【讨论】:

          【解决方案5】:

          你想做的第一件事会很困难。我通常建议使用 svn diff 或 svn cat,但是(据我所知)没有办法将修订号与代码输出内联。

          关于第二个问题,如果你正在寻找一个特定的用户,你可以使用

          svn log | grep -A 2 username
          

          这将在每个匹配的行之后给你额外的两行(-A =“之后”)。如果你没有很长的日志消息,你可以使用

          svn log | grep -B 2 search_string
          

          这将在 (-B) 每个匹配的行之前类似地打印两行。 (希望这足以为您提供修订号。)我绝对确定 AWK 有更好的方法可以根据日志消息为您提供修订号,但我累了,我想不出现在。 :D

          【讨论】:

            【解决方案6】:

            据我所知,这并不容易。我会编写一个小脚本来检索相关文件的每个变更集,然后通过 grep 查找字符串的差异。然后就像打印当前的修订号一样简单:)

            【讨论】:

              【解决方案7】:

              您可以使用pySVN + python diff tools 来执行此操作,虽然它不是 bash,但如果您更经常地使用此功能可能值得考虑。它是wget solution 的一个版本,但界面会更好,如果你构建它的话:)

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2012-09-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-04-24
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多