You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Rainer Sokoll <R....@intershop.de> on 2007/08/02 12:14:44 UTC

svn diff with svn:externals

Hi,

one of my users wrote this script - he wants to stay anonymous, but
agreed to share it with you :-)

example call: perl svnviewlog.pl diff --summarize -r1:1000 http://svn.example.com/foo/bar
---------[cut here]------
#! /usr/bin/perl
#
#  svnviewlog.pl  --  Utility script for viewing svn log on svn:externals
#
# This script shows svn log from your location or URL.
# It will additionally search for svn:externals and show there svn log as well
#
# written by Thomas S., 9 July 2007
# svn is available at the path
# svncopy.pl was used as basis

use Cwd;
use Getopt::Long;
use strict;


# Specify thom global variables
my $svn = 'svn';
my @svn_options = ();
my $verbose = 0;
my @arguments = @ARGV;
my $work_dir = pop @arguments;
my %extlist;
 
# Check the workingdir
info( "Checking '$work_dir'\n" );
my ( $status, @diff ) = SVNCall( "@arguments", $work_dir );       
foreach my $line ( @diff ) {
	print "$line";
}
#now get externals
%extlist = GetRecursiveExternals( $work_dir );

# And diff externals
while ( my ( $subdir, $exts ) = each ( %extlist ) )
{
	my @externals = @$exts;
	if ( scalar( @externals ) ) {
		DiffExternals( \@arguments, \@externals );
	}
}


#------------------------------------------------------------------------------
# Function:    GetRecursiveExternals
#
# This function retrieves the svn:externals value from the
# specified URL or location and subdirectories.
#
# Parameters:
#       location      location of SVN object - file/dir or URL.
#
# Returns:     hash
#------------------------------------------------------------------------------
sub GetRecursiveExternals
{
  my ( $location ) = @_;
  my %retval;
  my $externals;
  my $subdir = ".";
    
  my ( $status, @externals ) = SVNCall( "propget", "-R", "svn:externals", $location );
    
  foreach my $external ( @externals )
    {
      chomp( $external );

      if ( $external =~ m"(.*) - (.*\s.*)" )
        {
          $subdir = $1;
          $external = $2;
        }

      push( @{$retval{$subdir}}, $external ) unless $external =~ m"^\s*$";
    }

  return %retval;
}




#------------------------------------------------------------------------------
# Function:    SVNCall
#
# Makes a call to subversion.
#
# Parameters:
#       command     Subversion command
#       options     Other options to pass to Subversion
#
# Returns:     exit status, output from command
#------------------------------------------------------------------------------
sub SVNCall
{
  my ( $command, @options ) = @_;

  my @commandline = ( $svn, $command, @svn_options, @options );

  info( " > ", join( " ", @commandline ), "\n" );
  
  my @output = qx( @commandline 2>&1 );
      
  my $result = $?;
  my $exit   = $result >> 8;
  my $signal = $result & 127;
  my $cd     = $result & 128 ? "with core dump" : "";
  if ($signal or $cd)
    {
      error( "$0: 'svn $command' failed $cd: exit=$exit signal=$signal\n" );
    }
  
  if ( $exit > 0 )
    {
      info( join( "\n", @output ) );
    }
  if ( wantarray )
    {
      return ( $exit, @output );
    }
    
  return $exit;
}


#------------------------------------------------------------------------------
# Function:    DiffExternals
#
# DiffExternals( $work_dir, $subdir, \@externals );
#
# Parameters:
#       sourceref   Ref to the URLs to copy from
#       destination The URL being copied to
#       work_dir    The working directory
#       externals   Ref to the externals on the directory
#       msgref      Ref to message string to update with changes
#
# Returns:     1 on success
#------------------------------------------------------------------------------
sub DiffExternals
{
  my ( $optionsref, $externalsref ) = @_;
  my @externals = @$externalsref;
    
  # view diff for all external
  foreach my $external ( @externals ) {
		chomp( $external );
		next unless ( $external =~ m"^(\S+)(\s+)(?:-r\s*(\d+)\s+)?(.*)" );
		my ( $ext_dir, $spacing, $ext_rev, $ext_val ) = ( $1, $2, $3, $4 );
			
		info( " - Found $ext_dir => '$ext_val'" );
		info( " ($ext_rev)" ) if $ext_rev;
		info( "\n" );

		my ( $status, @diff ) = SVNCall( "@arguments", $ext_val );       
		foreach my $line ( @diff ) {
			print "$line";
		}
    }
}


#------------------------------------------------------------------------------
# Function:    info
#
# Prints out an informational message in verbose mode
#
# Parameters:
#       @_     The message(s) to print
#
# Returns:     none
#------------------------------------------------------------------------------
sub info
{
  if ( $verbose )
    {
      print @_;
    }
}
---------[cut here]------

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org