add git branch picker + status bar indicator

git.branches and git.checkout IPC verbs. Status bar shows current
branch with ahead/behind count; clicking opens a branch picker
dialog for checkout.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-04-22 17:30:37 +02:00
co-authored by Claude
parent 6592a88695
commit 45054f7aec
4 changed files with 325 additions and 0 deletions
+31
View File
@@ -194,6 +194,37 @@ Future<String> gitPush(
return ((r.stdout as String) + (r.stderr as String)).trim();
}
/// List local branches. Returns (name, isCurrent) pairs.
Future<List<({String name, bool current})>> gitBranches(
Directory workDir) async {
final r = await Process.run(
'git',
['branch', '--format=%(refname:short)\x00%(HEAD)'],
workingDirectory: workDir.path,
);
if (r.exitCode != 0) return const [];
final out = <({String name, bool current})>[];
for (final line in (r.stdout as String).split('\n')) {
if (line.trim().isEmpty) continue;
final parts = line.split('\x00');
if (parts.length < 2) continue;
out.add((name: parts[0], current: parts[1].trim() == '*'));
}
return out;
}
/// Checkout a branch.
Future<void> gitCheckout(Directory workDir, String branch) async {
final r = await Process.run(
'git',
['checkout', branch],
workingDirectory: workDir.path,
);
if (r.exitCode != 0) {
throw GitException('git checkout failed', stderr: r.stderr as String);
}
}
/// Get the current branch name.
Future<String?> gitCurrentBranch(Directory workDir) async {
final r = await Process.run(