mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-08 21:01:54 +01:00
fix(workspaces): inspect retained indexes before Git probes
Read managed Git metadata before starting Git commands. Keep the synthetic orphan index locked so unrelated Git maintenance cannot prune the regression fixture before inspection. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
16a646ba7a
commit
9f42901683
2 files changed
+3
-2
No files matched your search
@@ -43,7 +43,7 @@ async function git(cwd: string, args: string[]) {
|
|||||||
|
|
||||||
async function assertNoRetainedWorktree(sourcePath: string, expected: string, branch: string) {
|
async function assertNoRetainedWorktree(sourcePath: string, expected: string, branch: string) {
|
||||||
const target = await physicalPath(expected);
|
const target = await physicalPath(expected);
|
||||||
const common = await git(sourcePath, ["rev-parse", "--path-format=absolute", "--git-common-dir"]);
|
const common = path.join(sourcePath, ".git");
|
||||||
const admin = path.join(common, "worktrees");
|
const admin = path.join(common, "worktrees");
|
||||||
const entries = await fs.readdir(admin, { withFileTypes: true }).catch((error: NodeJS.ErrnoException) => {
|
const entries = await fs.readdir(admin, { withFileTypes: true }).catch((error: NodeJS.ErrnoException) => {
|
||||||
if (error.code === "ENOENT") return [];
|
if (error.code === "ENOENT") return [];
|
||||||
@@ -118,6 +118,7 @@ export async function inspectArchivedGitMigrationSource(db: Pick<Db, "select">,
|
|||||||
// not certify lost untracked files. Any surviving worktree registration
|
// not certify lost untracked files. Any surviving worktree registration
|
||||||
// can retain additional index/files authority and must stay blocked.
|
// can retain additional index/files authority and must stay blocked.
|
||||||
if (workspace.mode !== "isolated_workspace" || !workspace.projectId || !managedSourcePaths(workspace).includes(sourcePath)) return null;
|
if (workspace.mode !== "isolated_workspace" || !workspace.projectId || !managedSourcePaths(workspace).includes(sourcePath)) return null;
|
||||||
|
await assertNoRetainedWorktree(sourcePath, path.join(sourcePath, ".paperclip", "worktrees", workspace.branchName), workspace.branchName);
|
||||||
await git(sourcePath, ["check-ref-format", `refs/heads/${workspace.branchName}`]);
|
await git(sourcePath, ["check-ref-format", `refs/heads/${workspace.branchName}`]);
|
||||||
const expected = path.join(sourcePath, ".paperclip", "worktrees", workspace.branchName);
|
const expected = path.join(sourcePath, ".paperclip", "worktrees", workspace.branchName);
|
||||||
if (workspace.cwd !== expected || workspace.providerRef && workspace.providerRef !== expected) return null;
|
if (workspace.cwd !== expected || workspace.providerRef && workspace.providerRef !== expected) return null;
|
||||||
@@ -147,7 +148,6 @@ export async function inspectArchivedGitMigrationSource(db: Pick<Db, "select">,
|
|||||||
ne(executionWorkspaces.id, workspace.id),
|
ne(executionWorkspaces.id, workspace.id),
|
||||||
)).limit(1);
|
)).limit(1);
|
||||||
if (other) throw unavailable();
|
if (other) throw unavailable();
|
||||||
await assertNoRetainedWorktree(sourcePath, expected, workspace.branchName);
|
|
||||||
const commit = await git(sourcePath, ["rev-parse", "--verify", `refs/heads/${workspace.branchName}^{commit}`]);
|
const commit = await git(sourcePath, ["rev-parse", "--verify", `refs/heads/${workspace.branchName}^{commit}`]);
|
||||||
if (!/^[a-f0-9]{40}$/.test(commit)) throw unavailable();
|
if (!/^[a-f0-9]{40}$/.test(commit)) throw unavailable();
|
||||||
return { commit, sourcePath, cleanupOperationId: removalId, recipe: null, retainedBranch: workspace.branchName };
|
return { commit, sourcePath, cleanupOperationId: removalId, recipe: null, retainedBranch: workspace.branchName };
|
||||||
|
|||||||
@@ -597,6 +597,7 @@ describe.skipIf(!support.supported)("remote workspace migration", () => {
|
|||||||
if (mode === "orphan-index") {
|
if (mode === "orphan-index") {
|
||||||
const admin = path.join(f.base, ".git", "worktrees", "orphan");
|
const admin = path.join(f.base, ".git", "worktrees", "orphan");
|
||||||
await fs.mkdir(admin, { recursive: true }); await fs.copyFile(path.join(f.base, ".git", "index"), path.join(admin, "index"));
|
await fs.mkdir(admin, { recursive: true }); await fs.copyFile(path.join(f.base, ".git", "index"), path.join(admin, "index"));
|
||||||
|
await fs.writeFile(path.join(admin, "locked"), "retained staged recovery work\n");
|
||||||
}
|
}
|
||||||
if (mode === "changed-branch") {
|
if (mode === "changed-branch") {
|
||||||
const put = storage.putFile.bind(storage);
|
const put = storage.putFile.bind(storage);
|
||||||
|
|||||||
Reference in new issue
Block a user