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) {