2016-05-03 7 views
0

Ist es möglich, git pull und git push Befehle über PHP zu kanalisieren?Kanal `git auf dem Server` Anrufe durch PHP

Damit meine ich, ich https://example.com/projectname?credentials=xxx als git origin gesetzt würde, und dann, wenn ich ein pull oder push, der PHP-Skript ausführen analysiert die Anmeldeinformationen, wenn sie in Ordnung sind, den ursprünglichen Befehl von git git Repo gesendet senden Ordner auf meinem Server, und dann wird eine Antwort zurück an den Benutzer gesendet?

Konnte git-http-backend verwendet werden, um dies zu erreichen, oder gibt es einen anderen Weg?

+0

Sehen Sie, wie PHP-Arbeit wie ein Terminal zu machen. 'Shell_exec' Befehl sollte Ihnen helfen, – Autor69

+0

klingt wie ein Job für [Git Alias] (https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases) für mich. – DevDonkey

Antwort

0

ich habe es endlich für Pull-bezogene Befehle zu arbeiten, aber nicht für Push-Befehle

static $basegitdir = '/path/to/where/bare/git/repos/live'; 

/** 
* A PHP wrapper for git-http-backend 
*/ 
static function httpBackend() { 
    $packagename = 'gitrepo'; 
    $gitdir = self::$basegitdir . "{$packagename}.git"; 
    $gitcoredir = '/usr/lib/git-core'; // True for Ubuntu systems 
    try { 
     // In my implementation, func_get_args will return e.g. ['info', 'refs'], basically, all of the stuff git appends to the remote url 
     $arguments = func_get_args(); 
     // Remove the first argument 
     array_unshift($arguments, "{$packagename}.git"); 
     // Will resolve to something like '/repo.git/info/refs' 
     $path = '/' . implode('/', $arguments); 
     $service = filter_input(INPUT_GET, 'service'); 
     if ($service) { 
      $service = "?service={$service}"; 
     } 
     $res = self::proc_open("{$gitcoredir}/git-http-backend", [], $gitdir, true, [ 
      'PATH' => filter_input(INPUT_SERVER, 'PATH'), 
      'GIT_PROJECT_ROOT' => self::$basegitdir, 
      'GIT_HTTP_EXPORT_ALL' => 1, 
      // PATH_INFO <MUST> evaluate to something along the lines of '/repo.git/info/refs'. Note, basegitdir has been 
      // dropped from the beginning of the path. This is because Git joins GIT_PROJECT_ROOT and PATH_INFO. Also note the lack of a trailing slash after refs 
      'PATH_INFO' => $path, 
      'REMOTE_ADDR' => filter_input(INPUT_SERVER, 'REMOTE_ADDR'), 
      // QUERY_STRING MUST evaluate to something along the lines of '/repo.git/info/refs/?service=service', note the trailing slash after refs 
      'QUERY_STRING' => "{$path}/{$service}", 
      'REQUEST_METHOD' => filter_input(INPUT_SERVER, 'REQUEST_METHOD'), 
     ]); 
    } catch (\Exception $ex) { 
     // Log "Exception: {$ex->getMessage()}"; 
     exit; 
    } 
    $resbits = explode("\n", $res); 
    foreach ($resbits as $index => $header) { 
     if ($header && strpos($header, ':') !== false) { 
      // Headers 
      header($header); 
      unset($resbits[$index]); 
     } else { 
      // First blank line is the space between the headers and the start of the response from Git 
      break; 
     } 
    } 
    echo ltrim(implode("\n", $resbits)); 
    exit; 
} 

/** 
* A wrapper for the proc_open functions 
* @param string $command The command to execute 
* @param array $arguments Responses to bash 
* @param string $cwd The current working directory 
* @param boolean $blocking False to make requests asynchronous 
* @param array $env Environment variables 
* @return string The output 
* @throws \Exception 
*/ 
static function proc_open($command, array $arguments = [], $cwd = rootdir, $blocking = true, array $env = null) { 
    $pipes = []; 
    $descriptorspec = array(
     array('pipe', 'r'), // STDIN 
     array('pipe', 'w'), // STDOUT 
     array('pipe', 'w'), // STDERR 
    ); 
    $process = proc_open(trim($command), $descriptorspec, $pipes, $cwd, $env); 
    stream_set_blocking($pipes[1], (int) $blocking); 
    stream_set_blocking($pipes[2], (int) 1); 
    foreach ($arguments as $arg) { 
     // Write each of the supplied arguments to STDIN and ensure that it finishes with one trailing 
     fwrite($pipes[0], (preg_match("/\n(:?\s+)?$/", $arg) ? $arg : "{$arg}\n")); 
    } 
    $response = stream_get_contents($pipes[1]); 
    $error = stream_get_contents($pipes[2]); 
    if ($error) { 
     throw new \Exception($error); 
    } 
    // Make sure that each pipe is closed to prevent a lockout 
    foreach ($pipes as $pipe) { 
     fclose($pipe); 
    } 
    proc_close($process); 
    return $response; 
} 
Verwandte Themen