2014-06-26 14 views
0

我想使用node.js腳本作爲我的git鉤子腳本。目前我正在使用連接到msysgit Git-1.9.0-preview20140217便攜式安裝的Bonobo Git HTTP服務在我的Windows機器上進行實驗。它工作正常,用copuple pulls和push進行測試。如何獲取windows上的msysgit來調用hook中的node.js腳本?

我有nodejs啓動並運行,但我的git update腳本失敗,沒有任何明確的理由。它絕對有效 - 只要將它添加到服務器上的hooks文件夾中,就會始終拒絕推送,但SourceTree輸出日誌中沒有任何線索。

這裏是我的更新腳本:

#!C:/nodejs/node.exe 

console.log('Hello world!'); 
console.log('Hello world 2!'); 

我試過反斜槓,我試過雙斜槓,我想引用路徑 - 沒有結果。

服務器響應如下:

git -c diff.mnemonicprefix=false -c core.quotepath=false push -v --tags origin master:master 
Pushing to http://myurl.git 

POST git-receive-pack (4686 bytes) 

remote: error: hook declined to update refs/heads/master[K 

To http://myurl.git 
! [remote rejected] master -> master (hook declined) 

error: failed to push some refs to 'http://myurl.git' 


Completed with errors, see above. 

P.S.我不知道​​從哪裏來,我的主人是它的換行符被破壞了。

回答

0

我最終使用了類似的方法找到了一個我發現有人用於Python的方法。

我創建了一個C#控制檯應用程序如下:

using System; 
using System.Diagnostics; 
using System.IO; 

namespace GitNodeRunner 
{ 
    class Program 
    { 
     static int Main(string[] args) 
     { 
      if (args == null || args.Length == 0) 
      { 
       Console.Error.WriteLine("Path to script file not specified"); 

       return -1; 
      } 

      string argString = string.Join(" ", args); 
      Console.WriteLine("Node.js arguments received: {0}", argString); 

      string nodePath = Environment.GetEnvironmentVariable("NODE_HOME", 
       EnvironmentVariableTarget.Machine); // without "Machine" Git's Bash loses it 

      if (string.IsNullOrWhiteSpace(nodePath)) 
      { 
       Console.Error.WriteLine("NODE_HOME global envirnoment variable not found"); 

       return -1; 
      } 

      nodePath = Path.Combine(nodePath, "node.exe"); 

      ProcessStartInfo start = new ProcessStartInfo 
      { 
       UseShellExecute = false, 
       Arguments = argString, 
       FileName = nodePath, 
       RedirectStandardInput = true, 
       RedirectStandardOutput = true, 
       RedirectStandardError = true, 
       CreateNoWindow = true 
      }; 

      Process process = new Process(); 
      process.StartInfo = start; 

      process.EnableRaisingEvents = true; 
      process.OutputDataReceived += process_OutputDataReceived; 
      process.ErrorDataReceived += process_OutputDataReceived; 
      process.Start(); 

      process.BeginErrorReadLine(); 
      process.BeginOutputReadLine(); 

      process.WaitForExit(); 

      return process.ExitCode; 
     } 

     static void process_OutputDataReceived(object sender, DataReceivedEventArgs e) 
     { 
      string s = e.Data; 
      Console.Out.WriteLine(s); 
     } 

     static void process_ErrorDataReceived(object sender, DataReceivedEventArgs e) 
     { 
      string s = e.Data; 
      Console.Error.WriteLine(s); 
     } 
    } 
} 

我編譯它作爲混帳nodejs.exe,投入Git的bin文件夾,確保我已經定義NODE_HOME環境變量,現在我可以使用node.js腳本。作爲一個例子,我提供了我的node.js更新鉤子,它拒絕推送格式錯誤的註釋消息:

#!/bin/git-nodejs 

// bin/git-nodejs is our custom C# programmed node launcher 

// the following code is ported from http://git-scm.com/book/en/Customizing-Git-An-Example-Git-Enforced-Policy 

// we have some offset from standard Git args here: 
// 0 is path to node 
// 1 is path to this script 
var exec = require('child_process').exec, 
refname = process.argv[2], 
oldrev = process.argv[3], 
newrev = process.argv[4], 
regexMatch = /^REF #\d* /; // in my case I require strict start with "REF #number " 

console.log("Enforcing policies in branch " + refname + " for commits between revisions " + oldrev + " and " + newrev); 

// we have a special case - if this is a new branch, oldrev..newrev will cause git to throw an error, 
// that's why we check for empty branch commit ID 
var revListCmd = (oldrev === "0000000000000000000000000000000000000000") ? 
        "git rev-list " + newrev + " --not --branches=*" : 
        "git rev-list " + oldrev + ".." + newrev; 

exec(revListCmd, 
    function (error, stdout, stderr) { 
     if (error !== null) { 
      console.error("Exec error: " + error); 
      exitError(); 
     } 

     var missedRevs = stdout.split("\n"); 
     missedRevs.forEach(function(rev){ 
      // there is a redundant empty entry at the end after split() 
      if (rev.length === 0) { 
       return; 
      } 

      console.log("Verifying policy for revision " + rev); 

      // | sed '1,/^$/d' does not quite work as expected on Windows 
      // - it returns all commit details instead of comment 
      // thus we complete the processing from JavaScript 
      exec("git cat-file commit " + rev, 
       function (error, stdout, stderr) { 
        if (error !== null) { 
         console.error("Exec error: " + error); 
         exitError(); 
        } 

        // we skip the blank line (two sequential newlines) and take everything that follows 
        // not sure if this is the best solution but "it works on my machine" 
        var commitMessage = stdout.split("\n\n")[1];  
        // notice: if commit message missing, git will report it as "no message" 

        if (commitMessage.match(regexMatch) === null) { 
         console.error("Commit message '" + commitMessage + "' does not match the required pattern " + regexMatch); 
         exitError(); 
        } 

      }); 
     }); 
    }); 


////////////////////////// 
// some helpers 

function exitError() 
{ 
    // hack for bug https://github.com/joyent/node/issues/3584 
    // delay exit until stdout on Windows has had some time to flush 
    setTimeout(function() { 
     console.error("Exiting with error status 1"); 
     process.exit(1); 
    }, 1000); 
} 
相關問題