Question

We are in the process of moving to SVN.

Unfortunately for us, we are audited periodically, where the auditors require information like:
Histories of changes to files
History of access to SVN
New files Added
Changes in files

Is there a tool which can produce these reports for us (or some of these)?

Was it helpful?

Solution

StatSVN is a light weight subversion report generator. http://www.statsvn.org/

  1. first generate the verbose log file - svn log

  2. run StatSVN , it is a single jar file.

StatSVN provides a list of metrics:

  • which file is changed the most
  • how many lines are added
  • who is contributing more

OTHER TIPS

Trac (http://trac.edgewall.com) can be used to view the SVN details. Trac has nice features like a changeset view that allows to see different changesets (and go back or forth through them). It also presents a nice UI , much better than ViewVC(www.viewvc.org)

svn log is the basic command to get the file related information you're looking for...

You can have all of that information just through the SVN revision logs. You might want to consider a nice tool like Fisheye to do it for you though.

SVN provides much of what you ask for right from the command line:

  • History of changes to a specific file/directory: svn log /your/path gives you source code diffs, authors, check-in dates etc.
  • New files added: svnlook changed -r <rev> <path to repository> gives you all files which were touched in the given revision. Loop over all relevant revisions, and grep for "A" which denotes added files.
  • Changes in files: svn diff -r <first rev>:<last rev> <path> gives you a diff of for the entire span of revisions
  • History of access to SVN: SVN obviously maintains a log of all check-ins (see svn log). As for reading access, I don't know of a builtin mechanism, however you can probably create your own with little effort, depending on the configuration. If you only allow http access, you can use the webserver's log files.

It's not pretty, but SVN's output is highly structured so you can do your own formatting easily.

Here are some that I have used before to give a glance at change activity reporting and trends. The filtering isn't perfect, but you can get the idea:

set REPO_URL=svn://localhost/...
set REVISION_START=1
set REVISION_END=HEAD 
set COMMAND=svn log %REPO_URL% -v -g -r %REVISION_START%:%REVISION_END% 
set REG_EXPRESSION="^...[ACDIMRX].\/"

Affected Configuration Items:

%COMMAND% | find /c "/"

Changesets:

%COMMAND% | find /c "Changed paths"

List of unique files that have been affected over the given revision range (I had cygwin installed):

%COMMAND% | findstr /r %REG_EXPRESSION% | sort | uniq -u

Take a look at codesaga. It makes a good job of visualizing source control commits. I can't vouch for the reporting part.

This program might help you out, not with audits, but updates

http://www.svnmonitor.com/default.shtml

  • Monitor the source for certain events
  • Receive notifications of any kind (balloon popups, tray icons, email, sounds, ...) when certain events occur

To see actual accesses to SVN, you'd need to parse the Apache server logs (assuming you're serving SVN over Apache).

This question is also a bit old, but I've crafted a script that may be useful for simple reporting/auditing of Subversion and to keep track of the changes made to a SVN repository and I wanted to share it. It extracts information about SVN commits in a similar way to the command "svnlook" but it has a pair of advantages. First, it allows to iterate over all revisions of a repository to keep track of all the changes made. Second, the information is printed in a tab-separated tabular format (as in Unix commands like ps or df) that is both human readable and easy to parse or to import into a spreadsheet, which is great for reporting. It can also be called or embedded in a SVN post-commit hook.

It is a Perl script called svn-commit-info.pl and takes three arguments. The first is the repository path and it is mandatory. The second, optional, is the file pattern to search. And the third, also optional, is the revision number to query.

If executed only with the repository path, it prints to STDOUT information about the files affected by all the commits made in the repository. For example, assuming the repository is stored in /svn/repos/test in the Subversion server:

$ perl svn-commit-info.pl /svn/repos/test
# Repository: /svn/repos/test
# Fields: Action, Revision, Date, Author, Bytes, Path
# Actions: A = New, D = Deleted, U = Updated
A    1     2017-01-31 17:21:19     Samsa     <DIR>    TestProject/
A    2     2017-01-31 17:21:33     Samsa       815    TestProject/.project
A    2     2017-01-31 17:21:33     Samsa     <DIR>    TestProject/.settings/
A    2     2017-01-31 17:21:33     Samsa       564    TestProject/.settings/.jsdtscope
A    2     2017-01-31 17:21:33     Samsa     <DIR>    TestProject/www/
A    3     2017-01-31 17:27:48     David       355    TestProject/www/test.html
A    3     2017-01-31 17:27:48     David     <DIR>    TestProject/www/css/
A    3     2017-01-31 17:27:48     David      9622    TestProject/www/css/logo.jpg
A    3     2017-01-31 17:27:48     David      1231    TestProject/www/css/reportstyle.css
A    3     2017-01-31 17:27:48     David    168345    TestProject/www/css/style.css
U    4     2017-02-01 10:48:34     Samsa    183260    TestProject/www/css/style.css
D    5     2017-02-01 12:51:26     David       355    TestProject/www/test.html            

The tab-separated fields are: the operation performed, the revision number, the date and time, the author of the revision, the file size in bytes (unless the file is a directory marked by the string "<DIR>") and the path of the affected file in the repository. The first three lines contain human oriented comments about the output.

The output of the former command can take a long time to complete if the repository is big, with many files or revisions. If you want to keep track of the changes made to a particular file (or a set of files), it is better to specify the file pattern (that, in fact, is a Perl regexp). For example, to get information about the changes made to the file style.css:

$ perl svn-commit-info.pl /svn/repos/test style.css

If you are interested in a particular revision, you can specify the third parameter. For example to print all the changes of the third revision, taking into account that '.' matches any character in a Perl regular expression:

$ perl svn-commit-info.pl /svn/repos/test . 3

And of course you could harness the power of Unix filters and pipelining to do more complex queries, for example to find all the modifications made by user David:

$ svn-commit-info.pl /svn/repos/test | grep David

To find all the files created with size >= 1Mb:

$ svn-commit-info.pl /svn/repos/test | awk '$1 = "A" && $6 ~ /[0-9]/ && $6 >= 1024*1024'

The script uses the standard Subversion command "svnlook" but otherwise it is self contained. There are two helper functions to build the command and get the output of "svnlook" and then mades successive calls to the command to compose the output. It requires Subversion >= 1.7 and it has been tested on Perl 5.10.

#!/usr/bin/env perl
use strict; 

my $SVNLOOKCMD = "/usr/bin/svnlook";
my @FIELDS = qw(Action Revision Date Author Bytes Path);

# Builds and returns the "svnlook" command
sub svnlook_cmd {
   my($repository, $action, $revision, @varargs) = @_;
   my $cmd = $SVNLOOKCMD;
   $cmd.= " -r $revision" if $revision;
   $cmd.= " $action '$repository'";
   $cmd.= join "", map { " '$_'" } @varargs;
   $cmd.= '|';
   return $cmd;
}

# Executes the "svnlook" command and returns the output lines
sub svnlook_output {
   my($repository, $action, $revision, @varargs) = @_;
   open(my $svnlookfh, svnlook_cmd $repository, $action, $revision, @varargs);
   my @output = <$svnlookfh>;
   close $svnlookfh;
   chomp @output;
   return wantarray ? @output : $output[0];
}

my($repository, $file, $revision) = @ARGV;
unless($repository) {
    # 'repository' is the only mandatory argument
    print STDERR "$0 <repository> [<file>] [<revision>]\n";
    print STDERR "\t<repository> = path of Subversion repository\n";
    print STDERR "\t<file> = file pattern to search for (regular expression)\n";
    print STDERR "\t<revision> = commit revision number\n";
    exit 1;
}
$file = "." unless $file;
my $first = $revision ? $revision : 1;
my $last = $revision ? $revision : svnlook_output $repository, "youngest";
print "# Repository: $repository\n";
print "# Fields: ", join(", ", @FIELDS), "\n";
print "# Actions: A = New, D = Deleted, U = Updated\n";
for(my $rev = $first; $rev <= $last; $rev++) {
    my $author = "";
    my $date = "";
    foreach my $line (svnlook_output $repository, "changed", $rev) {
        if($line =~ /$file/i) {
            unless($date) {
                $date = svnlook_output $repository, "date", $rev;
                $date =~ s|^(\S+) (\S+).*$|\1 \2|;
            }
            $author = uc svnlook_output $repository, "author", $rev unless $author;
            my($action, $path) = split /\s+/, $line, 2;
            my $size;
            if($path =~ m|/$|) {
                $size = sprintf("%12s", "<DIR>");
            } else {
                $size = svnlook_output $repository, "filesize", $rev, $path;
                $size = sprintf("%12d", $size);
            }
            print join("\t", $action, $rev, $date, $author, $size, $path), "\n";
        }
    }
}
exit 0;

Hope this helps and sorry for the long post.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top