فهرست منبع

improve snapshotting speed further

Dax Raad 9 ماه پیش
والد
کامیت
571d60182a
3فایلهای تغییر یافته به همراه45 افزوده شده و 72 حذف شده
  1. 5 0
      bun.lock
  2. 0 1
      packages/opencode/.gitignore
  3. 40 71
      packages/opencode/src/snapshot/index.ts

+ 5 - 0
bun.lock

@@ -31,6 +31,7 @@
         "@openauthjs/openauth": "0.4.3",
         "@standard-schema/spec": "1.0.0",
         "ai": "catalog:",
+        "air": "0.4.14",
         "decimal.js": "10.5.0",
         "diff": "8.0.2",
         "env-paths": "3.0.0",
@@ -516,6 +517,8 @@
 
     "ai": ["[email protected]", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8", "@ai-sdk/react": "1.2.12", "@ai-sdk/ui-utils": "1.2.11", "@opentelemetry/api": "1.9.0", "jsondiffpatch": "0.6.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.23.8" }, "optionalPeers": ["react"] }, "sha512-KUDwlThJ5tr2Vw0A1ZkbDKNME3wzWhuVfAOwIvFUzl1TPVDFAXDFTXio3p+jaKneB+dKNCvFFlolYmmgHttG1g=="],
 
+    "air": ["[email protected]", "", { "dependencies": { "zephyr": "~1.3.5" } }, "sha512-E8bl9LlSGSQqjxxjeGIrpYpf8jVyJplsdK1bTobh61F7ks+3aLeXL4KbGSJIFsiaSSz5ZExLU51DGztmQSlZTQ=="],
+
     "ansi-align": ["[email protected]", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
 
     "ansi-regex": ["[email protected]", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
@@ -1700,6 +1703,8 @@
 
     "youch": ["[email protected]", "", { "dependencies": { "cookie": "^0.7.1", "mustache": "^4.2.0", "stacktracey": "^2.1.8" } }, "sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg=="],
 
+    "zephyr": ["[email protected]", "", {}, "sha512-oYH52DGZzIbXNrkijskaR8YpVKnXAe8jNgH1KirglVBnTFOn6mK9/0SVCxGn+73l0Hjhr4UYNzYkO07LXSWy6w=="],
+
     "zod": ["[email protected]", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="],
 
     "zod-openapi": ["[email protected]", "", { "peerDependencies": { "zod": "^3.21.4" } }, "sha512-tsrQpbpqFCXqVXUzi3TPwFhuMtLN3oNZobOtYnK6/5VkXsNdnIgyNr4r8no4wmYluaxzN3F7iS+8xCW8BmMQ8g=="],

+ 0 - 1
packages/opencode/.gitignore

@@ -1,4 +1,3 @@
-node_modules
 research
 dist
 gen

+ 40 - 71
packages/opencode/src/snapshot/index.ts

@@ -1,14 +1,7 @@
 import { App } from "../app/app"
-import {
-  add,
-  commit,
-  init,
-  checkout,
-  statusMatrix,
-  remove,
-} from "isomorphic-git"
+import { $ } from "bun"
 import path from "path"
-import fs from "fs"
+import fs from "fs/promises"
 import { Ripgrep } from "../file/ripgrep"
 import { Log } from "../util/log"
 
@@ -19,76 +12,52 @@ export namespace Snapshot {
     log.info("creating snapshot")
     const app = App.info()
     const git = gitdir(sessionID)
-    const files = await Ripgrep.files({
-      cwd: app.path.cwd,
-      limit: app.git ? undefined : 1000,
-    })
-    log.info("found files", { count: files.length })
-    // not a git repo and too big to snapshot
-    if (!app.git && files.length === 1000) return
-    await init({
-      dir: app.path.cwd,
-      gitdir: git,
-      fs,
-    })
-    log.info("initialized")
-    const status = await statusMatrix({
-      fs,
-      gitdir: git,
-      dir: app.path.cwd,
-    })
-    log.info("matrix", {
-      count: status.length,
-    })
-    const added = []
-    for (const [file, head, workdir, stage] of status) {
-      if (workdir === 0 && stage === 1) {
-        log.info("remove", { file })
-        await remove({
-          fs,
-          gitdir: git,
-          dir: app.path.cwd,
-          filepath: file,
+
+    // not a git repo, check if too big to snapshot
+    if (!app.git) {
+      const files = await Ripgrep.files({
+        cwd: app.path.cwd,
+        limit: 1000,
+      })
+      log.info("found files", { count: files.length })
+      if (files.length > 1000) return
+    }
+
+    if (await fs.mkdir(git, { recursive: true })) {
+      await $`git init`
+        .env({
+          ...process.env,
+          GIT_DIR: git,
+          GIT_WORK_TREE: app.path.root,
         })
-        continue
-      }
-      if (workdir !== head) {
-        added.push(file)
-      }
+        .quiet()
+        .nothrow()
+      log.info("initialized")
     }
-    log.info("removed files")
-    await add({
-      fs,
-      gitdir: git,
-      parallel: true,
-      dir: app.path.cwd,
-      filepath: added,
-    })
+
+    await $`git --git-dir ${git} add .`.quiet().cwd(app.path.cwd).nothrow()
     log.info("added files")
-    const result = await commit({
-      fs,
-      gitdir: git,
-      dir: app.path.cwd,
-      message: "snapshot",
-      author: {
-        name: "opencode",
-        email: "[email protected]",
-      },
-    })
-    log.info("commit", { result })
-    return result
+
+    const result =
+      await $`git --git-dir ${git} commit --allow-empty -m "snapshot" --author="opencode <[email protected]>"`
+        .quiet()
+        .cwd(app.path.cwd)
+        .nothrow()
+    log.info("commit")
+
+    // Extract commit hash from output like "[main abc1234] snapshot"
+    const match = result.stdout.toString().match(/\[.+ ([a-f0-9]+)\]/)
+    if (!match) throw new Error("Failed to extract commit hash")
+    return match[1]
   }
 
   export async function restore(sessionID: string, commit: string) {
     log.info("restore", { commit })
     const app = App.info()
-    await checkout({
-      fs,
-      gitdir: gitdir(sessionID),
-      dir: app.path.cwd,
-      ref: commit,
-      force: true,
-    })
+    const git = gitdir(sessionID)
+    await $`git --git-dir=${git} checkout ${commit} --force`
+      .quiet()
+      .cwd(app.path.root)
   }
 
   function gitdir(sessionID: string) {