Is there a way to find an SVN revision by searching for a text string that got removed in the file? I know the exact text to search for and which file to look in, but there are hundreds of revisions.
-
Do you mean by the changes you made or by a text which is in the log message? You can use svn log URL/file so you get the list of revisions where this file has been changed. Using svn blame -rRevision:Revision URL/file will print out the line which have been changed in the revision and a grep (unix) on that would give the needed information... – khmarbaise Apr 29 '10 at 08:59
-
I meant the actual file changes, not the log messages. svn blame + grep was _almost_ good enough, but the change was deleting the text instead of adding it, so it didn't show up there. I've updated the question with clarifications; thanks khmarbaise. – martin_ljchan Apr 29 '10 at 09:16
-
1svn blame will display lines in both cases if you add a line or remove a line. If you use the way i suggested in my answer (svn blame -r Rev:Rev URL/file). – khmarbaise Apr 29 '10 at 09:25
-
1Actually, this shows the rev for when a line is added, but not the rev when it's removed (blame doesn't generate output for a deleted line). Your suggestion still helped, though - it turns out the text I was looking for has never been added to the file at all. oops : ) – martin_ljchan Apr 30 '10 at 06:25
5 Answers
Building on khmarbaise's script, I came up with this:
#!/bin/bash
file="$1"
REVISIONS=`svn log $file -q --stop-on-copy |grep "^r" | cut -d"r" -f2 | cut -d" " -f1`
for rev in $REVISIONS; do
prevRev=$(($rev-1))
difftext=`svn diff --old=$file@$prevRev --new=$file@$rev | tr -s " " | grep -v " -\ \- " | grep -e "$2"`
if [ -n "$difftext" ]; then
echo "$rev: $difftext"
fi
done
pass the file name and search string on the command line:
xyz.sh "filename" "text to search"
svn diff gives me both the rev where it's added and where it's deleted; I'll leave it here in case it's useful to anyone. There's an error message at the last revision that I don't know how to get rid of (I still got a lot of bash to learn :) ) but the rev numbers are correct.

- 1,063
- 1
- 9
- 22
-
This script work beautifully even for string/text that's added becuase it works on svn diff. Thank you for the script. – Jeevan Pingali Jan 30 '13 at 11:40
-
In `grep "^r" | cut -d"r" -f2 | cut -d" " -f1` you're using three processes; I would use something like `sed -ne '/^r/ { s/^r//; s/ .*//; p }'` instead. – musiphil Sep 11 '13 at 19:21
-
1I guess `tr -s " " | grep -v " -\ \- "` is no longer relevant as you migrated from `svn blame`, where it used to filter out *unchanged* lines. So your script will also print unchanged lines with the given word that are close enough to changed lines. You should really look for lines that begin with `-` or `+`, i.e. filter with `grep "^[-+]"`. – musiphil Sep 11 '13 at 20:23
just a little bash script which filters out the changed lines...If you change pom.xml into your file may with supplemental URL you have what you need...(If you are on Unix like system). Put the following into a script file (xyz.sh) and do a filter on the output.
#!/bin/bash
REVISIONS=`svn log pom.xml -q|grep "^r" | cut -d"r" -f2 | cut -d" " -f1`
for rev in $REVISIONS; do
svn blame -r$rev:$rev pom.xml | tr -s " " | grep -v " -\ \- "
done
xyz.sh | grep "Text you are searching for"
The printout will be something like:
256 ......
The 256 is the revision in which the change had been made.

- 92,914
- 28
- 189
- 235
I like blameall.py.
It's output for a file contains all existing and deleted lines so that I can see the deleted lines in the surrounding context.

- 1,212
- 1
- 9
- 19
Made a simple PHP version of the accepted answer to be run on the command line:
<?php
$file = $argv[1];
$searchfor = $argv[2];
if (!$file) die('Please specify file name to search through as the first argument.');
if (!$searchfor) die('Please specify text to search for as the second argument.');
echo PHP_EOL .'Searching '. $file .' for: '. $searchfor . PHP_EOL . PHP_EOL;
$cmd = 'svn log '. $file .' -q';
$output = array();
exec($cmd, $output);
// Find all revisions
$all_revisions = array();
foreach ($output as $line) {
if (preg_match("/^r(\\d+) /", $line, $match)) {
$all_revisions[] = $match[1];
}
}
echo 'Checking '. count($all_revisions) .' revisions...'. PHP_EOL . PHP_EOL;
// Get diff for each revision
foreach ($all_revisions as $keykey => $rev) {
$prev_rev = $all_revisions[$keykey+1];
$cmd = 'svn diff --old='. $file .'@'. $prev_rev .' --new='. $file .'@'. $rev;
$output = array();
exec($cmd, $output);
// Check if string is present
$str = implode(PHP_EOL, $output);
if (strpos($str, $searchfor) !== false) {
echo 'Found in revision '. $prev_rev .' but removed from '. $rev .'.'. PHP_EOL;
break;
} else {
echo 'Not found in revision '. $rev .'.'. PHP_EOL;
}
}
echo 'Done.'. PHP_EOL;
Run the script the script with the following command:
php scriptname.php "filetosearchthrough.php" "text to search for"
The script could be fine-tuned but does what you need. Keep in mind that it takes a long time to search through many revisions.

- 3,403
- 6
- 34
- 64
If you can't or you don't want to use scripts:
svn log --diff [path_to_file] > log.txt
(the [path_to_file] is optional, if you don't specify it, it will include all the files in the current folder and subfolders)
There you can find all added lines (they begin with +), all removed lines (they begin with -) and some context lines (they begin with a space). Modified lines will appear with the + and repeated with the -
You can process the resulting file with any decent text editor (e.g. Notepad++), grep, scripts or anything you like.
UPDATE:
In case the file was deleted and added again at some point of the history, you can do the following to search before that point:
- First find when the file was deleted:
- svn log -v [path-to-parent-folder] > logParent.txt
- search for "D [path-to-file]" in logParent.txt
- for earch revision found (let's call it [deleted-revision]) subtract 1: [prev-deleted-revision] = [deleted-revision]-1
- svn log --diff [path-to-file]@[prev-deleted-revision] > log.txt

- 1,360
- 13
- 32