Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a moderate size repository (around 2500 versions) from a project I've been running in the past 3 years. There is a particular file (let's call it foo.xml) there which I now want to analyse its evolution. Ideally, what I'm looking for, is to export into a directory every versions that file had, appended with the date, e.g.


What is the quickest way of achieving this?

share|improve this question
While this is not a direct answer to your question, you might want to use 'svn annotate filename'. That is a good way to study evolution. – vtest Jul 5 '10 at 10:09
up vote 4 down vote accepted

I don't think SVN has that functionality built in, but if you are able to run commands on the server that holds the SVN repository (and assuming the server has the standard UNIX/Linux tools available), this bash script should do it for you:

for rev in "$(svnlook history $REPOS $FILE | awk 'NR > 2 { print $1 }')"; do
    rev_date=$(svnlook date -r $rev $REPOS | awk '{ print $1 }')
    svnlook cat -r $rev $REPOS $FILE > ${rev_date}_${FILE}

This will produce filenames of the form 2007-08-08_foo.xml. Of course, you have to change /path/to/repos in the first line to the actual filesystem path (not a URL) of the repository, and dir/foo.xml in the second line to the path of the file within the repository.

If it's really important to you to have underscores in the date, change line 4 as follows:

    rev_date=$(svnlook date -r $rev $REPOS | awk '{ print $1 }' | tr - _)

Also keep in mind that if the file was ever modified more than once on a given day, only the first edit on each day will actually be reflected in the written files.

share|improve this answer

My coworker wrote this shell script for a similar purpose:

for rev in `svn log $1 | grep ^r[0-9] | cut -c 2- | cut -d ' ' -f 1`; do
    svn log -r $rev
    svn diff -r $[$rev-1]:$rev $1 2>/dev/null || svn cat -r $rev $1

You don't need server access to run it; run it in a directory where you have that file checked out and pass a filename as the argument. You may want to modify the loop body to write full files instead of printing diffs to stdout:

    svn cat -r $rev $1 > $1.$rev
share|improve this answer
Extracting dates for each revision and putting them into the filename is left as an excercise for the reader. – Marius Gedminas Jul 11 '10 at 13:44

I was having trouble with one of the scripts in this answer, it did not appear to work whenever there was a space in a filename. I am no master at bash scripting, but this is a quick solution.

echo "svn log \"$1\" | grep ^r[0-9] | cut -c 2- | cut -d ' ' -f 1"
for rev in `svn log "$1" | grep ^r[0-9] | cut -c 2- | cut -d ' ' -f 1`; do
    svn log -r $rev
    #svn diff -r $[$rev-1]:$rev $1 2>/dev/null || svn cat -r $rev $1
    `svn cat -r $rev "$1" > "$rev.$1"`
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .