summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2026-03-12 23:54:11 -0500
committerGitHub <[email protected]>2026-03-12 23:54:11 -0500
commitf8475649da1cd7a6d49f8f30ee2fad374c2f4fcc (patch)
treeaa1c68e07a436d39537b3219215f4297a50ea795
parentb94e110a4c3d78ee00a81d16fc70faab56eb6e8a (diff)
downloadopencode-f8475649da1cd7a6d49f8f30ee2fad374c2f4fcc.tar.gz
opencode-f8475649da1cd7a6d49f8f30ee2fad374c2f4fcc.zip
chore: cleanup migrate from global code (#17292)
-rw-r--r--packages/opencode/src/project/project.ts33
-rw-r--r--packages/opencode/test/project/migrate-global.test.ts8
2 files changed, 12 insertions, 29 deletions
diff --git a/packages/opencode/src/project/project.ts b/packages/opencode/src/project/project.ts
index 1e14e94d7..d6f7d5a7e 100644
--- a/packages/opencode/src/project/project.ts
+++ b/packages/opencode/src/project/project.ts
@@ -1,12 +1,11 @@
import z from "zod"
import { Filesystem } from "../util/filesystem"
import path from "path"
-import { Database, eq } from "../storage/db"
+import { and, Database, eq } from "../storage/db"
import { ProjectTable } from "./project.sql"
import { SessionTable } from "../session/session.sql"
import { Log } from "../util/log"
import { Flag } from "@/flag/flag"
-import { work } from "../util/queue"
import { fn } from "@opencode-ai/util/fn"
import { BusEvent } from "@/bus/bus-event"
import { iife } from "@/util/iife"
@@ -276,7 +275,13 @@ export namespace Project {
// Runs on every startup because sessions created before git init
// accumulate under "global" and need migrating whenever they appear.
if (data.id !== ProjectID.global) {
- await migrateFromGlobal(data.id, data.worktree)
+ Database.use((db) =>
+ db
+ .update(SessionTable)
+ .set({ project_id: data.id })
+ .where(and(eq(SessionTable.project_id, ProjectID.global), eq(SessionTable.directory, data.worktree)))
+ .run(),
+ )
}
GlobalBus.emit("event", {
payload: {
@@ -311,28 +316,6 @@ export namespace Project {
return
}
- async function migrateFromGlobal(id: ProjectID, worktree: string) {
- const row = Database.use((db) => db.select().from(ProjectTable).where(eq(ProjectTable.id, ProjectID.global)).get())
- if (!row) return
-
- const sessions = Database.use((db) =>
- db.select().from(SessionTable).where(eq(SessionTable.project_id, ProjectID.global)).all(),
- )
- if (sessions.length === 0) return
-
- log.info("migrating sessions from global", { newProjectID: id, worktree, count: sessions.length })
-
- await work(10, sessions, async (row) => {
- // Skip sessions that belong to a different directory
- if (row.directory && row.directory !== worktree) return
-
- log.info("migrating session", { sessionID: row.id, from: ProjectID.global, to: id })
- Database.use((db) => db.update(SessionTable).set({ project_id: id }).where(eq(SessionTable.id, row.id)).run())
- }).catch((error) => {
- log.error("failed to migrate sessions from global to project", { error, projectId: id })
- })
- }
-
export function setInitialized(id: ProjectID) {
Database.use((db) =>
db
diff --git a/packages/opencode/test/project/migrate-global.test.ts b/packages/opencode/test/project/migrate-global.test.ts
index 77e0a1d77..b66653f70 100644
--- a/packages/opencode/test/project/migrate-global.test.ts
+++ b/packages/opencode/test/project/migrate-global.test.ts
@@ -100,14 +100,15 @@ describe("migrateFromGlobal", () => {
expect(row!.project_id).toBe(project.id)
})
- test("migrates sessions with empty directory", async () => {
+ test("does not claim sessions with empty directory", async () => {
await using tmp = await tmpdir({ git: true })
const { project } = await Project.fromDirectory(tmp.path)
expect(project.id).not.toBe(ProjectID.global)
ensureGlobal()
- // Legacy sessions may lack a directory value
+ // Legacy sessions may lack a directory value.
+ // Without a matching origin directory, they should remain global.
const id = uid()
seed({ id, dir: "", project: ProjectID.global })
@@ -115,8 +116,7 @@ describe("migrateFromGlobal", () => {
const row = Database.use((db) => db.select().from(SessionTable).where(eq(SessionTable.id, id)).get())
expect(row).toBeDefined()
- // Empty directory means "no known origin" — should be claimed
- expect(row!.project_id).toBe(project.id)
+ expect(row!.project_id).toBe(ProjectID.global)
})
test("does not steal sessions from unrelated directories", async () => {