summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-07-03 21:17:15 -0400
committerDax Raad <[email protected]>2025-07-03 21:36:09 -0400
commit571d60182a011cc2c71c451d3ddb3243b72cbbd8 (patch)
tree8d07eb97a911d23a145d648b4b694f3da2bd8ff4
parent167a9dcaf312c2ceda2ed43e0adecf33d5e98c60 (diff)
downloadopencode-571d60182a011cc2c71c451d3ddb3243b72cbbd8.tar.gz
opencode-571d60182a011cc2c71c451d3ddb3243b72cbbd8.zip
improve snapshotting speed further
-rw-r--r--bun.lock5
-rw-r--r--packages/opencode/.gitignore1
-rw-r--r--packages/opencode/src/snapshot/index.ts111
3 files changed, 45 insertions, 72 deletions
diff --git a/bun.lock b/bun.lock
index 200e0587e..a723e36be 100644
--- a/bun.lock
+++ b/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=="],
diff --git a/packages/opencode/.gitignore b/packages/opencode/.gitignore
index 66857d897..e057ca61f 100644
--- a/packages/opencode/.gitignore
+++ b/packages/opencode/.gitignore
@@ -1,4 +1,3 @@
-node_modules
research
dist
gen
diff --git a/packages/opencode/src/snapshot/index.ts b/packages/opencode/src/snapshot/index.ts
index fcf77c459..95d7776c6 100644
--- a/packages/opencode/src/snapshot/index.ts
+++ b/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) {