#!/usr/bin/env perl # # This file is Copyright (C) 2005 Thiago Macieira # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # ===================================================================== # This is a replacement for the old svnlastchange script, with a bit # more of functionality. # # The old one was: # svn log -r COMMITTED "$*" # svn diff -r PREV:COMMITTED "$*" || \ # echo >&2 "Error retrieving diff: the file was probably added in the last revision" # # ===================================================================== # Turn on warnings the best way depending on the Perl version. BEGIN { if ( $] >= 5.006_000) { require warnings; import warnings; } else { $^W = 1; } } use strict; # # Read the parameters # my @files; my $rev; my $special = 0; my $onlyrev = 0; my $onlylog = 0; while (@ARGV) { my $arg = shift @ARGV; if ($arg eq '-h') { &usage; exit 0; } elsif ($arg =~ /^-r(.*)$/) { $rev = $1; if (length($1) == 0) { $rev = shift @ARGV; } $special = 1 if ($rev =~ /^-/); } elsif ($arg eq '-R') { $onlyrev = 1; $special = 1; $rev = -1 unless $rev; } elsif ($arg eq '-l') { $onlylog = 1; } else { push(@files, $arg); } } @files = ('.') unless @files; if (!$special) { my $prev; if ($rev) { $prev = $rev - 1; } else { $rev = 'COMMITTED'; $prev = 'PREV'; } system('svn', 'log', '-r', $rev, @files); system('svn', 'diff', '-r', "$prev:$rev", @files) unless $onlylog; exit $?; } # # Special operation # Retrieve the full log in order to find the right version # foreach my $file (@files) { my $pid = open(LOG, '-|'); die "svnlastchange: cannot fork: $!\n" unless (defined $pid); unless ($pid) { open(STDERR, ">&STDOUT") or die "svnlastchange: cannot dup STDOUT: $!\n"; exec('svn', 'log', $file) or die "svnlastchange: cannot exec svn: $!\n"; } my $is_header = 0; while () { s/[\r\n]+$//; if ($is_header && /^r(\d+) \| /) { $rev = $rev + 1; if ($rev == 0) { if ($onlyrev) { print "$1\n"; } else { system('svn', 'log', '-r', $1, $file); system('svn', 'diff', '-r', ($1 - 1) . ":$1", $file) unless $onlylog; } last; } } if ($_ eq '------------------------------------------------------------------------') { $is_header = 1; } else { $is_header = 0; } } close(LOG); exit $? if $?; } sub usage { print "svnlastchange [-hlR] [-r rev] [filename...]\n"; print "\n"; print "Where:\n"; print " -h shows this help screen\n"; print " -l shows the commit log only\n"; print " -R prints the revision number only (to be used with -r)\n"; print " -r rev shows the commit log for revision 'rev'\n"; print " if rev is negative, the 'rev'nth revision before the current\n"; print " one is shown\n"; print "\n"; print "Examples:\n"; print " svnlastchange . shows the last change to the current directory\n"; print " svnlastchange -r -2 shows the change before the last\n"; print " svnlastchange -R -r -1 shows the last change's revision\n"; exit 0; }