Git Hook Pre-Receive Command Throwing Error

Issue #753 open
Michael Vacirca created an issue

We are running on the latest SCM-Manager version 1.46 and attempting to use a perl script pre-receive command to check commit messages. However, we get a failure message and we continue to get the failure message even with the most basic perl script in place.

Likewise, we get the same error when using Ruby, or Bash.

We are running Windows 7 64-bit, we have msysgit 1.95 installed, and Java 8 update 51.

2015-07-28 17:55:31.462 [qtp25376898-21] ERROR sonia.scm.web.GitFileHook - failu
re during file hook execution
java.io.IOException: Cannot run program "C:\scm\repositories\git\VMT\hooks\pre-r
eceive" (in directory "C:\scm\repositories\git\VMT"): CreateProcess error=193, %
1 is not a valid Win32 application
at java.lang.ProcessBuilder.start(Unknown Source) ~[na:1.8.0_51]
at sonia.scm.web.GitFileHook.createProcess(GitFileHook.java:142) [scm-gi
t-plugin-1.35.jar:na]
at sonia.scm.web.GitFileHook.execute(GitFileHook.java:216) [scm-git-plug
in-1.35.jar:na]
at sonia.scm.web.GitFileHook.execute(GitFileHook.java:197) [scm-git-plug
in-1.35.jar:na]
at sonia.scm.web.GitFileHook.execute(GitFileHook.java:117) [scm-git-plug
in-1.35.jar:na]

Comments (6)

  1. Sebastian Sdorra repo owner
    • changed status to open

    It looks like windows does not know how to execute the file. Do you use cygwin or something similar?

  2. Michael Vacirca reporter

    I do not use cygwin. We have ActivePerl, and Ruby installed and they are accessible from both msysgit's git bash shell and windows command prompt. I was assuming that the git bash shell is kicked off to execute scripts? Is this not the case? What is the proper procedure here to have scm-manager call the git pre-receive hook without a file name extension associated with it? I'm at a loss.

  3. Michael Vacirca reporter

    I don't believe it is, as you are causing windows to try to fine a file type association. Since we don't have one as thereis no file type extension, it dies unable to know what process to call.

    I wonder if we can wrap a batch script to call the correct script.

  4. Michael Vacirca reporter

    Didn't work.... I tried to call a perl command from a batch formatted script, and it failed to execute with the same error.

    Pre-Receive

    @ECHO OFF
    
    perl pre-receive.pl
    set errors=%errorlevel%
    
    if NOT %errors% == 0 (
     echo You do not follow the convention for commit messsages which requires you to start all commits with your JIRA Task ID followed by a colon. [eg. FM-001: or FFSA-001:]
    )
    

    Pre-Receive.pl

    use warnings;
    use strict;
    
    my $errors = 0;
    while (<>) {
      chomp;
      next unless my($old,$new) =
        m[ ^ ([0-9a-f]+) \s+   # old SHA-1
             ([0-9a-f]+) \s+   # new SHA-1
             refs/heads/master # ref
           \s* $ ]x;
    
      chomp(my @commits = `git rev-list $old..$new`);
      if ($?) {
        warn "git rev-list $old..$new failed\n";
        ++$errors, next;
      }
    
      foreach my $sha1 (@commits) {
        my $msg = `git cat-file commit $sha1`;
        if ($?) {
          warn "git cat-file commit $sha1 failed";
          ++$errors, next;
        }
    
        $msg =~ s/\A.+? ^$ \s+//smx;
        unless ($msg =~ /\[\d+\]/) {
          warn "No bug number in $sha1:\n\n" . $msg . "\n";
          ++$errors, next;
        }
      }
    }
    
    exit $errors == 0 ? 0 : 1;
    
  5. Ian Day

    Ran into the same issue. Ended up patching the source so it would run on Windows Server.

    Changes to GitFileHook.java:

      private Process createProcess(File hook) throws IOException
      {
        ProcessBuilder pb;
        if (SystemUtils.IS_OS_WINDOWS)
        {
          //We can't directly run a non-extensioned bash script from Windows because it doesn't look at the file contents
          //like OSX/Linux do, and instead only works on the extension. post-receive and pre-receive do not have an extension
          //So we must give it a helping hand and point it to sh.exe
          //Git (and therefore sh.exe) must be in the path
    
          //Additionally, passing a Windows path (ie: E:\git) to a bash script that expects things in Unix form can fail
          //horribly too, in my case, the auto generated pre-receive and post-receive from subgit will end up with something
          //badly malformed, such as: /e/git/repo.git/hooks/E:\git\repo.git
          //So, create a Unix-like relative path based on the base repository folder and the hook filename
          //Since the ProcessBuilder will run in the repo folder (see comment #99 below) this should be all we need
    
          //We also need to cater for cases where directory links are used. Such as when you create a local subgit mirror
          //of an svn repo, the .git folder has to live in a subfolder of the SVN repo, and subgit expects to find the
          //svn repo in the parent folder, so we'll use the path of the link instead of the hook path itself.
          //So we use getCanonicalPath instead of getAbsolutePath
    
          File path = new File(hook.getCanonicalPath());
          File base = new File(rpack.getRepository().getDirectory().getCanonicalPath());
          String relative = base.toURI().relativize(path.toURI()).getPath();
    
          logger.debug("Converted " + hook.getAbsolutePath() + " to " + relative);
          logger.debug("Running sh.exe " + relative);
          pb = new ProcessBuilder("sh.exe", relative);        
    
          // use repostitory directory as working directory for file hooks
          // see issue #99
          pb.directory(base);
        }
        else
        {
          pb = new ProcessBuilder(hook.getAbsolutePath());
    
          // use repostitory directory as working directory for file hooks
          // see issue #99
          pb.directory(rpack.getRepository().getDirectory());
        }
    
        // copy system environment for hook
        pb.environment().putAll(System.getenv());
    
        // start process
        return pb.redirectErrorStream(true).start();
      }
    

    Feel free to use it :)

  6. Log in to comment