175 lines · 6.8 KB
import { mergeBudget, mergeRootTrees } from "./git/merge";
import type { MergeSource } from "./git/merge";
import { MergeTooComplexError } from "./git/merge3";
import { makeCommit, signatureNow } from "./git/objects";
import type { RawObject } from "./git/objects";
import { compareCommits } from "./git/history";
import type { GitStore } from "./git/store";
import { pushToArtifacts, PushRejectedError } from "./git/writer";
import { currentBaseSha, loadPullRepos, withPullStore } from "./pull-merge";
import type { Landed } from "./pull-merge";
import { MergeError } from "./pulls";
import type { PullRow } from "./pulls";
import type { CommitSummary } from "~/lib/types";

const MAX_REBASE_COMMITS = 100;
const MAX_REBASE_TREE_READS = 3000;
const MAX_REBASE_CONTENT_MERGES = 400;
const SHA_BYTES = 20;
const decoder = new TextDecoder();

type Entry = { name: string; mode: string; hash: string };

function hex(bytes: Uint8Array): string {
  return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
}

function parseTree(content: Uint8Array): Entry[] {
  const entries: Entry[] = [];
  let offset = 0;
  while (offset < content.byteLength) {
    const space = content.indexOf(0x20, offset);
    const nul = content.indexOf(0, space);
    const mode = decoder.decode(content.subarray(offset, space));
    const name = decoder.decode(content.subarray(space + 1, nul));
    entries.push({ name, mode, hash: hex(content.subarray(nul + 1, nul + 1 + SHA_BYTES)) });
    offset = nul + 1 + SHA_BYTES;
  }
  return entries;
}