1import { spawnSync } from "node:child_process"
2
3// Returns stdout untouched: a patch ends in newlines and can end in a context
4// line that is a single space, so trimming it corrupts the patch.
5const gitRaw = (cwd, args, input) => {
6 const result = spawnSync("git", args, {
7 cwd,
8 encoding: "utf8",
9 maxBuffer: 50 * 1024 * 1024,
10 input
11 })
12 if (result.error) throw result.error
13 if (result.status !== 0) {
14 throw new Error(`${result.stdout}${result.stderr}`.trim())
15 }
16 return result.stdout
17}
18
19/** The uncommitted changes to tracked files of `root`, as a binary patch. */
20export const readWorktreeDiff = (root) => gitRaw(root, ["diff", "--binary", "HEAD", "--"])
21
22/** Applies a patch read by `readWorktreeDiff` to the worktree at `root`. */
23export const applyWorktreeDiff = (root, diff) => {
24 if (diff !== "") gitRaw(root, ["apply", "--binary", "-"], diff)
25}