--- /dev/null
+<?php
+
+
+// needs to be run from git-recieve (and it has to be the only thing run.
+
+class MTrackWeb_Hook_Git_Bridge extends MTrackWeb_Hook_Bridge
+{
+
+
+ var $repo;
+ var $files = array();
+ var $log = array();
+ var $commits = array();
+ var $fileActions = array(); // file=> delete / modify etc..
+
+ /**
+ * fills up repo, files, log, commits by running log on the STDIN
+ */
+ function __construct($repo)
+ {
+
+
+
+ $this->repo = $repo;
+
+ while (($line = fgets(STDIN)) !== false) {
+
+ list($old, $new, $ref) = explode(' ', trim($line), 3);
+ $this->commits[] = $new;
+
+ $fp = $this->repo->impl()->git('log', '--no-color', '--name-status',
+ '--date=rfc', $ref, "$old..$new");
+
+
+ $props = array();
+ $line = fgets($fp);
+ if (!preg_match("/^commit\s+(\S+)$/", $line)) {
+ throw new Exception("unexpected output from git log: $line");
+ }
+ // read key: value properties like Author: / Date:
+ while (($line = fgets($fp)) !== false) {
+ $line = rtrim($line);
+ if (!strlen($line)) break;
+ if (preg_match("/^(\S+):\s*(.*)\s*$/", $line, $M)) {
+ $props[$M[1]] = $M[2];
+ }
+ }
+ // read the commit log.
+ while (($line = fgets($fp)) !== false) {
+ $line = rtrim($line);
+ if (strncmp($line, ' ', 4)) {
+ break;
+ }
+ $this->log[] = substr($line, 4);
+ }
+
+
+ do {
+ if (preg_match("/^(.+)\s+(\S+)\s*$/", $line, $M)) {
+ $st = $M[1];
+ $file = $M[2];
+ $this->files[$file] = $new;
+ $this->fileActions[$file] = $st;
+ }
+
+ } while (($line = fgets($fp)) !== false);
+ }
+ }
+
+
+ function enumChangedOrModifiedFileNames()
+ {
+ $ret = array();
+ foreach($this->files as $f=>$com) {
+ if ($this->fileActions[$f] == 'D') {
+ continue;
+ }
+ $ret[] = $f;
+ }
+ return $ret;
+ }
+
+ function getCommitMessage()
+ {
+ $log = join("\n", $this->log);
+ $log = preg_replace('/\[([a-fA-F0-9]+)\]/',
+ "[changeset:" . $this->repo->getBrowseRootName() . ",\$1]", $log);
+ return $log;
+ }
+
+ function getFileStream($path)
+ {
+ $rev = $this->files[$path];
+
+ // There may be a better way...
+ // ls-tree to determine the hash of the file from this change:
+ $fp = $this->repo->impl()->git('ls-tree', '-r', $rev, $path);
+ $line = fgets($fp);
+ $fp = null;
+ list($mode, $type, $hash, $name) = preg_split("/\s+/", $line);
+ // now we can cat that blob
+ return $this->repo->impl()->git('cat-file', 'blob', $hash);
+ }
+
+ function getChangesetDescriptor()
+ {
+ $cs = array();
+ foreach ($this->commits as $ref) {
+ $cs[] = '[changeset:' . $this->repo->getBrowseRootName() . ",$ref]";
+ }
+ return join(", ", $cs);
+ }
+}
\ No newline at end of file