| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- import { App } from "../app/app"
- import { $ } from "bun"
- import path from "path"
- import fs from "fs/promises"
- import { Ripgrep } from "../file/ripgrep"
- import { Log } from "../util/log"
- export namespace Snapshot {
- const log = Log.create({ service: "snapshot" })
- export async function create(sessionID: string) {
- log.info("creating snapshot")
- const app = App.info()
- // not a git repo, check if too big to snapshot
- if (!app.git) {
- return
- const files = await Ripgrep.files({
- cwd: app.path.cwd,
- limit: 1000,
- })
- log.info("found files", { count: files.length })
- if (files.length >= 1000) return
- }
- const git = gitdir(sessionID)
- if (await fs.mkdir(git, { recursive: true })) {
- await $`git init`
- .env({
- ...process.env,
- GIT_DIR: git,
- GIT_WORK_TREE: app.path.root,
- })
- .quiet()
- .nothrow()
- log.info("initialized")
- }
- await $`git --git-dir ${git} add .`.quiet().cwd(app.path.cwd).nothrow()
- log.info("added files")
- const result =
- await $`git --git-dir ${git} commit -m "snapshot" --no-gpg-sign --author="opencode <[email protected]>"`
- .quiet()
- .cwd(app.path.cwd)
- .nothrow()
- const match = result.stdout.toString().match(/\[.+ ([a-f0-9]+)\]/)
- if (!match) return
- return match![1]
- }
- export async function restore(sessionID: string, snapshot: string) {
- log.info("restore", { commit: snapshot })
- const app = App.info()
- const git = gitdir(sessionID)
- await $`git --git-dir=${git} checkout ${snapshot} --force`.quiet().cwd(app.path.root)
- }
- export async function diff(sessionID: string, commit: string) {
- const git = gitdir(sessionID)
- const result = await $`git --git-dir=${git} diff -R ${commit}`.quiet().cwd(App.info().path.root)
- return result.stdout.toString("utf8")
- }
- function gitdir(sessionID: string) {
- const app = App.info()
- return path.join(app.path.data, "snapshot", sessionID)
- }
- }
|