# Files changed · PR \#16734 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/16734/diffs)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

[feat\(server\): package and apply a thread's git work](https://git.cafe/pingdotgg/t3code/pull/16734.md)

Version: 15

Head commit: 75b2c90834b04ac7254bb95a713fd1c39a047384

Base commit: 48dea790a657af09a50d188a5092ada32bab8542

Comparison base: 48dea790a657af09a50d188a5092ada32bab8542

Showing up to 20 entries from this revision. If the pull request changes, reopen the first page before continuing.

## apps/server/src/peer/handoff/HandoffGit.test.ts

Status: added; +399; −0

```diff
@@ -1,0 +1,399 @@
+import * as NodeServices from "@effect/platform-node/NodeServices";
+import { assert, it } from "@effect/vitest";
+import * as Crypto from "effect/Crypto";
+import * as Effect from "effect/Effect";
+import * as FileSystem from "effect/FileSystem";
+import * as Layer from "effect/Layer";
+import * as Path from "effect/Path";
+
+import * as VcsProcess from "../../vcs/VcsProcess.ts";
+import * as HandoffGit from "./HandoffGit.ts";
+
+// A thread's git work moves from the laptop's checkout to the box's clone of
+// the same repository: the commits the remote lacks, the edits, the deletes
+// and the new files, exactly, and nothing on the box is overwritten.
+
+const layer = HandoffGit.layer.pipe(
+  Layer.provideMerge(VcsProcess.layer),
+  Layer.provideMerge(NodeServices.layer),
+);
+
+const sh = (cwd: string, args: ReadonlyArray<string>) =>
+  VcsProcess.VcsProcess.pipe(
+    Effect.flatMap((processes) =>
+      processes.run({
+        operation: "HandoffGit.test",
+        command: "git",
+        cwd,
+        args,
+        env: {
+          ...process.env,
+          GIT_AUTHOR_NAME: "Test",
+          GIT_AUTHOR_EMAIL: "test@example.com",
+          GIT_COMMITTER_NAME: "Test",
+          GIT_COMMITTER_EMAIL: "test@example.com",
+        },
+      }),
+    ),
+    Effect.map((result) => result.stdout.trim()),
+    Effect.orDie,
+  );
+
+/** `git status --porcelain`, sorted; untrimmed, since its first column is a space. */
+const status = (cwd: string) =>
+  VcsProcess.VcsProcess.pipe(
+    Effect.flatMap((processes) =>
+      processes.run({
+        operation: "HandoffGit.test",
+        command: "git",
+        cwd,
+        args: ["status", "--porcelain"],
+      }),
+    ),
+    Effect.map((result) =>
+      result.stdout
+        .split("\n")
+        .filter((line) => line !== "")
+        .sort(),
+    ),
+    Effect.orDie,
+  );
+
+/** An origin with one commit on main, and the laptop's and the box's clones of it. */
+const repos = Effect.gen(function* () {
+  const fileSystem = yield* FileSystem.FileSystem;
+  const path = yield* Path.Path;
+  const root = yield* fileSystem.makeTempDirectoryScoped({ prefix: "t3-handoff-git-" });
+  const origin = path.join(root, "origin.git");
+  const seed = path.join(root, "seed");
+  yield* fileSystem.makeDirectory(seed);
+  yield* sh(root, ["init", "--quiet", "--bare", "--initial-branch=main", origin]);
+  yield* sh(seed, ["init", "--quiet", "--initial-branch=main"]);
+  yield* fileSystem.writeFileString(path.join(seed, "app.ts"), "export const version = 1;\n");
+  yield* fileSystem.writeFileString(path.join(seed, "old.ts"), "export const gone = true;\n");
+  yield* sh(seed, ["add", "."]);
+  yield* sh(seed, ["commit", "--quiet", "-m", "start"]);
+  yield* sh(seed, ["remote", "add", "origin", origin]);
+  yield* sh(seed, ["push", "--quiet", "origin", "main"]);
+  const laptop = path.join(root, "laptop");
+  const box = path.join(root, "box");
+  yield* sh(root, ["clone", "--quiet", origin, laptop]);
+  yield* sh(root, ["clone", "--quiet", origin, box]);
+  const outDir = path.join(root, "out");
+  yield* fileSystem.makeDirectory(outDir);
+  return { root, origin, laptop, box, outDir };
+});
+
+/** The laptop's thread: an unpushed commit on a branch, then uncommitted work. */
+const workOnLaptop = (laptop: string) =>
+  Effect.gen(function* () {
+    const fileSystem = yield* FileSystem.FileSystem;
+    const path = yield* Path.Path;
+    yield* sh(laptop, ["checkout", "--quiet", "-b", "fix/login"]);
+    yield* fileSystem.writeFileString(path.join(laptop, "app.ts"), "export const version = 2;\n");
+    yield* sh(laptop, ["commit", "--quiet", "-am", "unpushed: bump version"]);
+    yield* fileSystem.writeFileString(path.join(laptop, "app.ts"), "export const version = 3;\n");
+    yield* fileSystem.remove(path.join(laptop, "old.ts"));
+    yield* fileSystem.writeFileString(path.join(laptop, "new.ts"), "export const fresh = true;\n");
+    yield* fileSystem.writeFileString(path.join(laptop, ".env"), "SECRET=1\n");
+    yield* fileSystem.writeFileString(path.join(laptop, ".gitignore"), ".env\n");
+    yield* sh(laptop, ["add", "new.ts"]);
+  });
+
+it.layer(layer)("handing a thread's git work to another checkout", (it) => {
+  it.effect("carries an unpushed commit, edits, deletes and new files exactly", () =>
+    Effect.scoped(
+      Effect.gen(function* () {
+        const fileSystem = yield* FileSystem.FileSystem;
+        const path = yield* Path.Path;
+        const handoff = yield* HandoffGit.HandoffGit;
+        const { laptop, box, outDir, root } = yield* repos;
+        yield* workOnLaptop(laptop);
+        const stagedBefore = yield* sh(laptop, ["diff", "--cached", "--name-only"]);
+
+        const packed = yield* handoff.pack({ cwd: laptop, handoffId: "h1", outDir });
+        assert.equal(packed.branch, "fix/login");
+        // Packing leaves the laptop's own staging and refs as they were.
+        assert.equal(yield* sh(laptop, ["diff", "--cached", "--name-only"]), stagedBefore);
+        assert.equal(yield* sh(laptop, ["for-each-ref", "refs/t3code"]), "");
+
+        const worktree = path.join(root, "box-worktree");
+        const applied = yield* handoff.apply({
+          repoRoot: box,
+          worktreePath: worktree,
+          handoffId: "h1",
+          bundlePath: packed.bundlePath,
+          branch: packed.branch,
+          tip: packed.tip,
+          snapshot: packed.snapshot,
+        });
+        assert.equal(applied.branch, "fix/login");
+        // The committed work, unpushed on the laptop, is the branch here.
+        assert.equal(yield* sh(worktree, ["rev-parse", "HEAD"]), packed.tip);
+        assert.equal(yield* sh(worktree, ["log", "-1", "--format=%s"]), "unpushed: bump version");
+        // The working tree matches, and shows as uncommitted.
+        assert.equal(
+          yield* fileSystem.readFileString(path.join(worktree, "app.ts")),
+          "export const version = 3;\n",
+        );
+        assert.isFalse(yield* fileSystem.exists(path.join(worktree, "old.ts")));
+        assert.equal(
+          yield* fileSystem.readFileString(path.join(worktree, "new.ts")),
+          "export const fresh = true;\n",
+        );
+        assert.deepEqual(yield* status(worktree), [
+          " D old.ts",
+          " M app.ts",
+          "?? .gitignore",
+          "?? new.ts",
+        ]);
+        // Ignored files stay where they were.
+        assert.isFalse(yield* fileSystem.exists(path.join(worktree, ".env")));
+        assert.equal(yield* sh(box, ["for-each-ref", "refs/t3code"]), "");
+      }),
+    ),
+  );
+
+  it.effect("refuses a branch that moved on here, and leaves everything as it was", () =>
+    Effect.scoped(
+      Effect.gen(function* () {
+        const fileSystem = yield* FileSystem.FileSystem;
+        const path = yield* Path.Path;
+        const handoff = yield* HandoffGit.HandoffGit;
+        const { laptop, box, outDir, root } = yield* repos;
+        yield* workOnLaptop(laptop);
+        const packed = yield* handoff.pack({ cwd: laptop, handoffId: "h2", outDir });
+
+        // The box has its own commit on the same branch.
+        yield* sh(box, ["checkout", "--quiet", "-b", "fix/login"]);
+        yield* fileSystem.writeFileString(path.join(box, "box.ts"), "export const mine = 1;\n");
+        yield* sh(box, ["add", "."]);
+        yield* sh(box, ["commit", "--quiet", "-m", "box-only work"]);
+        yield* sh(box, ["checkout", "--quiet", "main"]);
+        const boxBranch = yield* sh(box, ["rev-parse", "fix/login"]);
+        const worktreesBefore = yield* sh(box, ["worktree", "list", "--porcelain"]);
+
+        const refused = yield* handoff
+          .apply({
+            repoRoot: box,
+            worktreePath: path.join(root, "box-worktree"),
+            handoffId: "h2",
+            bundlePath: packed.bundlePath,
+            branch: packed.branch,
+            tip: packed.tip,
+            snapshot: packed.snapshot,
+          })
+          .pipe(Effect.flip);
+        assert.equal(refused._tag, "HandoffBranchDivergedError");
+        assert.equal(yield* sh(box, ["rev-parse", "fix/login"]), boxBranch);
+        assert.equal(yield* sh(box, ["worktree", "list", "--porcelain"]), worktreesBefore);
+        assert.equal(yield* sh(box, ["for-each-ref", "refs/t3code"]), "");
+        assert.isFalse(yield* fileSystem.exists(path.join(root, "box-worktree")));
+      }),
+    ),
+  );
+
+  it.effect("moves a branch that is behind forward, and undoes it when a later step fails", () =>
+    Effect.scoped(
+      Effect.gen(function* () {
+        const fileSystem = yield* FileSystem.FileSystem;
+        const path = yield* Path.Path;
+        const handoff = yield* HandoffGit.HandoffGit;
+        const { laptop, box, outDir, root } = yield* repos;
+        yield* workOnLaptop(laptop);
+        const packed = yield* handoff.pack({ cwd: laptop, handoffId: "h3", outDir });
+        // The box has the branch at main, behind the laptop's tip.
+        yield* sh(box, ["branch", "fix/login", "main"]);
+        const before = yield* sh(box, ["rev-parse", "fix/login"]);
+
+        // The worktree path is taken, so adding the worktree fails after the branch moved.
+        const taken = path.join(root, "taken");
+        yield* fileSystem.makeDirectory(taken);
+        yield* fileSystem.writeFileString(path.join(taken, "keep.txt"), "mine\n");
+        const failed = yield* handoff
+          .apply({
+            repoRoot: box,
+            worktreePath: taken,
+            handoffId: "h3",
+            bundlePath: packed.bundlePath,
+            branch: packed.branch,
+            tip: packed.tip,
+            snapshot: packed.snapshot,
+          })
+          .pipe(Effect.flip);
+        assert.equal(failed._tag, "HandoffGitStepError");
+        assert.equal(yield* sh(box, ["rev-parse", "fix/login"]), before);
+        assert.equal(yield* sh(box, ["for-each-ref", "refs/t3code"]), "");
+        assert.equal(yield* fileSystem.readFileString(path.join(taken, "keep.txt")), "mine\n");
+
+        // With a free path it moves forward and applies.
+        const applied = yield* handoff.apply({
+          repoRoot: box,
+          worktreePath: path.join(root, "box-worktree"),
+          handoffId: "h3",
+          bundlePath: packed.bundlePath,
+          branch: packed.branch,
+          tip: packed.tip,
+          snapshot: packed.snapshot,
+        });
+        assert.equal(applied.branch, "fix/login");
+        assert.equal(yield* sh(box, ["rev-parse", "fix/login"]), packed.tip);
+      }),
+    ),
+  );
+
+  it.effect("carries the whole working tree when the thread sits in a subdirectory", () =>
+    Effect.scoped(
+      Effect.gen(function* () {
+        const fileSystem = yield* FileSystem.FileSystem;
+        const path = yield* Path.Path;
+        const handoff = yield* HandoffGit.HandoffGit;
+        const { laptop, box, outDir, root } = yield* repos;
+        yield* workOnLaptop(laptop);
+        const packages = path.join(laptop, "packages");
+        yield* fileSystem.makeDirectory(packages);
+        yield* fileSystem.writeFileString(path.join(packages, "lib.ts"), "export const lib = 1;\n");
+
+        const packed = yield* handoff.pack({ cwd: packages, handoffId: "h6", outDir });
+        const worktree = path.join(root, "box-worktree");
+        yield* handoff.apply({
+          repoRoot: box,
+          worktreePath: worktree,
+          handoffId: "h6",
+          bundlePath: packed.bundlePath,
+          branch: packed.branch,
+          tip: packed.tip,
+          snapshot: packed.snapshot,
+        });
+        // Edits above the subdirectory travel too, not only those under it.
+        assert.deepEqual(yield* status(worktree), [
+          " D old.ts",
+          " M app.ts",
+          "?? .gitignore",
+          "?? new.ts",
+          "?? packages/",
+        ]);
+      }),
+    ),
+  );
+
+  it.effect("packs the thread's checkout even when the server runs inside another repository", () =>
+    Effect.scoped(
+      Effect.gen(function* () {
+        const handoff = yield* HandoffGit.HandoffGit;
+        const { laptop, box, outDir } = yield* repos;
+        yield* workOnLaptop(laptop);
+        const boxGitDir = yield* sh(box, ["rev-parse", "--path-format=absolute", "--git-dir"]);
+        // As when the server is started from a git hook in the box's clone.
+        yield* Effect.acquireRelease(
+          Effect.sync(() => {
+            const before = process.env.GIT_DIR;
+            process.env.GIT_DIR = boxGitDir;
+            return before;
+          }),
+          (before) =>
+            Effect.sync(() => {
+              if (before === undefined) delete process.env.GIT_DIR;
+              else process.env.GIT_DIR = before;
+            }),
+        );
+        const packed = yield* handoff.pack({ cwd: laptop, handoffId: "h8", outDir });
+        assert.equal(packed.branch, "fix/login");
+      }),
+    ),
+  );
+
+  it.effect("keeps a branch it created when someone moved it before a later step failed", () =>
+    Effect.scoped(
+      Effect.gen(function* () {
+        const handoff = yield* HandoffGit.HandoffGit;
+        const { laptop, box, outDir } = yield* repos;
+        yield* workOnLaptop(laptop);
+        const packed = yield* handoff.pack({ cwd: laptop, handoffId: "h7", outDir });
+        // A hook that fires when the worktree is checked out moves the branch
+        // the apply just created, then fails the checkout.
+        const hooks = yield* sh(box, [
+          "rev-parse",
+          "--path-format=absolute",
+          "--git-path",
+          "hooks",
+        ]);
+        const fileSystem = yield* FileSystem.FileSystem;
+        const path = yield* Path.Path;
+        const moved = yield* sh(box, ["rev-parse", "main"]);
+        const hook = path.join(hooks, "post-checkout");
+        yield* fileSystem.makeDirectory(hooks, { recursive: true });
+        yield* fileSystem.writeFileString(
+          hook,
+          `#!/bin/sh\ngit -C "${box}" update-ref refs/heads/fix/login ${moved}\nexit 1\n`,
+        );
+        yield* fileSystem.chmod(hook, 0o755);
+
+        const failed = yield* handoff
+          .apply({
+            repoRoot: box,
+            worktreePath: path.join(path.dirname(box), "box-worktree"),
+            handoffId: "h7",
+            bundlePath: packed.bundlePath,
+            branch: packed.branch,
+            tip: packed.tip,
+            snapshot: packed.snapshot,
+          })
+          .pipe(Effect.flip);
+        assert.equal(failed._tag, "HandoffGitStepError");
+        // The rollback left the branch where the other process put it.
+        assert.equal(yield* sh(box, ["rev-parse", "fix/login"]), moved);
+      }),
+    ),
+  );
+
+  it.effect("fetches the base a bundle builds on, and refuses work over the size limit", () =>
+    Effect.scoped(
+      Effect.gen(function* () {
+        const fileSystem = yield* FileSystem.FileSystem;
+        const path = yield* Path.Path;
+        const handoff = yield* HandoffGit.HandoffGit;
+        const { laptop, box, outDir, root } = yield* repos;
+        // The laptop's branch builds on a commit pushed after the box cloned.
+        yield* fileSystem.writeFileString(path.join(laptop, "pushed.ts"), "export const p = 1;\n");
+        yield* sh(laptop, ["add", "."]);
+        yield* sh(laptop, ["commit", "--quiet", "-m", "pushed later"]);
+        // Pushed through the remote, so the laptop knows origin has it and the
+        // bundle leaves it out: the box has to fetch it.
+        yield* sh(laptop, ["push", "--quiet", "origin", "main"]);
+        yield* workOnLaptop(laptop);
+        const packed = yield* handoff.pack({ cwd: laptop, handoffId: "h4", outDir });
+        assert.isFalse(
+          (yield* sh(packed.bundlePath.replace(/\/[^/]+$/, ""), [
+            "bundle",
+            "list-heads",
+            packed.bundlePath,
+          ])).includes(yield* sh(laptop, ["rev-parse", "main"])),
+        );
+        const applied = yield* handoff.apply({
+          repoRoot: box,
+          worktreePath: path.join(root, "box-worktree"),
+          handoffId: "h4",
+          bundlePath: packed.bundlePath,
+          branch: packed.branch,
+          tip: packed.tip,
+          snapshot: packed.snapshot,
+        });
+        assert.equal(applied.branch, "fix/login");
+        assert.isTrue(yield* fileSystem.exists(path.join(root, "box-worktree", "pushed.ts")));
+
+        // An untracked file bigger than a handoff carries, and incompressible.
+        const crypto = yield* Crypto.Crypto;
+        yield* fileSystem.writeFile(
+          path.join(laptop, "big.bin"),
+          yield* crypto.randomBytes(HandoffGit.MAX_HANDOFF_BUNDLE_BYTES + 1024).pipe(Effect.orDie),
+        );
+        const tooLarge = yield* handoff
+          .pack({ cwd: laptop, handoffId: "h5", outDir })
+          .pipe(Effect.flip);
+        assert.equal(tooLarge._tag, "HandoffTooLargeError");
+        assert.isFalse(yield* fileSystem.exists(path.join(outDir, "h5.bundle")));
+      }),
+    ),
+  );
+});
```

## apps/server/src/peer/handoff/HandoffGit.ts

Status: added; +366; −0

```diff
@@ -1,0 +1,366 @@
+import * as Context from "effect/Context";
+import * as Effect from "effect/Effect";
+import * as FileSystem from "effect/FileSystem";
+import * as Layer from "effect/Layer";
+import * as Path from "effect/Path";
+import * as Schema from "effect/Schema";
+
+import * as VcsProcess from "../../vcs/VcsProcess.ts";
+
+/** A bundle larger than one upload can carry is refused; push the branch first. */
+export const MAX_HANDOFF_BUNDLE_BYTES = 50 * 1024 * 1024;
+
+/** The work a thread hands off: its branch tip and the working tree on top of it. */
+export interface HandoffPackage {
+  /** The git bundle: commits not on any remote, plus the snapshot commit. */
+  readonly bundlePath: string;
+  readonly bundleBytes: number;
+  /** The branch the work is on, or null for a detached checkout. */
+  readonly branch: string | null;
+  /** The branch tip. The thread's committed work ends here. */
+  readonly tip: string;
+  /** A commit on top of `tip` holding the working tree, untracked files included. */
+  readonly snapshot: string;
+  /** The remote commit the bundle builds on, for a peer to fetch when it lacks it. */
+  readonly baseRemoteUrl: string | null;
+}
+
+/** `cwd` has no commit to hand off. */
+export class HandoffNotARepositoryError extends Schema.TaggedError<HandoffNotARepositoryError>()(
+  "HandoffNotARepositoryError",
+  { cwd: Schema.String },
+) {
+  override get message(): string {
+    return `${this.cwd} is not a git checkout with a commit.`;
+  }
+}
+
+/** The unpushed work is more than one upload carries. */
+export class HandoffTooLargeError extends Schema.TaggedError<HandoffTooLargeError>()(
+  "HandoffTooLargeError",
+  { bundleBytes: Schema.Number },
+) {
+  override get message(): string {
+    return `The unpushed work is ${Math.ceil(this.bundleBytes / 1024 / 1024)} MiB, over the ${MAX_HANDOFF_BUNDLE_BYTES / 1024 / 1024} MiB a handoff carries. Push the branch, then hand off again.`;
+  }
+}
+
+/** The checkout here lacks the commits the bundle builds on, even after fetching. */
+export class HandoffMissingBaseError extends Schema.TaggedError<HandoffMissingBaseError>()(
+  "HandoffMissingBaseError",
+  {},
+) {
+  override get message(): string {
+    return "This checkout lacks the commits the handoff builds on, even after fetching. Push the branch where it came from, then hand off again.";
+  }
+}
+
+/** The branch is checked out in another worktree here, at another commit. */
+export class HandoffBranchCheckedOutError extends Schema.TaggedError<HandoffBranchCheckedOutError>()(
+  "HandoffBranchCheckedOutError",
+  { branch: Schema.String },
+) {
+  override get message(): string {
+    return `${this.branch} is checked out in another worktree here and differs. Switch that checkout off it, then hand off again.`;
+  }
+}
+
+/** The branch here has commits the handed-off work lacks. */
+export class HandoffBranchDivergedError extends Schema.TaggedError<HandoffBranchDivergedError>()(
+  "HandoffBranchDivergedError",
+  { branch: Schema.String },
+) {
+  override get message(): string {
+    return `${this.branch} here has commits the handed-off work lacks. Reconcile the branches, then hand off again.`;
+  }
+}
+
+/**
+ * A git step failed, or left something other than what the handoff needs.
+ * `step` says which; the git failure, when there is one, is the cause.
+ */
+export class HandoffGitStepError extends Schema.TaggedError<HandoffGitStepError>()(
+  "HandoffGitStepError",
+  {
+    step: Schema.String,
+    detail: Schema.optional(Schema.String),
+    cause: Schema.optional(Schema.Defect()),
+  },
+) {
+  override get message(): string {
+    return this.detail ?? `git ${this.step} failed.`;
+  }
+}
+
+export type HandoffGitError =
+  | HandoffNotARepositoryError
+  | HandoffTooLargeError
+  | HandoffMissingBaseError
+  | HandoffBranchCheckedOutError
+  | HandoffBranchDivergedError
+  | HandoffGitStepError;
+
+/**
+ * Moves a thread's git work between environments as one git bundle: the
+ * commits no remote has, and a snapshot commit of the working tree made with
+ * a temporary index, as checkpoints are. Applying it never touches a
+ * checkout it does not create, moves an existing branch only forward, and
+ * undoes everything it did when a step fails.
+ */
+export class HandoffGit extends Context.Service<
+  HandoffGit,
+  {
+    /** Packages `cwd`'s branch and working tree into a bundle in `outDir`. */
+    readonly pack: (input: {
+      readonly cwd: string;
+      readonly handoffId: string;
+      readonly outDir: string;
+    }) => Effect.Effect<HandoffPackage, HandoffGitError>;
+    /**
+     * Applies a package in `repoRoot`: a new worktree at `worktreePath` on its
+     * branch, with the working tree as it was. Nothing is left behind on failure.
+     */
+    readonly apply: (input: {
+      readonly repoRoot: string;
+      readonly worktreePath: string;
+      readonly handoffId: string;
+      readonly bundlePath: string;
+      readonly branch: string | null;
+      readonly tip: string;
+      readonly snapshot: string;
+    }) => Effect.Effect<{ readonly branch: string | null }, HandoffGitError>;
+  }
+>()("t3/peer/handoff/HandoffGit") {}
+
+const IDENTITY = {
+  GIT_AUTHOR_NAME: "T3 Code",
+  GIT_AUTHOR_EMAIL: "t3code@users.noreply.github.com",
+  GIT_COMMITTER_NAME: "T3 Code",
+  GIT_COMMITTER_EMAIL: "t3code@users.noreply.github.com",
+};
+
+const handoffRef = (handoffId: string, name: string) => `refs/t3code/handoff/${handoffId}/${name}`;
+
+/**
+ * Repository-scoped variables the server may have inherited would point git
+ * at another repository, index or object store than `cwd`'s.
+ */
+const REPOSITORY_ENV = {
+  GIT_DIR: undefined,
+  GIT_WORK_TREE: undefined,
+  GIT_COMMON_DIR: undefined,
+  GIT_INDEX_FILE: undefined,
+  GIT_OBJECT_DIRECTORY: undefined,
+  GIT_ALTERNATE_OBJECT_DIRECTORIES: undefined,
+  GIT_NAMESPACE: undefined,
+  GIT_CEILING_DIRECTORIES: undefined,
+} satisfies NodeJS.ProcessEnv;
+
+const make = Effect.gen(function* () {
+  const processes = yield* VcsProcess.VcsProcess;
+  const fileSystem = yield* FileSystem.FileSystem;
+  const path = yield* Path.Path;
+
+  const git = (
+    cwd: string,
+    args: ReadonlyArray<string>,
+    options: { readonly env?: NodeJS.ProcessEnv; readonly allowNonZeroExit?: boolean } = {},
+  ) =>
+    processes
+      .run({
+        operation: "HandoffGit",
+        command: "git",
+        cwd,
+        args,
+        timeoutMs: 120_000,
+        env: { ...process.env, ...REPOSITORY_ENV, ...options.env },
+        ...(options.allowNonZeroExit === undefined
+          ? {}
+          : { allowNonZeroExit: options.allowNonZeroExit }),
+      })
+      .pipe(
+        Effect.mapError(
+          (cause) =>
+            new HandoffGitStepError({
+              step: args[0] ?? "git",
+              cause,
+            }),
+        ),
+        // The caller sees only the step; git's own reason goes to the log.
+        Effect.tapError((error) =>
+          Effect.logWarning("handoff-git.step-failed", { step: error.step, cause: error.cause }),
+        ),
+      );
+
+  const out = (cwd: string, args: ReadonlyArray<string>) =>
+    git(cwd, args).pipe(Effect.map((result) => result.stdout.trim()));
+
+  const ok = (cwd: string, args: ReadonlyArray<string>) =>
+    git(cwd, args, { allowNonZeroExit: true }).pipe(Effect.map((result) => result.exitCode === 0));
+
+  const pack: HandoffGit["Service"]["pack"] = (input) =>
+    Effect.gen(function* () {
+      if (!(yield* ok(input.cwd, ["rev-parse", "--verify", "HEAD"]))) {
+        return yield* new HandoffNotARepositoryError({ cwd: input.cwd });
+      }
+      const tip = yield* out(input.cwd, ["rev-parse", "HEAD"]);
+      const branchName = yield* git(input.cwd, ["symbolic-ref", "--quiet", "--short", "HEAD"], {
+        allowNonZeroExit: true,
+      });
+      const branch = branchName.exitCode === 0 ? branchName.stdout.trim() : null;
+      const gitDir = yield* out(input.cwd, ["rev-parse", "--path-format=absolute", "--git-dir"]);
+      const indexPath = path.join(gitDir, `t3-handoff-index-${input.handoffId}`);
+      // The working tree as a commit on top of the tip, in a private index so
+      // the user's staging is untouched. Ignored files stay behind.
+      const snapshot = yield* Effect.gen(function* () {
+        const env = { GIT_INDEX_FILE: indexPath, ...IDENTITY };
+        yield* git(input.cwd, ["read-tree", "HEAD"], { env });
+        // `:/` is the whole working tree, wherever in it the thread's checkout sits.
+        yield* git(input.cwd, ["add", "--all", "--", ":/"], { env });
+        const tree = (yield* git(input.cwd, ["write-tree"], { env })).stdout.trim();
+        return (yield* git(
+          input.cwd,
+          ["commit-tree", tree, "-p", tip, "-m", `T3 Code handoff ${input.handoffId}`],
+          { env },
+        )).stdout.trim();
+      }).pipe(
+        Effect.ensuring(
+          Effect.forEach([indexPath, `${indexPath}.lock`], (file) =>
+            fileSystem.remove(file, { force: true }).pipe(Effect.ignore),
+          ),
+        ),
+      );
+      const snapshotRef = handoffRef(input.handoffId, "snapshot");
+      yield* git(input.cwd, ["update-ref", snapshotRef, snapshot]);
+      const bundlePath = path.join(input.outDir, `${input.handoffId}.bundle`);
+      // Only what no remote has: the peer fetches the rest from the remote.
+      yield* git(input.cwd, [
+        "bundle",
+        "create",
+        bundlePath,
+        snapshotRef,
+        "--not",
+        "--remotes",
+      ]).pipe(
+        Effect.ensuring(git(input.cwd, ["update-ref", "-d", snapshotRef]).pipe(Effect.ignore)),
+      );
+      const bundleBytes = Number(
+        (yield* fileSystem.stat(bundlePath).pipe(
+          Effect.mapError(
+            (cause) =>
+              new HandoffGitStepError({
+                step: "bundle",
+                detail: "The bundle was not written.",
+                cause,
+              }),
+          ),
+        )).size,
+      );
+      if (bundleBytes > MAX_HANDOFF_BUNDLE_BYTES) {
+        yield* fileSystem.remove(bundlePath, { force: true }).pipe(Effect.ignore);
+        return yield* new HandoffTooLargeError({ bundleBytes });
+      }
+      const remote = yield* git(input.cwd, ["remote", "get-url", "origin"], {
+        allowNonZeroExit: true,
+      });
+      return {
+        bundlePath,
+        bundleBytes,
+        branch,
+        tip,
+        snapshot,
+        baseRemoteUrl: remote.exitCode === 0 ? remote.stdout.trim() : null,
+      };
+    });
+
+  const apply: HandoffGit["Service"]["apply"] = (input) =>
+    Effect.gen(function* () {
+      const fetched = handoffRef(input.handoffId, "snapshot");
+      const undo: Array<Effect.Effect<void>> = [];
+      // Read when it runs: the steps are pushed as the apply goes.
+      const rollback = Effect.suspend(() =>
+        Effect.forEach(undo.toReversed(), (step) => step, { discard: true }),
+      );
+      return yield* Effect.gen(function* () {
+        // The bundle builds on commits the remote has; fetch them if missing.
+        if (!(yield* ok(input.repoRoot, ["bundle", "verify", input.bundlePath]))) {
+          yield* git(input.repoRoot, ["fetch", "--quiet", "origin"], { allowNonZeroExit: true });
+          if (!(yield* ok(input.repoRoot, ["bundle", "verify", input.bundlePath]))) {
+            return yield* new HandoffMissingBaseError();
+          }
+        }
+        yield* git(input.repoRoot, [
+          "fetch",
+          "--quiet",
+          "--no-tags",
+          input.bundlePath,
+          `${handoffRef(input.handoffId, "snapshot")}:${fetched}`,
+        ]);
+        undo.push(git(input.repoRoot, ["update-ref", "-d", fetched]).pipe(Effect.ignore));
+        if ((yield* out(input.repoRoot, ["rev-parse", fetched])) !== input.snapshot) {
+          return yield* new HandoffGitStepError({
+            step: "fetch",
+            detail: "The bundle does not hold the snapshot it was sent with.",
+          });
+        }
+        // The branch here may only move forward to the tip, and only when no
+        // checkout has it, so nobody's work is overwritten.
+        let branch = input.branch;
+        if (branch !== null) {
+          const ref = `refs/heads/${branch}`;
+          const existing = yield* git(input.repoRoot, ["rev-parse", "--verify", "--quiet", ref], {
+            allowNonZeroExit: true,
+          });
+          if (existing.exitCode === 0) {
+            const current = existing.stdout.trim();
+            const checkedOut = (yield* out(input.repoRoot, ["worktree", "list", "--porcelain"]))
+              .split("\n")
+              .some((line) => line === `branch ${ref}`);
+            if (checkedOut && current !== input.tip) {
+              return yield* new HandoffBranchCheckedOutError({ branch });
+            }
+            if (current !== input.tip) {
+              if (
+                !(yield* ok(input.repoRoot, ["merge-base", "--is-ancestor", current, input.tip]))
+              ) {
+                return yield* new HandoffBranchDivergedError({ branch });
+              }
+              // Compare-and-swap: fails if the branch moved since it was read.
+              yield* git(input.repoRoot, ["update-ref", ref, input.tip, current]);
+              undo.push(
+                git(input.repoRoot, ["update-ref", ref, current, input.tip]).pipe(Effect.ignore),
+              );
+            }
+            if (checkedOut) branch = null;
+          } else {
+            yield* git(input.repoRoot, ["update-ref", ref, input.tip, ""]);
+            // Only while it is still the tip: a branch someone moved on since keeps their commits.
+            undo.push(
+              git(input.repoRoot, ["update-ref", "-d", ref, input.tip]).pipe(Effect.ignore),
+            );
+          }
+        }
+        yield* git(
+          input.repoRoot,
+          branch === null
+            ? ["worktree", "add", "--detach", input.worktreePath, input.tip]
+            : ["worktree", "add", input.worktreePath, branch],
+        );
+        undo.push(
+          git(input.repoRoot, ["worktree", "remove", "--force", input.worktreePath]).pipe(
+            Effect.ignore,
+          ),
+        );
+        // The working tree as it was, untracked files included, then the
+        // index back on the tip so the changes show as uncommitted.
+        yield* git(input.worktreePath, ["checkout", "--no-overlay", input.snapshot, "--", "."]);
+        yield* git(input.worktreePath, ["reset", "--quiet", input.tip]);
+        yield* git(input.repoRoot, ["update-ref", "-d", fetched]).pipe(Effect.ignore);
+        return { branch };
+      }).pipe(Effect.tapError(() => rollback));
+    });
+
+  return HandoffGit.of({ pack, apply });
+});
+
+export const layer = Layer.effect(HandoffGit, make);
```
