diff --git a/admin.php b/admin.php
index 5376a27..89de681 100644
--- a/admin.php
+++ b/admin.php
@@ -41,12 +41,28 @@ function git_output(array $args): string {
}
function git_local_branches(): array {
- $out = git_output(['branch', '--format=%(refname:short)']);
- $branches = array_values(array_filter(array_map('trim', explode("\n", $out)), fn($v) => $v !== ''));
+ $out = git_output(['branch', '--list', '--no-color']);
+ $branches = array_values(array_filter(array_map(function ($line) {
+ return trim(ltrim(trim($line), '*'));
+ }, explode("\n", $out)), fn($v) => $v !== ''));
sort($branches, SORT_NATURAL | SORT_FLAG_CASE);
return $branches;
}
+function git_remote_branches(): array {
+ $out = git_output(['branch', '-r', '--no-color']);
+ $branches = array_values(array_filter(array_map('trim', explode("\n", $out)), function ($branch) {
+ return $branch !== '' && !str_contains($branch, ' -> ') && !str_ends_with($branch, '/HEAD');
+ }));
+ sort($branches, SORT_NATURAL | SORT_FLAG_CASE);
+ return $branches;
+}
+
+function branch_from_remote(string $remoteBranch): string {
+ $parts = explode('/', $remoteBranch, 2);
+ return $parts[1] ?? $remoteBranch;
+}
+
$message = null;
$result = null;
@@ -63,13 +79,33 @@ if ($allowed && $_SERVER['REQUEST_METHOD'] === 'POST') {
$result = git_run(['pull', '--ff-only']);
$message = 'git pull --ff-only';
} elseif ($action === 'switch') {
- $branch = trim((string)($_POST['branch'] ?? ''));
- $branches = git_local_branches();
- if (!in_array($branch, $branches, true)) {
- $result = ['code' => 1, 'output' => 'Unknown or non-local branch: ' . $branch];
+ $ref = trim((string)($_POST['branch'] ?? ''));
+ $localBranches = git_local_branches();
+ $remoteBranches = git_remote_branches();
+ if (str_starts_with($ref, 'local:')) {
+ $branch = substr($ref, 6);
+ if (!in_array($branch, $localBranches, true)) {
+ $result = ['code' => 1, 'output' => 'Unknown local branch: ' . $branch];
+ } else {
+ $result = git_run(['switch', $branch]);
+ $message = 'git switch ' . $branch;
+ }
+ } elseif (str_starts_with($ref, 'remote:')) {
+ $remoteBranch = substr($ref, 7);
+ if (!in_array($remoteBranch, $remoteBranches, true)) {
+ $result = ['code' => 1, 'output' => 'Unknown remote branch: ' . $remoteBranch];
+ } else {
+ $branch = branch_from_remote($remoteBranch);
+ if (in_array($branch, $localBranches, true)) {
+ $result = git_run(['switch', $branch]);
+ $message = 'git switch ' . $branch;
+ } else {
+ $result = git_run(['switch', '--track', $remoteBranch]);
+ $message = 'git switch --track ' . $remoteBranch;
+ }
+ }
} else {
- $result = git_run(['switch', $branch]);
- $message = 'git switch ' . $branch;
+ $result = ['code' => 1, 'output' => 'Unknown branch selection.'];
}
}
}
@@ -78,11 +114,13 @@ if ($allowed && $_SERVER['REQUEST_METHOD'] === 'POST') {
$currentBranch = '';
$status = '';
$branches = [];
+$remoteBranches = [];
$lastCommit = '';
if ($allowed) {
$currentBranch = git_output(['rev-parse', '--abbrev-ref', 'HEAD']);
$status = git_output(['status', '-sb']);
$branches = git_local_branches();
+ $remoteBranches = git_remote_branches();
$lastCommit = git_output(['log', '-1', '--pretty=%h %s (%cr)']);
}
?>
@@ -170,10 +208,19 @@ if ($allowed) {