* List branches in a repository
(params: ListBranchesParams)
| 1400 | * List branches in a repository |
| 1401 | */ |
| 1402 | async function handleListBranches(params: ListBranchesParams): Promise<ListBranchesResponse> { |
| 1403 | const startTime = Date.now() |
| 1404 | logger.info("[Git:listBranches] Listing branches", JSON.stringify({ repoDir: params.repoDir, includeRemote: params.includeRemote })) |
| 1405 | |
| 1406 | try { |
| 1407 | validateRepoDir(params.repoDir) |
| 1408 | |
| 1409 | // Resolve git info (handles subdirectories) |
| 1410 | const { repoRoot } = await resolveGitInfo(params.repoDir) |
| 1411 | |
| 1412 | // Detect default branch |
| 1413 | let defaultBranch = "main" |
| 1414 | |
| 1415 | // Try to get from remote HEAD |
| 1416 | const remoteHeadResult = await execGit(["symbolic-ref", "refs/remotes/origin/HEAD"], repoRoot) |
| 1417 | if (remoteHeadResult.success) { |
| 1418 | const refName = remoteHeadResult.stdout.trim() |
| 1419 | defaultBranch = refName.replace("refs/remotes/origin/", "") |
| 1420 | } else { |
| 1421 | // Check if main exists |
| 1422 | const mainExistsResult = await execGit(["show-ref", "--verify", "refs/heads/main"], repoRoot) |
| 1423 | if (mainExistsResult.success) { |
| 1424 | defaultBranch = "main" |
| 1425 | } else { |
| 1426 | // Check if master exists |
| 1427 | const masterExistsResult = await execGit(["show-ref", "--verify", "refs/heads/master"], repoRoot) |
| 1428 | if (masterExistsResult.success) { |
| 1429 | defaultBranch = "master" |
| 1430 | } |
| 1431 | } |
| 1432 | } |
| 1433 | |
| 1434 | // Get local branches |
| 1435 | const localBranchesResult = await execGit(["branch", "--format=%(refname:short)"], repoRoot) |
| 1436 | if (!localBranchesResult.success) { |
| 1437 | throw new Error(`Failed to list branches: ${localBranchesResult.stderr}`) |
| 1438 | } |
| 1439 | |
| 1440 | const localBranches = localBranchesResult.stdout |
| 1441 | .split("\n") |
| 1442 | .map((b) => b.trim()) |
| 1443 | .filter((b) => b.length > 0) |
| 1444 | |
| 1445 | const branches: BranchInfo[] = localBranches.map((name) => ({ |
| 1446 | name, |
| 1447 | isDefault: name === defaultBranch, |
| 1448 | isRemote: false, |
| 1449 | })) |
| 1450 | |
| 1451 | // Optionally include remote branches |
| 1452 | if (params.includeRemote) { |
| 1453 | const remoteBranchesResult = await execGit(["branch", "-r", "--format=%(refname:short)"], repoRoot) |
| 1454 | if (remoteBranchesResult.success) { |
| 1455 | const remoteBranches = remoteBranchesResult.stdout |
| 1456 | .split("\n") |
| 1457 | .map((b) => b.trim()) |
| 1458 | .filter((b) => b.length > 0 && !b.includes("HEAD")) |
| 1459 |
no test coverage detected