140

有没有办法对颠覆存储库执行全文搜索,包括所有历史记录?

例如,我编写了一个我在某处使用过的功能,但后来不需要它,所以我 svn rm'd 文件,但现在我需要再次找到它以将其用于其他用途。svn 日志可能会说“删除未使用的东西”之类的东西,并且有很多这样的签入。

编辑 2016-04-15:请注意,此处“全文搜索”一词所要求的是搜索提交历史记录的实际差异,而不是文件名和/或提交消息。我指出这一点是因为作者上面的措辞并没有很好地反映这一点——因为在他的例子中,他可能只是在寻找文件名和/或提交消息。因此有很多svn log答案和评论。

4

16 回答 16

76
git svn clone <svn url>
git log -G<some regex>
于 2010-09-29T10:24:53.823 回答
42

svn log在 Apache Subversion 1.8 中支持一个新--search选项。因此,您可以搜索 Subversion 存储库历史日志消息,而无需使用 3'rd 方工具和脚本。

svn log --search搜索作者、日期、日志消息文本和更改路径列表。

SVNBook | svn log命令行参考

于 2013-07-04T15:04:44.723 回答
24

如果您正在运行 Windows,请查看SvnQuery。它维护本地或远程存储库的全文索引。曾经提交到存储库的每个文档都会被编入索引。您可以从一个简单的 Web 界面进行类似 google 的查询。

于 2009-01-27T23:03:23.387 回答
21

我正在使用一个小的 shellscript,但这仅适用于单个文件。您当然可以将其与 find 结合使用以包含更多文件。

#!/bin/bash
for REV in `svn log $1 | grep ^r[0-9] | awk '{print $1}'`; do 
  svn cat $1 -r $REV | grep -q $2
  if [ $? -eq 0 ]; then 
    echo "$REV"
  fi 
done

如果您真的想搜索所有内容,请使用svnadmin dump命令并通过 grep 搜索。

于 2010-01-07T09:20:58.807 回答
12

我发现做到这一点的最好方法是少用:

svn 日志 --verbose | 较少的

一旦少了输出,你可以点击/搜索,比如 VIM。

编辑:

据作者说,他想搜索的不仅仅是消息和文件名。在这种情况下,您将需要将其与以下内容一起进行 ghetto-hack:

svn diff -r0:HEAD | less

您也可以替代grep或其他东西来为您进行搜索。如果您想在存储库的子目录中使用它,您需要使用svn log来识别该目录存在的第一个修订版,并使用该修订版而不是0.

于 2008-09-04T17:22:35.593 回答
10
svn log -v [repository] > somefile.log

对于差异,您可以使用该--diff选项

svn log -v --diff [repository] > somefile.log

然后使用 vim 或 nano 或任何你喜欢使用的东西,并搜索你正在寻找的东西。你会很快找到它。

这不是一个花哨的脚本或任何自动化的东西。但它有效。

于 2015-10-14T08:19:45.503 回答
9

我一直在寻找类似的东西。我想出的最好的是OpenGrok。我还没有尝试实现它,但听起来很有希望。

于 2008-09-04T17:06:56.380 回答
6

虽然不是免费的,但您可以看看来自 Atlassian 的 Fisheye,他们就是为您带来 JIRA 的人。它使用许多其他有用的功能对 SVN 进行全文搜索。

http://www.atlassian.com/software/fisheye/

于 2010-04-26T15:42:13.050 回答
5

我刚刚遇到了这个问题

svnadmin dump <repo location> |grep -i <search term>

为我完成了这项工作。返回第一次出现的修订并引用了我正在寻找的行。

于 2010-06-24T14:31:17.463 回答
4

我一直在寻找同样的东西,发现了这个:

http://svn-search.sourceforge.net/

于 2008-10-26T15:07:01.507 回答
3

svn log -l<commit limit> | grep -C<5 or more lines> <search message>

于 2016-06-16T09:26:17.657 回答
2

我对此没有任何经验,但SupoSE(开源,用 Java 编写)是一个专门为此而设计的工具。

于 2008-09-04T17:04:53.280 回答
1

我通常按​​照Jack M所说的去做(使用 svn log --verbose),但我通过管道传递给grep而不是更少。

于 2008-09-04T17:25:45.367 回答
1

我把它写成一个 cygwin bash 脚本来解决这个问题。

但是,它要求搜索词当前位于文件系统文件中。对于与文件系统 grep 匹配的所有文件,然后执行该文件的所有 svn 差异的 grep。不完美,但对于大多数用途来说应该足够好。希望这可以帮助。

/usr/local/bin/svngrep

#!/bin/bash
# Usage: svngrep $regex @grep_args

regex="$@"
pattern=`echo $regex | perl -p -e 's/--?\S+//g; s/^\\s+//;'` # strip --args
if [[ ! $regex ]]; then
    echo "Usage: svngrep \$regex @grep_args"
else 
    for file in `grep -irl --no-messages --exclude=\*.tmp --exclude=\.svn $regex ./`;     do 
        revs="`svnrevisions $file`";
        for rev in $revs; do
            diff=`svn diff $file -r$[rev-1]:$rev \
                 --diff-cmd /usr/bin/diff -x "-Ew -U5 --strip-trailing-cr" 2> /dev/null`
            context=`echo "$diff" \
                 | grep -i --color=none   -U5 "^\(+\|-\).*$pattern" \
                 | grep -i --color=always -U5             $pattern  \
                 | grep -v '^+++\|^---\|^===\|^Index: ' \
                 `
            if [[ $context ]]; then
                info=`echo "$diff" | grep '^+++\|^---'`
                log=`svn log $file -r$rev`
                #author=`svn info -r$rev | awk '/Last Changed Author:/ { print $4 }'`; 

                echo "========================================================================"
                echo "========================================================================"
                echo "$log"
                echo "$info"
                echo "$context"
                echo
            fi;
        done;
    done;
fi

/usr/local/bin/svnrevisions

#!/bin/sh
# Usage:  svnrevisions $file
# Output: list of fully numeric svn revisions (without the r), one per line

file="$@"
    svn log "$file" 2> /dev/null | awk '/^r[[:digit:]]+ \|/ { sub(/^r/,"",$1); print  $1 }'
于 2012-01-07T00:05:21.413 回答
-2

如果您试图确定哪个版本负责特定的代码行,您可能正在寻找:

svn blame

信用:原始答案

于 2016-07-29T14:17:45.140 回答
-3

我遇到了这个bash 脚本,但我还没有尝试过。

于 2012-06-24T11:34:54.433 回答