summaryrefslogtreecommitdiffhomepage
path: root/packages
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 /packages
parent167a9dcaf312c2ceda2ed43e0adecf33d5e98c60 (diff)
downloadopencode-571d60182a011cc2c71c451d3ddb3243b72cbbd8.tar.gz
opencode-571d60182a011cc2c71c451d3ddb3243b72cbbd8.zip
improve snapshotting speed further
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/.gitignore1
-rw-r--r--packages/opencode/src/snapshot/index.ts111
2 files changed, 40 insertions, 72 deletions
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) {