From cda5e84147c6fe5bb21faeda2083862c958a9880 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 5 May 2026 05:26:07 +0000 Subject: [PATCH 1/2] Fix external package publish ancestry check Co-authored-by: Kent C. Dodds --- .../src/repo/repo-session-do.node.test.ts | 40 +++++++++++++++++++ packages/worker/src/repo/repo-session-do.ts | 10 ++--- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/worker/src/repo/repo-session-do.node.test.ts b/packages/worker/src/repo/repo-session-do.node.test.ts index 51a2fc850e..578d2be284 100644 --- a/packages/worker/src/repo/repo-session-do.node.test.ts +++ b/packages/worker/src/repo/repo-session-do.node.test.ts @@ -924,6 +924,46 @@ test('publishFromExternalRef rejects stale expected HEAD values', async () => { ) }) +test('publishFromExternalRef checks fast-forward ancestry through shell git adapter', async () => { + setCommonSessionFixtures() + mockModule.getEntitySourceById.mockResolvedValue({ + id: 'source-1', + user_id: 'user-1', + repo_id: 'source-repo', + published_commit: 'commit-old', + manifest_path: 'package.json', + source_root: '/', + entity_kind: 'package', + entity_id: 'package-1', + }) + mockModule.git.log.mockResolvedValueOnce([ + { oid: 'commit-new' }, + { oid: 'commit-old' }, + ]) + + const repoSession = new RepoSession(createDurableObjectState(), createEnv()) + + const result = await repoSession.publishFromExternalRef({ + sessionId: 'external-publish-source-1', + sourceId: 'source-1', + userId: 'user-1', + newCommit: 'commit-new', + }) + + expect(result.status).toBe('published') + expect(mockModule.git.log).toHaveBeenCalledWith({ + dir: '/session', + ref: 'commit-new', + depth: -1, + }) + expect(mockModule.updateEntitySource).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + publishedCommit: 'commit-new', + }), + ) +}) + test('getSessionState prefers fresh D1 reads over cached session and source rows', async () => { // Guards against a regression where the cache, populated by openSession, // would shadow fresh D1 reads and hide updates such as rebaseSession diff --git a/packages/worker/src/repo/repo-session-do.ts b/packages/worker/src/repo/repo-session-do.ts index 99cf98c7f5..db54506ba2 100644 --- a/packages/worker/src/repo/repo-session-do.ts +++ b/packages/worker/src/repo/repo-session-do.ts @@ -7,7 +7,6 @@ import { } from '@cloudflare/shell' import { applyPatch, formatPatch, parsePatch } from 'diff' import { createGit } from '@cloudflare/shell/git' -import * as git from 'isomorphic-git' import { deleteRepoSession, getRepoSessionById, @@ -457,15 +456,12 @@ class RepoSessionBase extends DurableObject { if (input.ancestor === input.descendant) { return true } - return git.isDescendent({ - fs: this.fileSystem as unknown as Parameters< - typeof git.isDescendent - >[0]['fs'], + const commits = await this.git.log({ dir: repoSessionWorkspacePrefix, - oid: input.descendant, - ancestor: input.ancestor, + ref: input.descendant, depth: -1, }) + return commits.some((commit) => commit.oid === input.ancestor) } private async writeCheckStatus(status: RepoSessionCheckStatus) { From 2f1da6cd32aafd98905b0458a285d26cdfbd74aa Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 5 May 2026 05:36:41 +0000 Subject: [PATCH 2/2] Use positive infinite git log depth Co-authored-by: Kent C. Dodds --- packages/worker/src/repo/repo-session-do.node.test.ts | 2 +- packages/worker/src/repo/repo-session-do.ts | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/worker/src/repo/repo-session-do.node.test.ts b/packages/worker/src/repo/repo-session-do.node.test.ts index 578d2be284..c41ccaa2be 100644 --- a/packages/worker/src/repo/repo-session-do.node.test.ts +++ b/packages/worker/src/repo/repo-session-do.node.test.ts @@ -954,7 +954,7 @@ test('publishFromExternalRef checks fast-forward ancestry through shell git adap expect(mockModule.git.log).toHaveBeenCalledWith({ dir: '/session', ref: 'commit-new', - depth: -1, + depth: Number.POSITIVE_INFINITY, }) expect(mockModule.updateEntitySource).toHaveBeenCalledWith( expect.anything(), diff --git a/packages/worker/src/repo/repo-session-do.ts b/packages/worker/src/repo/repo-session-do.ts index db54506ba2..6b65e784f6 100644 --- a/packages/worker/src/repo/repo-session-do.ts +++ b/packages/worker/src/repo/repo-session-do.ts @@ -456,10 +456,12 @@ class RepoSessionBase extends DurableObject { if (input.ancestor === input.descendant) { return true } + // Repo command parsing rejects negative depths; use a positive infinite + // depth here to request the complete ancestry chain from the git adapter. const commits = await this.git.log({ dir: repoSessionWorkspacePrefix, ref: input.descendant, - depth: -1, + depth: Number.POSITIVE_INFINITY, }) return commits.some((commit) => commit.oid === input.ancestor) }