14 July 2014

svn-find: Which version did we do that in?


The following is a bash script which works with svn (subversion) to allow you to look at one particular file, and find the revision in which a certain text first (or last) appears in it.

It is in the form of a bash function: running the code below will cause the function to become available in your current environment, so that you can call it later with the command "svn-find".

You need to provide either two or three parameters: 
  1. the relative path to and name of the file you want to search, 
  2. the text you want to search for, 
  3. and optionally the URL to the repository.
For example:

svn-find path/to/file searchtext

if you are in a subversion working directory, or

svn-find path/to/file searchtext https://url.of/repository

if you want to use it on repostories for which you don't have a current working directory open on your machine.

The output of the command will be (if successful) the log outputs from two adjacent revisions of the file -- one of which contains the search text, and one which does not.

For example, if the file in question contained the search text right up to and including version XXXX, but from then on (starting with version YYYY) did not contain that text, then the output will be something like:

rXXXX has 'this is the text'
 
------------------------------------------------------------------------
rXXXX | developer | 2012-08-01 15:21:32 +0100 (Wed, 01 Aug 2012) | 1 line

Log entry of last revision containing text
------------------------------------------------------------------------

===============================================
rYYYY does not

------------------------------------------------------------------------
rYYYY | developer-who-removed-it | 2012-09-15 01:05:14 +0100 (Sat, 15 Sep 2012) | 1 line

Log entry which might indicate why it was removed
------------------------------------------------------------------------


Conversely, if the current up-to-date verion of the file does contain the search text, then svn-find will search back to show you the revision in which the text first appeared, followed by the revision immediately preceding it, i.e. the last revision which did not contain the text.

If not successful, svn-find may report instead either that the text is found in every single revision of the file, or that it does not appear in any of them.


Note that the current implementation will only find the most recent transition between the existence/non-existence of the search text. If you have a certain string that you keep adding to a file and then in later revisions removing from it, and then later adding back in and so forth, you should feel free to adapt the script so that it doesn't stop searching as soon as it finds the first transition.

 
The script begins below this line of ======================

function svn-find()
{
    local file="$1"
    local text="$2"
    local url="$3"
    local y
    local n
    local r

    if ! svn info $url &> /dev/null
    then
        if [ "$url" != "" ]
        then
            echo "Sorry, $url is not under version control"
        else
            echo "Sorry, this directory is not under version control"
        fi
        return 1
    fi

    if [ "$url" != "" ]
    then
        local url=$url/
    fi

    for r in $(svn log -q $url $file | awk '/r[0-9]+ /{print $1}')
    do
        if svn cat -$r $url$file | grep -q "$text"
        then
            y=$r
            if [ "$n" != "" ]
            then
                echo "$y has '$text'"
                echo
                svn log $url -$y
                echo
                echo "==============================================="
                echo
                  echo "$n does not"
                echo
                svn log $url -$n
                echo
                  return
            fi
        else
            n=$r
            if [ "$y" != "" ]
            then
                echo "$y has '$text'"
                echo
                svn log $url -$y
                echo
                echo "==============================================="
                echo
                  echo "$n does not"
                echo
                svn log $url -$n
                echo
                  return
            fi
        fi
    done

    if [ "$y" != "" ]
    then
        echo "All revisions have '$text'"
    else
        echo "No revision has '$text'"
    fi
}

No comments: