import { execFileSync } from "node:child_process"; import type { GitInfo } from "./types.js"; export function getGitInfo(cwd: string): GitInfo { const branch = git(cwd, ["branch", "--show-current"]); if (!branch) return { branch: null, dirty: false, ahead: 0, behind: 0 }; const porcelain = git(cwd, ["status", "--porcelain=v1", "--branch"]) ?? ""; const lines = porcelain.split("\n").filter(Boolean); let ahead = 0; let behind = 0; const first = lines[0] ?? ""; const aheadMatch = first.match(/ahead (\d+)/); const behindMatch = first.match(/behind (\d+)/); if (aheadMatch) ahead = Number(aheadMatch[1]); if (behindMatch) behind = Number(behindMatch[1]); const fileStats = { modified: 0, added: 0, deleted: 0, untracked: 0 }; for (const line of lines.slice(1)) { const xy = line.slice(0, 2); if (xy.includes("?")) fileStats.untracked += 1; if (xy.includes("M")) fileStats.modified += 1; if (xy.includes("A")) fileStats.added += 1; if (xy.includes("D")) fileStats.deleted += 1; } return { branch, dirty: lines.length > 1, ahead, behind, fileStats }; } function git(cwd: string, args: string[]): string | null { try { return execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 300, }).trim(); } catch { return null; } }