131 lines · 4.1 KB
import { createServerFn } from "@tanstack/react-start";
import { execFileSync } from "node:child_process";

const REPO_PATH = process.env.GITUI_REPO_PATH || process.cwd();

function git(args: string[]): string {
  return execFileSync("git", args, {
    cwd: REPO_PATH,
    encoding: "utf-8",
    maxBuffer: 10 * 1024 * 1024,
  }).replace(/[\r\n]+$/, "");
}

function assertSafeRevision(value: string, label: string): void {
  if (!value || value.startsWith("-")) {
    throw new Error(`Invalid ${label}: must be non-empty and must not start with "-"`);
  }
}

export interface CommitInfo {
  hash: string;
  shortHash: string;
  author: string;
  date: string;
  message: string;
}

export interface GitStatus {
  staged: Array<{ status: string; path: string }>;
  unstaged: Array<{ status: string; path: string }>;
  untracked: string[];
}

function parseStatus(raw: string): GitStatus {
  const staged: GitStatus["staged"] = [];
  const unstaged: GitStatus["unstaged"] = [];
  const untracked: string[] = [];
  const entries = raw.split("\0").filter(Boolean);

  for (let index = 0; index < entries.length; index++) {