diff --git a/repo.php b/repo.php index 2bbec439..bcbe0be4 100644 --- a/repo.php +++ b/repo.php @@ -34,6 +34,8 @@ if (!isset($_REQUEST['repo'])) { } $repoId = $_REQUEST['repo']; +list($repoId, $branchId) = explode('/', $repoId); + if (!array_key_exists($repoId, $allRepositories)) { Header("HTTP/1.1 404 Repository not found"); exit(0); @@ -42,6 +44,16 @@ if (!array_key_exists($repoId, $allRepositories)) { $repoData = $allRepositories[$repoId]; $repo = getRepo($repoId, $repoData); +if ($branchId) { + try { + $repo->setBranch($branchId); + } + catch (Exception $e) { + Header("HTTP/1.1 404 No such branch"); + exit(0); + } +} + $cacheDir = null; $ts = $repo->timestamp($path); if (isset($config['cache'])) { diff --git a/src/RepositoryGit.php b/src/RepositoryGit.php index b0e6f4d6..d35ff30b 100644 --- a/src/RepositoryGit.php +++ b/src/RepositoryGit.php @@ -2,10 +2,27 @@ class RepositoryGit extends RepositoryBase { function __construct ($id, $def) { parent::__construct($id, $def); - $this->branch = $def['branch'] ?? 'HEAD'; + if (array_key_exists('branch', $def)) { + $this->branch = $def['branch']; + } + else { + $this->branch = chop(shell_exec("cd " . escapeShellArg($this->path) . "; git rev-parse --abbrev-ref HEAD")); + } + $this->branchEsc = escapeShellArg($this->branch); } + function setBranch ($branch) { + $this->branch = $branch; + $this->branchEsc = escapeShellArg($this->branch); + + exec("cd " . escapeShellArg($this->path) . "; git ls-tree {$this->branchEsc}", $output, $return); + + if ($return !== 0) { + throw new Exception('no such branch'); + } + } + function timestamp () { $ts = (int)shell_exec("cd " . escapeShellArg($this->path) . "; git log -1 {$this->branchEsc} --pretty=format:%ct"); @@ -40,6 +57,20 @@ class RepositoryGit extends RepositoryBase { } pclose($d); + if (!array_key_exists('branch', $this->def)) { + $d = popen("cd " . escapeShellArg($this->path) . "; git for-each-ref --sort=-committerdate refs/heads/", "r"); + $data['branch'] = $this->branch; + $data['branches'] = array(); + while ($r = fgets($d)) { + if (preg_match("/^([0-9a-f]{40}) commit\trefs\/heads\/(.*)$/", $r, $m)) { + $data['branches'][$m[2]] = array( + 'commit' => $m[1], + ); + } + } + pclose($d); + } + return $data; }