[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Pre-commit hooks

From: Phil <plabonte_at_gmail.com>
Date: Fri, 21 Mar 2008 12:21:53 -0400

Rick,

This is my pre-commit hook script. It makes sure there is a lock. It has
been working great... I am not sure who helped me modify it but whoever it
was thanks again.
You may have to modify it to specify the location of of svnlook

Email me if you need help deploying it. You call this perl script, name it
whatever you want, from the pre-commit hook script that is preinstalled with
subverion.

Phil

#!/usr/bin/env perl

# ====================================================================
# ensure-needs-lock.pl: check that every added file has the
# svn:needs-lock property. If any file fails this test the user is
# sent a verbose error message suggesting solutions and the commit is
# aborted.
#
# Usage: ensure-needs-lock.pl REPOS TXN-NAME
# ====================================================================
# Most of ensure-needs-lock.pl was taken from
# check-mime-type.pl, Revision 12600, 2005-01-05 11:44:05 -0600.
# ====================================================================
# Copyright (c) 2000-2005 CollabNet. All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://subversion.tigris.org/license.html.
# If newer versions of this license are posted there, you may use a
# newer version instead, at your option.
#
# This software consists of voluntary contributions made by many
# individuals. For exact contribution history, see the revision
# history and logs, available at http://subversion.tigris.org/.
# ====================================================================

# 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;
use Carp;

######################################################################
# Configuration section.

# Svnlook path.
my $svnlook = "/usr/local/bin/svnlook";

# Since the path to svnlook depends upon the local installation
# preferences, check that the required program exists to insure that
# the administrator has set up the script properly.
{
  my $ok = 1;
  foreach my $program ($svnlook)
    {
      if (-e $program)
        {
          unless (-x $program)
            {
              warn "$0: required program `$program' is not executable, ",
                   "edit $0.\n";
              $ok = 0;
            }
        }
      else
        {
          warn "$0: required program `$program' does not exist, edit $0.\n";
          $ok = 0;
        }
    }
  exit 1 unless $ok;
}

######################################################################
# Initial setup/command-line handling.

&usage unless @ARGV == 2;

my $repos = shift;
my $txn = shift;

unless (-e $repos)
  {
    &usage("$0: repository directory `$repos' does not exist.");
  }
unless (-d $repos)
  {
    &usage("$0: repository directory `$repos' is not a directory.");
  }

# Define two constant subroutines to stand for read-only or read-write
# access to the repository.
sub ACCESS_READ_ONLY () { 'read-only' }
sub ACCESS_READ_WRITE () { 'read-write' }

######################################################################
# Harvest data using svnlook.

# Change into /tmp so that svnlook diff can create its .svnlook
# directory.
my $tmp_dir = '/tmp';
chdir($tmp_dir)
  or die "$0: cannot chdir `$tmp_dir': $!\n";

# Figure out what files have added using svnlook.
my @files_added;
foreach my $line (&read_from_process($svnlook, 'changed', $repos, '-t',
$txn))
  {
        # Add only files that were added to @files_added
    if ($line =~ /^A. (.*[^\/])$/)
      {
        push(@files_added, $1);
      }
  }

my @errors;
foreach my $path ( @files_added )
    {
        my $needs_lock;

        # Parse the complete list of property values of the file $path to
extract
        # the needs-lock property
        foreach my $prop (&read_from_process($svnlook, 'proplist', $repos,
'-t',
                          $txn, '--verbose', $path))
            {
                if ($prop =~ /^\s*svn:needs-lock : (\S+)/)
                    {
                        $needs_lock = $1;
                    }
            }

        # Detect error conditions and add them to @errors
        if (not $needs_lock)
            {
                push @errors, "$path : svn:needs-lock is not set";
            }
    }

# If there are any errors list the problem files and give information
# on how to avoid the problem. Hopefully people will set up auto-props
# and will not see this verbose message more than once.
if (@errors)
  {
    warn "$0:\n\n",
         join("\n", @errors), "\n\n",
                 <<EOS;

    Every added file must have the svn:needs-lock property set.

    If you need more help contact Admin.

EOS
    exit 1;
  }
else
  {
    exit 0;
  }

sub usage
{
  warn "@_\n" if @_;
  die "usage: $0 REPOS TXN-NAME\n";
}

sub safe_read_from_pipe
{
  unless (@_)
    {
      croak "$0: safe_read_from_pipe passed no arguments.\n";
    }
  print "Running @_\n";
  my $pid = open(SAFE_READ, '-|');
  unless (defined $pid)
    {
      die "$0: cannot fork: $!\n";
    }
  unless ($pid)
    {
      open(STDERR, ">&STDOUT")
        or die "$0: cannot dup STDOUT: $!\n";
      exec(@_)
        or die "$0: cannot exec `@_': $!\n";
    }
  my @output;
  while (<SAFE_READ>)
    {
      chomp;
      push(@output, $_);
    }
  close(SAFE_READ);
  my $result = $?;
  my $exit = $result >> 8;
  my $signal = $result & 127;
  my $cd = $result & 128 ? "with core dump" : "";
  if ($signal or $cd)
    {
      warn "$0: pipe from `@_' failed $cd: exit=$exit signal=$signal\n";
    }
  if (wantarray)
    {
      return ($result, @output);
    }
  else
    {
      return $result;
    }
}

sub read_from_process
  {
  unless (@_)
    {
      croak "$0: read_from_process passed no arguments.\n";
    }
  my ($status, @output) = &safe_read_from_pipe(@_);
  if ($status)
    {
      if (@output)
        {
          die "$0: `@_' failed with this output:\n", join("\n", @output),
"\n";
        }
      else
        {
          die "$0: `@_' failed with no output.\n";
        }
    }
  else
    {
      return @output;

On Fri, Mar 21, 2008 at 4:13 AM, Ryan Schmidt <
subversion-2008a_at_ryandesign.com> wrote:

> On Mar 20, 2008, at 11:07, DePriest Richard 403 wrote:
>
> > Ryan Schmidt wrote:
> >
> >> On Mar 19, 2008, at 16:58, DePriest Richard 403 wrote:
> >>
> >>> I have another question about pre-commit hooks. I have been
> >>> trying to
> >>> get a pre-commit hook to process and not let anyone commit a change
> >>> without having a lock on the modified file. When I test my hook the
> >>> commit fails everytime. If I remove the pre-commit hook the commit
> >>> will work fine. I just figured I have something not coded
> >>> correctly in
> >>> my hook or the perl scipt it calls.
> >>> After numerous tests, I have discovered a couple of things. It is
> >>> looking like th pre-commit hook is not executing correctly. The
> >>> reason
> >>> I say that is because I coded a pre-commit hook with only an exit 0
> >>> line. This hook causes the commit to fail. I am using the tortoise
> >>> GUI. Anybody out there got any ideas.
> >>
> >> Can't suggest anything unless you show us the code of the hook script
> >> itself...
> >
> >
> > Here is the pre-commit hook I am trying to use (just for testing).
> > This
> > is the text file. On the server the hook is named pre-commit and the
> > permissions are set to 777 (rwxrwxrwx)
> >
> > <pre-commit.txt>
>
>
> Your file just contains the single line "exit 0". You will need at
> least one more line before that indicating what program is supposed
> to execute it, e.g. "#!/bin/sh"
>
> Don't forget to Reply All so everyone gets your replies, not just me.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_subversion.tigris.org
> For additional commands, e-mail: users-help_at_subversion.tigris.org
>
>
Received on 2008-03-21 17:22:19 CET

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.