Skip to content

fix(worktree): fetch trunk before creating worktree to avoid stale base#2324

Merged
richardsolomou merged 3 commits into
mainfrom
posthog-code/fetch-trunk-before-worktree
May 25, 2026
Merged

fix(worktree): fetch trunk before creating worktree to avoid stale base#2324
richardsolomou merged 3 commits into
mainfrom
posthog-code/fetch-trunk-before-worktree

Conversation

@richardsolomou
Copy link
Copy Markdown
Member

@richardsolomou richardsolomou commented May 23, 2026

Problem

Local worktree tasks in the desktop app can start off a stale local trunk. When the user's local main hasn't been refreshed, WorktreeManager.createWorktree bases the new detached worktree on the local ref — so the agent begins iterating on code that's already behind origin/main, surfacing user-visible "worktree starts behind master" reports.

This only affects mode === "worktree" tasks. mode === "local" reuses the user's existing folder (no worktree), and mode === "cloud" returns from doCreateWorkspace before any worktree is created (the cloud runner provisions its workspace separately).

Changes

Add an opt-in fetchBeforeCreate option on the trunk path:

  • WorktreeManager.createWorktree({ fetchBeforeCreate: true }) calls a new resolveFreshBaseRef helper that does a best-effort git fetch origin <baseBranch> and bases the worktree on origin/<base> when reachable. Falls back to the local base ref if the fetch fails (offline, no origin, ref doesn't exist on the remote) so existing local-only setups still work.
  • CreateWorktreeSaga gets the same option for parity, using this.git directly inside the existing write lock (the fetch query helper would re-enter the lock and deadlock).
  • apps/code/src/main/services/workspace/service.ts passes fetchBeforeCreate: true on the trunk path only. The occupied-branch fallback (which bases off a user-local branch they may have committed to) is intentionally left as-is — fetching there would silently bypass their local commits.

We base off origin/<base> rather than fast-forwarding the local branch so the user's local checkout is never mutated; only the worktree picks up the remote tip.

Two small helpers (hasRef, fetchRef) added to packages/git/src/queries.ts to keep the saga and WorktreeManager symmetric.

How did you test this?

  • pnpm --filter @posthog/git test src/worktree.test.ts — 3 new tests pass:
    • Without fetchBeforeCreate, worktree is based on the stale local ref (baseline that proves the bug).
    • With fetchBeforeCreate, worktree starts at the remote tip and local main is not mutated.
    • With fetchBeforeCreate and an unreachable remote, falls back to the local base.
  • pnpm --filter @posthog/git typecheck, pnpm --filter code typecheck, pnpm lint — all clean.
  • The 2 pre-existing failures in the git test suite (forceRemove EACCES, detectDefaultBranch > prefers remote HEAD) reproduce on main and are unrelated.

Publish to changelog?

no

When the worktree base is created off the local trunk ref, a clone
whose local default branch hasn't been refreshed produces a worktree that
starts behind `origin/main`. The agent then iterates on stale code,
which is the root cause behind the user-reported pattern of worktrees
starting "behind master".

Add an opt-in `fetchBeforeCreate` flag on the trunk path that fetches
`origin/<base>` first and bases the worktree on the remote tip when
reachable. Falls back to the local base ref if the fetch fails so
offline / local-only setups still work and the user's local checkout
stays untouched (we base off `origin/<branch>`, not a fast-forward of
local `<branch>`).

Wired up at the workspace-service trunk path; the occupied-branch
fallback keeps local-base behavior so user-local commits aren't silently
bypassed.

Generated-By: PostHog Code
@richardsolomou richardsolomou requested a review from a team May 24, 2026 12:34
@richardsolomou richardsolomou marked this pull request as ready for review May 24, 2026 15:38
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 24, 2026

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
packages/git/src/worktree.test.ts:68-117
**Non-parameterized tests for fetch flag variants**

The first two tests share identical setup (clone a separate repo, push a new commit, verify the local is stale, instantiate `WorktreeManager`) and differ only in the `fetchBeforeCreate` flag and the expected HEAD SHA. Per the team's "prefer parameterised tests" convention, they should be collapsed into a single `it.each` entry rather than two copy-pasted bodies. The third test (unreachable remote) has a different setup so it reasonably stays separate.

Reviews (1): Last reviewed commit: "fix(worktree): fetch trunk before creati..." | Re-trigger Greptile

Comment thread packages/git/src/worktree.test.ts Outdated
Copy link
Copy Markdown
Contributor

@k11kirky k11kirky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry to be annoying - but the comments in here are really verbose, feels like AI dumping thoughts. Can we clean that up - otherwise its looks good to go

Generated-By: PostHog Code
Task-Id: 5fb5d72d-177e-4557-94f5-82145111de52
@richardsolomou richardsolomou enabled auto-merge (squash) May 25, 2026 11:47
@richardsolomou richardsolomou merged commit 2ecfcdb into main May 25, 2026
15 checks passed
@richardsolomou richardsolomou deleted the posthog-code/fetch-trunk-before-worktree branch May 25, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants