Searching subversion history (full text)
Asked Answered
I

16

145

Is there a way to perform a full text search of a subversion repository, including all the history?

For example, I've written a feature that I used somewhere, but then it wasn't needed, so I svn rm'd the files, but now I need to find it again to use it for something else. The svn log probably says something like "removed unused stuff", and there's loads of checkins like that.

Edit 2016-04-15: Please note that what is asked here by the term "full text search", is to search the actual diffs of the commit history, and not filenames and/or commit messages. I'm pointing this out because the author's phrasing above does not reflect that very well - since in his example he might as well be only looking for a filename and/or commit message. Hence a lot of the svn log answers and comments.

Illicit answered 4/9, 2008 at 17:0 Comment(2)
Apache Subversion 1.8 accepts --search argument for svn log command. See my answer at https://mcmap.net/q/158584/-searching-subversion-history-full-textGeneric
svn log --search does not perform a full text search as required by @rjmunro, but only searches author, date, log message and list of changed paths.Shears
B
72
git svn clone <svn url>
git log -G<some regex>
Bugger answered 29/9, 2010 at 10:24 Comment(12)
Good point. The gitk GUI does this kind of search very well, and it's easy to use the git svn tools to access an svn repository. Admitedly, I've moved entirely to using git since the time I asked this question, so accepting this answer might be a bit specific to me.Illicit
If you want to just search the commit messages, use git log --grep regex.Zavras
Be advised, this can take a while depending on the size of your repository. For me it took more than an hour.Presume
More git grep examples in this answerGarganey
Does this really search through the whole history?Hanse
@rjmunro: A simple git grep < some regex > as given in the answer does not search the history at all. And thus this doesn't answer your question at all.Shears
@Shears Converting to git and searching with the gitk gui worked for me. I assumed this answer was the equivalent command line way to do it. Actually it looks like the equivalent command is git log -S (from this answer), but git log -G might be even better. I'm editing this answer.Illicit
I downvoted this solution since converting a big SVN repository to GIT is often not feasible or would take much too long. It's like recommending Java when having a question about a C# language construct.Pathos
You may need to install an additional package for this command. On Ubuntu, you want to apt-get install git-svn.Brennan
Doesn't "svn log --verbose --diff | grep ..." buy your roughly the same functionality without having to use git?Interknit
@Interknit It roughly is the same functionality. It is very good in so far you work with svn alone. I find this idea to utilize git to search for commits ridiculous. The trouble starts when you want to see more than just the line containing the term you searched for. grep can print a number of lines before the finding and after but you never know how many lines you need (to find the revision number at the top or the whole comment to the bottom). The output is hard to read.Presidium
This is searching with git, not searching with SVN as per the question. This is the equivalent of providing a Python script to answer a C question - it works, but it doesn't answer the original question.Protection
G
46

Update April, 2022

VisualSVN Server 5.0 comes with a new full-text search feature that allows you to search through the contents and history of your repositories in the web interface. Try out the feature on the demo server.


Old answer

svn log in Apache Subversion 1.8 supports a new --search option. So you can search Subversion repository history log messages without using 3'rd party tools and scripts.

svn log --search searches in author, date, log message text and list of changed paths.

See SVNBook | svn log command-line reference.

Generic answered 4/7, 2013 at 15:4 Comment(3)
Handy, but not full-text search. I'm sticking with the git-svn answer :-)Illicit
Not that at the moment svn repos on googlecode are still running on svn 1.6... see: code.google.com/p/support/wiki/…? But, updating your client to 1,8 (and svn upgrade of any checked out repo) will allow you to use svn log --search on the repo...Tsingyuan
The working copy needs all the updates but this command lists the whole change including revision number, changed files and comment. How is it not full-text?Presidium
K
24

If you are running Windows have a look at SvnQuery. It maintains a full text index of local or remote repositories. Every document ever committed to a repository gets indexed. You can do google-like queries from a simple web interface.

Kier answered 27/1, 2009 at 23:3 Comment(2)
It would be great if SvnQuery was still maintained but sadly it died and now it just doesn't work at all.Vinery
I found a working clone (?) at github.com/kalyptorisk/svnquery/releasesWinchell
N
22

I'm using a small shellscript, but this only works for a single file. You can ofcourse combine this with find to include more files.

#!/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

If you really want to search everything, use the svnadmin dump command and grep through that.

Nipissing answered 7/1, 2010 at 9:20 Comment(5)
I had to remove the "r" from revisions numbers with: awk '{print substr($1,2,length($1))}' and remove the grep "-q" option, to actually show the matches.Reeducate
strings myDump.txt | grep "turtle fwd 10"Sir
And this is why we embrace git.Zavras
might want to do last grep -i for ignore case and drop the -q to actually see the row that matchedWhatsoever
Saving the repository content with svnadmin dump and searching, worked for me.Saucedo
K
13

The best way that I've found to do this is with less:

svn log --verbose | less

Once less comes up with output, you can hit / to search, like VIM.

Edit:

According to the author, he wants to search more than just the messages and the file names. In which case you will be required to ghetto-hack it together with something like:

svn diff -r0:HEAD | less

You can also substitute grep or something else to do the searching for you. If you want to use this on a sub-directory of the repository, you will need to use svn log to discern the first revision in which that directory existed, and use that revision instead of 0.

Kinshasa answered 4/9, 2008 at 17:22 Comment(3)
That's not full text searching, it's searching the logs and filenames.Illicit
If that is the case, then you need to use more expressive commit logs. If you want to grep the difference between revisions, that is whole other ball of wax. And I personally do not know a way to do that.Kinshasa
> svn diff -r0:HEAD > log > less log is my choice on windows. ThanksBrickey
T
10
svn log -v [repository] > somefile.log

for diff you can use the --diff option

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

then use vim or nano or whatever you like using, and do a search for what you're looking for. You'll find it pretty quickly.

It's not a fancy script or anything automated. But it works.

Tonjatonjes answered 14/10, 2015 at 8:19 Comment(3)
AFAICS, That will search commit messages, not the actual diffs.Illicit
Then use svn log -v --diff [repository] > somefile.logTonjatonjes
or just pipe through grep as in zednight's answerPeccavi
S
9

I have been looking for something similar. The best I have come up with is OpenGrok. I have not tried to implement it yet, but sounds promising.

Soak answered 4/9, 2008 at 17:6 Comment(1)
I've been using OpenGrok for several months, it rocks.Liminal
W
6

While not free, you might take a look at Fisheye from Atlassian, the same folks that bring you JIRA. It does full text search against SVN with many other useful features.

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

Whallon answered 26/4, 2010 at 15:42 Comment(2)
Fisheye's pretty good. As you say, not free, but the <=10 committer license is only $10/year.Pictor
Currently, 5 users is $10, BUT at only 10 users it jumps to $1,000 !Infeld
C
5

I just ran into this problem and

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

did the job for me. Returned the revision of the first occurrence and quoted the line I was looking for.

Castilian answered 24/6, 2010 at 14:31 Comment(1)
Works only locally and will take a lot of time if a repository is large.Generic
I
4

I was looking for the same thing and found this:

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

Inequity answered 26/10, 2008 at 15:7 Comment(0)
L
4

Use unix utility like grep:

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

or you can save the result of the svn log somewhere, then search through it

Loehr answered 16/6, 2016 at 9:26 Comment(1)
add --diff to that to get text search of the changesPeccavi
W
2

I don't have any experience with it, but SupoSE (open source, written in Java) is a tool designed to do exactly this.

Wear answered 4/9, 2008 at 17:4 Comment(0)
O
1

I usually do what Jack M says (use svn log --verbose) but I pipe to grep instead of less.

Outworn answered 4/9, 2008 at 17:25 Comment(2)
That's not full text searching, it's searching the logs and filenames.Illicit
That is what I usually end up doing, but I've found that with less you can actually see the revision, date, etc instead of just the line in the comment. That is usually what I'm looking for anyway.Kinshasa
A
1

I wrote this as a cygwin bash script to solve this problem.

However it requires that the search term is currently within the filesystem file. For all the files that match the filesystem grep, an grep of all the svn diffs for that file are then performed. Not perfect, but should be good enough for most usage. Hope this helps.

/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 }'
Ajaajaccio answered 7/1, 2012 at 0:5 Comment(1)
'A' for effort! (just use git :))Zavras
F
-2

In case you are trying to determine which revision is responsible for a specific line of code, you are probably looking for:

svn blame

Credit: original answer

Fornicate answered 29/7, 2016 at 14:17 Comment(0)
B
-3

I came across this bash script, but I have not tried it.

Blackbeard answered 24/6, 2012 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.