mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
48 lines
1.7 KiB
TypeScript
48 lines
1.7 KiB
TypeScript
import type { GitFileStatus } from "./git-types";
|
|
|
|
export interface GitPorcelainEntry {
|
|
path: string;
|
|
originalPath?: string;
|
|
indexStatus: string;
|
|
worktreeStatus: string;
|
|
}
|
|
|
|
function usesRenamePath(indexStatus: string, worktreeStatus: string): boolean {
|
|
return indexStatus === "R" || indexStatus === "C" || worktreeStatus === "R" || worktreeStatus === "C";
|
|
}
|
|
|
|
export function parseGitPorcelainV1(output: string): GitPorcelainEntry[] {
|
|
const records = output.split("\0");
|
|
const entries: GitPorcelainEntry[] = [];
|
|
|
|
for (let i = 0; i < records.length; i++) {
|
|
const record = records[i];
|
|
if (!record || record.length < 4 || record[2] !== " ") continue;
|
|
const indexStatus = record[0];
|
|
const worktreeStatus = record[1];
|
|
const entry: GitPorcelainEntry = {
|
|
path: record.slice(3),
|
|
indexStatus,
|
|
worktreeStatus,
|
|
};
|
|
if (usesRenamePath(indexStatus, worktreeStatus)) {
|
|
entry.originalPath = records[++i] || undefined;
|
|
}
|
|
entries.push(entry);
|
|
}
|
|
|
|
return entries;
|
|
}
|
|
|
|
const CONFLICT_STATUSES = new Set(["DD", "AU", "UD", "UA", "DU", "AA", "UU"]);
|
|
|
|
export function classifyGitStatus(entry: GitPorcelainEntry): Pick<GitFileStatus, "status" | "code"> {
|
|
const pair = `${entry.indexStatus}${entry.worktreeStatus}`;
|
|
if (pair === "??") return { status: "untracked", code: "U" };
|
|
if (CONFLICT_STATUSES.has(pair) || pair.includes("U")) return { status: "conflict", code: "C" };
|
|
if (pair.includes("D")) return { status: "deleted", code: "D" };
|
|
if (pair.includes("R") || pair.includes("C")) return { status: "renamed", code: "R" };
|
|
if (pair.includes("A")) return { status: "added", code: "A" };
|
|
return { status: "modified", code: "M" };
|
|
}
|