110 lines · 3.5 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,
  }).trim();
}

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[];
}

export const getLog = createServerFn({ method: "POST" })
  .inputValidator((d: { count?: number; skip?: number }) => d)
  .handler(async ({ data }) => {
    const count = data.count ?? 50;
    const skip = data.skip ?? 0;
    const raw = git(["log", "--format=%H%x00%h%x00%an%x00%ai%x00%s", "-n", String(count), `--skip=${skip}`]);
    if (!raw) return [] as CommitInfo[];
    return raw.split("\n").map((line): CommitInfo => {
      const [hash, shortHash, author, date, message] = line.split("\x00");
      return { hash, shortHash, author, date, message };
    });
  });