Tom
Tom

Reputation: 44543

How do I search all revisions of a file in a SubVersion repository?

I'd like to grep all revisions of a file for a string. e.g. to find when a function was added or removed.

Is there a "simple" way to do this? (i.e. a single bash command line would be nice.) Doing a manual binary search by checking out revisions and testing individually seems too tedious and error prone.

If I was smart enough to commit the change with a useful description then I can grep the log with something like:

svn log myfile.c | grep my_func

This doesn't provide a revision number though, so I suspect there's a better way to do that too.

Upvotes: 35

Views: 12560

Answers (7)

Paul Dixon
Paul Dixon

Reputation: 300825

I wrote a script to do it

TYpical usage:

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

Here's the script, easy to hack for your own purposes

#!/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);
    }
}

Upvotes: 36

the brx in the walls
the brx in the walls

Reputation: 187

This is a command to search for revisions of a file containing a string:

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

Upvotes: 4

Andrew Cox
Andrew Cox

Reputation: 10988

You could use the pySVN + the python diff tools to do this, while it is not bash, it maybe worth considering if you use this function on a more regular basis. It is a version of the wget solution but would have a nicer interface, well if you build it :)

Upvotes: 0

guerda
guerda

Reputation: 24049

With a Subversion 1.6 server and its mod_dav_svn you can specify the revision number via a GET parameter:

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

So you can easily wget your files in all revisions and then diff them.

Source: SVN 1.6 changelog

Upvotes: 3

bluebrother
bluebrother

Reputation: 8886

As far as I know that's not easily possible. I'd write a small script that retrieves each changeset for the file in question and then grep through the diff for the string. Then it's as simple as printing the current revision number :)

Upvotes: 0

Thilo
Thilo

Reputation: 262494

The "annotate/blame" command does not do exactly what you want, but it could help:

svn blame — Show author and revision information in-line for the specified files or URLs.

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

So, you should be able to find out who added a function. As for finding out who deleted a function, no idea.

Upvotes: 7

Zachary Murray
Zachary Murray

Reputation: 1220

The first thing that you want to do will be difficult. I would normally suggest using svn diff or svn cat, but there is (as far as I know) no way to get the revision number inline with the code output.

On the second question, if you're looking for a specific user, you can use

svn log | grep -A 2 username

which will give you two extra lines after every matched line (-A = "after"). If you don't have very long log messages, you can use

svn log | grep -B 2 search_string

which will similarly print two lines before (-B) each matched line. (Which should hopefully be enough to give you the revision number.) I am absolutely certain that there is a better way with AWK to give you the revision numbers in line with the log messages, but I'm tired and I can't think of it right now. :D

Upvotes: 1

Related Questions