| | |
| | function getRepositories() { |
| | - $repos = []; |
| | - if (!is_dir(REPOS_PATH)) { |
| | - return $repos; |
| | - } |
| | + $repos = []; |
| | + if (!is_dir(REPOS_PATH)) { |
| | + return $repos; |
| | + } |
| | |
| | - $dirs = scandir(REPOS_PATH); |
| | - foreach ($dirs as $dir) { |
| | - if ($dir === '.' || $dir === '..') continue; |
| | - $path = REPOS_PATH . '/' . $dir; |
| | - if (is_dir($path) && (is_dir($path . '/.git') || is_file($path . '/HEAD'))) { |
| | - $repos[] = $dir; |
| | - } |
| | + $dirs = scandir(REPOS_PATH); |
| | + foreach ($dirs as $dir) { |
| | + if ($dir === '.' || $dir === '..') continue; |
| | + $path = REPOS_PATH . '/' . $dir; |
| | + if (is_dir($path) && (is_dir($path . '/.git') || is_file($path . '/HEAD'))) { |
| | + $repos[] = $dir; |
| | } |
| | + } |
| | |
| | - $orderFile = __DIR__ . '/../order.txt'; |
| | - if (file_exists($orderFile)) { |
| | - $lines = array_filter(array_map('trim', file($orderFile))); |
| | - $blacklist = []; |
| | - $order = []; |
| | + $orderFile = __DIR__ . '/../order.txt'; |
| | + if (file_exists($orderFile)) { |
| | + $lines = array_filter(array_map('trim', file($orderFile))); |
| | + $blacklist = []; |
| | + $order = []; |
| | |
| | - // Parse order.txt for blacklisted (starting with -) and ordered repos |
| | - foreach ($lines as $line) { |
| | - if (substr($line, 0, 1) === '-') { |
| | - // Blacklisted repo - add without the - prefix |
| | - $blacklist[] = substr($line, 1); |
| | - } else { |
| | - // Normal ordered repo |
| | - $order[] = $line; |
| | - } |
| | - } |
| | + // Parse order.txt for blacklisted (starting with -) and ordered repos |
| | + foreach ($lines as $line) { |
| | + if (substr($line, 0, 1) === '-') { |
| | + // Blacklisted repo - add without the - prefix |
| | + $blacklist[] = substr($line, 1); |
| | + } else { |
| | + // Normal ordered repo |
| | + $order[] = $line; |
| | + } |
| | + } |
| | |
| | - // Filter out blacklisted repos |
| | - $repos = array_filter($repos, function($repo) use ($blacklist) { |
| | - return !in_array($repo, $blacklist); |
| | - }); |
| | + // Filter out blacklisted repos |
| | + $repos = array_filter($repos, function($repo) use ($blacklist) { |
| | + return !in_array($repo, $blacklist); |
| | + }); |
| | |
| | - // Create order map and sort |
| | - $orderMap = array_flip($order); |
| | + // Create order map and sort |
| | + $orderMap = array_flip($order); |
| | |
| | - usort($repos, function($a, $b) use ($orderMap) { |
| | - $aPos = isset($orderMap[$a]) ? $orderMap[$a] : PHP_INT_MAX; |
| | - $bPos = isset($orderMap[$b]) ? $orderMap[$b] : PHP_INT_MAX; |
| | + usort($repos, function($a, $b) use ($orderMap) { |
| | + $aPos = isset($orderMap[$a]) ? $orderMap[$a] : PHP_INT_MAX; |
| | + $bPos = isset($orderMap[$b]) ? $orderMap[$b] : PHP_INT_MAX; |
| | |
| | - if ($aPos === PHP_INT_MAX && $bPos === PHP_INT_MAX) { |
| | - return strcmp($a, $b); |
| | - } |
| | + if ($aPos === PHP_INT_MAX && $bPos === PHP_INT_MAX) { |
| | + return strcmp($a, $b); |
| | + } |
| | |
| | - return $aPos - $bPos; |
| | - }); |
| | - } else { |
| | - sort($repos); |
| | - } |
| | + return $aPos - $bPos; |
| | + }); |
| | + } else { |
| | + sort($repos); |
| | + } |
| | |
| | - return $repos; |
| | + return $repos; |
| | } |
| | |
| | function getRepoInfo($repo) { |
| | - $info = []; |
| | - $repoPath = REPOS_PATH . '/' . basename($repo); |
| | + $info = []; |
| | + $repoPath = REPOS_PATH . '/' . basename($repo); |
| | |
| | - $descFile = is_dir($repoPath . '/.git') ? $repoPath . '/.git/description' : $repoPath . '/description'; |
| | - $info['description'] = file_exists($descFile) ? trim(file_get_contents($descFile)) : 'No description'; |
| | - if ($info['description'] === 'Unnamed repository; edit this file \'description\' to name the repository.') { |
| | - $info['description'] = 'No description'; |
| | - } |
| | + $descFile = is_dir($repoPath . '/.git') ? $repoPath . '/.git/description' : $repoPath . '/description'; |
| | + $info['description'] = file_exists($descFile) ? trim(file_get_contents($descFile)) : 'No description'; |
| | + if ($info['description'] === 'Unnamed repository; edit this file \'description\' to name the repository.') { |
| | + $info['description'] = 'No description'; |
| | + } |
| | |
| | - $log = execGitCached($repo, "log -1 --format='%H|%an|%ae|%at|%s'"); |
| | - if (!empty($log) && $log !== null) { |
| | - $parts = explode('|', trim($log)); |
| | - if (count($parts) >= 5) { |
| | - $info['last_commit'] = [ |
| | - 'hash' => $parts[0], |
| | - 'author' => $parts[1], |
| | - 'email' => $parts[2], |
| | - 'date' => $parts[3], |
| | - 'message' => $parts[4] |
| | - ]; |
| | - } |
| | + $log = execGitCached($repo, "log -1 --format='%H|%an|%ae|%at|%s'"); |
| | + if (!empty($log) && $log !== null) { |
| | + $parts = explode('|', trim($log)); |
| | + if (count($parts) >= 5) { |
| | + $info['last_commit'] = [ |
| | + 'hash' => $parts[0], |
| | + 'author' => $parts[1], |
| | + 'email' => $parts[2], |
| | + 'date' => $parts[3], |
| | + 'message' => $parts[4] |
| | + ]; |
| | } |
| | + } |
| | |
| | - $branches = execGitCached($repo, "branch -a"); |
| | - $info['branches'] = empty($branches) ? 0 : count(array_filter(explode("\n", $branches))); |
| | + $branches = execGitCached($repo, "branch -a"); |
| | + $info['branches'] = empty($branches) ? 0 : count(array_filter(explode("\n", $branches))); |
| | |
| | - $tags = execGitCached($repo, "tag"); |
| | - $info['tags'] = empty($tags) ? 0 : count(array_filter(explode("\n", $tags))); |
| | + $tags = execGitCached($repo, "tag"); |
| | + $info['tags'] = empty($tags) ? 0 : count(array_filter(explode("\n", $tags))); |
| | |
| | - return $info; |
| | + return $info; |
| | } |
| | |
| | function getBranches($repo) { |
| | - $output = execGitCached($repo, "branch -a --format='%(refname:short)|%(committerdate:unix)|%(subject)'"); |
| | - $branches = []; |
| | - if (empty($output) || $output === null) { |
| | - return $branches; |
| | - } |
| | - foreach (explode("\n", trim($output)) as $line) { |
| | - if (empty($line)) continue; |
| | - $parts = explode('|', $line, 3); |
| | - if (count($parts) >= 3) { |
| | - $branches[] = [ |
| | - 'name' => $parts[0], |
| | - 'date' => $parts[1], |
| | - 'message' => $parts[2] |
| | - ]; |
| | - } |
| | - } |
| | + $output = execGitCached($repo, "branch -a --format='%(refname:short)|%(committerdate:unix)|%(subject)'"); |
| | + $branches = []; |
| | + if (empty($output) || $output === null) { |
| | return $branches; |
| | + } |
| | + foreach (explode("\n", trim($output)) as $line) { |
| | + if (empty($line)) continue; |
| | + $parts = explode('|', $line, 3); |
| | + if (count($parts) >= 3) { |
| | + $branches[] = [ |
| | + 'name' => $parts[0], |
| | + 'date' => $parts[1], |
| | + 'message' => $parts[2] |
| | + ]; |
| | + } |
| | + } |
| | + return $branches; |
| | } |
| | |
| | function getCommits($repo, $branch = 'HEAD', $limit = 30) { |
| | - $output = execGitCached($repo, "log $branch -$limit --format='%H|%an|%ae|%at|%s'"); |
| | + $cmd = "log " . escapeshellarg($branch) . " -$limit --format='%H|%an|%ae|%at|%s'"; |
| | + $output = execGitCached($repo, $cmd); |
| | $commits = []; |
| | if (empty($output) || $output === null) { |
 |
| | |
| | function getCommitDetails($repo, $hash) { |
| | - $info = execGitCached($repo, "show --format='%H|%an|%ae|%at|%s|%b' --stat $hash"); |
| | - $diff = execGitCached($repo, "show --format='' $hash"); |
| | - $lines = explode("\n", $info); |
| | - $header = array_shift($lines); |
| | - $parts = explode('|', $header, 6); |
| | - return [ |
| | - 'hash' => $parts[0] ?? '', |
| | - 'author' => $parts[1] ?? '', |
| | - 'email' => $parts[2] ?? '', |
| | - 'date' => $parts[3] ?? '', |
| | - 'message' => $parts[4] ?? '', |
| | - 'body' => $parts[5] ?? '', |
| | - 'stat' => implode("\n", $lines), |
| | - 'diff' => $diff |
| | - ]; |
| | + $info = execGitCached($repo, "show --format='%H|%an|%ae|%at|%s|%b' --stat $hash"); |
| | + $diff = execGitCached($repo, "show --format='' $hash"); |
| | + $lines = explode("\n", $info); |
| | + $header = array_shift($lines); |
| | + $parts = explode('|', $header, 6); |
| | + return [ |
| | + 'hash' => $parts[0] ?? '', |
| | + 'author' => $parts[1] ?? '', |
| | + 'email' => $parts[2] ?? '', |
| | + 'date' => $parts[3] ?? '', |
| | + 'message' => $parts[4] ?? '', |
| | + 'body' => $parts[5] ?? '', |
| | + 'stat' => implode("\n", $lines), |
| | + 'diff' => $diff |
| | + ]; |
| | } |
| | |
| | function getTree($repo, $ref = 'HEAD', $path = '') { |
| | - if ($ref === 'HEAD') { |
| | - $defaultBranch = execGitCached($repo, "symbolic-ref HEAD"); |
| | - if (!empty($defaultBranch) && $defaultBranch !== null) { |
| | - $ref = trim(str_replace('refs/heads/', '', $defaultBranch)); |
| | - } else { |
| | - $branches = execGitCached($repo, "branch"); |
| | - if (!empty($branches)) { |
| | - $branchList = array_filter(array_map('trim', explode("\n", $branches))); |
| | - if (!empty($branchList)) { |
| | - $ref = trim(str_replace('* ', '', $branchList[0])); |
| | - } |
| | - } |
| | - } |
| | - } |
| | + $fullPath = $path ? $ref . ':' . $path : $ref; |
| | + $cmd = "ls-tree " . escapeshellarg($fullPath); |
| | + $output = execGitCached($repo, $cmd); |
| | + $items = []; |
| | + if (empty($output) || $output === null) { |
| | + return $items; |
| | + } |
| | |
| | - $fullPath = $path ? $ref . ':' . $path : $ref; |
| | - $cmd = "ls-tree " . escapeshellarg($fullPath); |
| | - $output = execGitCached($repo, $cmd); |
| | - $items = []; |
| | - if (empty($output) || $output === null) { |
| | - return $items; |
| | + foreach (explode("\n", trim($output)) as $line) { |
| | + if (empty($line)) continue; |
| | + if (preg_match('/^(\d+)\s+(blob|tree)\s+([a-f0-9]+)\s+(.+)$/', $line, $matches)) { |
| | + $items[] = [ |
| | + 'mode' => $matches[1], |
| | + 'type' => $matches[2], |
| | + 'hash' => $matches[3], |
| | + 'name' => $matches[4] |
| | + ]; |
| | } |
| | + } |
| | |
| | - foreach (explode("\n", trim($output)) as $line) { |
| | - if (empty($line)) continue; |
| | - if (preg_match('/^(\d+)\s+(blob|tree)\s+([a-f0-9]+)\s+(.+)$/', $line, $matches)) { |
| | - $items[] = [ |
| | - 'mode' => $matches[1], |
| | - 'type' => $matches[2], |
| | - 'hash' => $matches[3], |
| | - 'name' => $matches[4] |
| | - ]; |
| | - } |
| | + usort($items, function($a, $b) { |
| | + if ($a['type'] !== $b['type']) { |
| | + return $a['type'] === 'tree' ? -1 : 1; |
| | } |
| | - |
| | - usort($items, function($a, $b) { |
| | - if ($a['type'] !== $b['type']) { |
| | - return $a['type'] === 'tree' ? -1 : 1; |
| | - } |
| | - return strcmp($a['name'], $b['name']); |
| | - }); |
| | - return $items; |
| | + return strcmp($a['name'], $b['name']); |
| | + }); |
| | + return $items; |
| | } |
| | |
| | function getBlob($repo, $hash) { |
| | - return execGitCached($repo, "cat-file blob $hash"); |
| | + return execGitCached($repo, "cat-file blob $hash"); |
| | } |
| | |