X-Git-Url: https://git.cweiske.de/phorkie.git/blobdiff_plain/9e9f228abdf3f10d369b2699ffef29b59ff2bbf4..137322548e4739c826e49ceefaddfb668a6f9cf2:/src/phorkie/Repository.php diff --git a/src/phorkie/Repository.php b/src/phorkie/Repository.php index 6dec015..aa1ea4c 100644 --- a/src/phorkie/Repository.php +++ b/src/phorkie/Repository.php @@ -12,11 +12,27 @@ class Repository public $id; /** - * Full path to the git repository + * Full path to the .git repository * * @var string */ - public $repoDir; + public $gitDir; + + /** + * Full path to the work tree directory + * + * @var string + */ + public $workDir; + + /** + * Revision of the repository that shall be shown + * + * @var string + */ + public $hash; + + /** * Load Repository data from GET-Request @@ -34,12 +50,46 @@ class Repository throw new Exception_Input('Paste ID not numeric'); } $this->id = (int)$_GET['id']; + $this->loadDirs(); + $this->loadHash(); + } + + protected function loadDirs() + { + $gitDir = $GLOBALS['phorkie']['cfg']['gitdir'] . '/' . $this->id . '.git'; + if (!is_dir($gitDir)) { + throw new Exception_NotFound( + sprintf('Paste %d .git dir not found', $this->id) + ); + } + $this->gitDir = $gitDir; + + $workDir = $GLOBALS['phorkie']['cfg']['workdir'] . '/' . $this->id; + if (!is_dir($workDir)) { + throw new Exception_NotFound( + sprintf('Paste %d work dir not found', $this->id) + ); + } + $this->workDir = $workDir; + } - $repoDir = $GLOBALS['phorkie']['cfg']['repos'] . '/' . $this->id; - if (!is_dir($repoDir)) { - throw new Exception_NotFound('Paste not found'); + public function loadHash() + { + if ($this->hash !== null) { + return; } - $this->repoDir = $repoDir; + + $output = $this->getVc()->getCommand('log') + ->setOption('pretty', 'format:%H') + ->setOption('max-count', 1) + ->execute(); + $output = trim($output); + if (strlen($output) !== 40) { + throw new Exception( + 'Loading commit hash failed: ' . $output + ); + } + $this->hash = $output; } public function loadById($id) @@ -48,17 +98,13 @@ class Repository throw new Exception_Input('Paste ID not numeric'); } $this->id = (int)$id; - - $repoDir = $GLOBALS['phorkie']['cfg']['repos'] . '/' . $this->id; - if (!is_dir($repoDir)) { - throw new Exception_NotFound('Paste not found'); - } - $this->repoDir = $repoDir; + $this->loadDirs(); + $this->loadHash(); } public function getVc() { - return new \VersionControl_Git($this->repoDir); + return new \VersionControl_Git($this->gitDir); } /** @@ -68,7 +114,7 @@ class Repository */ public function getFiles() { - $files = glob($this->repoDir . '/*'); + $files = glob($this->workDir . '/*'); $arFiles = array(); foreach ($files as $path) { $arFiles[] = new File($path, $this); @@ -85,7 +131,7 @@ class Repository if ($name == '') { throw new Exception_Input('Empty file name given'); } - $path = $this->repoDir . '/' . $base; + $path = $this->workDir . '/' . $base; if ($bHasToExist && !is_readable($path)) { throw new Exception_Input('File does not exist'); } @@ -110,33 +156,38 @@ class Repository */ public function delete() { - return Tools::recursiveDelete($this->repoDir); + return Tools::recursiveDelete($this->workDir) + && Tools::recursiveDelete($this->gitDir); } public function getDescription() { - if (!is_readable($this->repoDir . '/.git/description')) { + if (!is_readable($this->gitDir . '/description')) { return null; } - return file_get_contents($this->repoDir . '/.git/description'); + return file_get_contents($this->gitDir . '/description'); } public function setDescription($description) { - file_put_contents($this->repoDir . '/.git/description', $description); + file_put_contents($this->gitDir . '/description', $description); } /** * Get a link to the repository * * @param string $type Link type. Supported are: + * - "commit" * - "edit" + * - "delete" + * - "delete-confirm" * - "display" * - "fork" + * @param string $option * * @return string */ - public function getLink($type) + public function getLink($type, $option = null) { if ($type == 'edit') { return '/' . $this->id . '/edit'; @@ -148,6 +199,8 @@ class Repository return '/' . $this->id . '/delete'; } else if ($type == 'delete-confirm') { return '/' . $this->id . '/delete/confirm'; + } else if ($type == 'commit') { + return '/' . $this->id . '/' . $option; } throw new Exception('Unknown link type'); } @@ -156,10 +209,55 @@ class Repository { $var = $public ? 'public' : 'private'; if (isset($GLOBALS['phorkie']['cfg']['git'][$var])) { - return $GLOBALS['phorkie']['cfg']['git'][$var] . $this->id . '/.git'; + return $GLOBALS['phorkie']['cfg']['git'][$var] . $this->id . '.git'; } return null; } + + /** + * Returns the history of the repository. + * We don't use VersionControl_Git's rev list fetcher since it does not + * give us separate email addresses and names, and it does not give us + * the amount of changed (added/deleted) lines. + * + * @return array Array of history objects + */ + public function getHistory() + { + $output = $this->getVc()->getCommand('log') + ->setOption('pretty', 'format:commit %H%n%at%n%an%n%ae') + ->setOption('max-count', 10) + ->setOption('shortstat') + ->execute(); + + $arCommits = array(); + $arOutput = explode("\n", $output); + $lines = count($arOutput); + $current = 0; + while ($current < $lines) { + $commit = new Repository_Commit(); + list($name,$commit->hash) = explode(' ', $arOutput[$current]); + if ($name !== 'commit') { + throw new Exception( + 'Git log output format not as expected: ' . $arOutput[$current] + ); + } + $commit->committerTime = $arOutput[$current + 1]; + $commit->committerName = $arOutput[$current + 2]; + $commit->committerEmail = $arOutput[$current + 3]; + + $arLineParts = explode(' ', trim($arOutput[$current + 4])); + $commit->filesChanged = $arLineParts[0]; + $commit->linesAdded = $arLineParts[3]; + $commit->linesDeleted = $arLineParts[5]; + + $current += 6; + + $arCommits[] = $commit; + } + + return $arCommits; + } } ?>