Skip to content

fix(update): sync default branch from the configured upstream on both paths - #30

Merged
epodivilov merged 1 commit into
mainfrom
fix/unify-remote-resolution
Jul 22, 2026
Merged

fix(update): sync default branch from the configured upstream on both paths#30
epodivilov merged 1 commit into
mainfrom
fix/unify-remote-resolution

Conversation

@epodivilov

Copy link
Copy Markdown
Owner

What

wt update decides how to advance the default branch based on whether it has a worktree: fast-forward when it does, ref update when it doesn't. Those two paths disagreed on everything else.

  • Remote. The fast-forward path honored the configured upstream; the ref-update path always used the primary remote and ignored upstream. In a fork workflow that silently changed the base of every subsequent rebase depending on whether the default branch happened to be checked out. updateBranchRef now takes an optional remote, mirroring mergeFFOnly, and the use case passes the configured upstream on both paths.
  • Hooks. post-update hooks ran for the default branch only on the fast-forward path. They now run on both after a successful upstream sync; with no worktree for the default branch they run in the repository root, and their results are reported the same way.

Why the adapter refactor is here

Primary-remote resolution used to be memoized in a closure inside the git adapter that never invalidated, so tests had to build a fresh adapter per case to avoid a stale value. It is now resolvePrimaryRemote, resolved once in the container and injected into the adapter. That removes the mutable state, makes the remote a composition-time decision, and is what makes the behavior above testable without the fresh-adapter workaround.

What a user notices

With upstream configured and no worktree for the default branch:

  • the branch advances from <upstream>/<default> instead of origin/<default>
  • post-update hooks run for it (for example, pushing the synced default branch back to the fork)
  • the summary line reads <default> synced from <upstream>/<default> instead of <default> ref updated

Without upstream configured, behavior is unchanged.

Checks

pnpm typecheck, pnpm lint, pnpm test — 523 tests pass. New coverage for the no-worktree path with an explicit upstream (remote choice, hooks, dry run) and for resolvePrimaryRemote (default-branch tracking remote, current-branch fallback, sole remote, . sentinel, no-remote fallback to origin). Both fixes were mutation-checked: reverting either one fails the new tests.

@epodivilov
epodivilov marked this pull request as ready for review July 21, 2026 22:04
… paths

When the default branch had no worktree, `wt update` updated its ref from the
primary remote and skipped post-update hooks, while the worktree path
fast-forwarded from the configured upstream and ran them. In a fork workflow
the base of every subsequent rebase therefore depended on whether the default
branch happened to be checked out.

- updateBranchRef takes an optional remote, mirroring mergeFFOnly, and the use
  case passes the configured upstream on both paths
- post-update hooks for the default branch run on both paths; with no worktree
  for it they run in the repository root
- primary-remote resolution leaves the adapter's per-instance cache: it is
  exposed as resolvePrimaryRemote, resolved once in the container, and injected
@epodivilov
epodivilov force-pushed the fix/unify-remote-resolution branch from 29725ff to 35261a8 Compare July 21, 2026 22:08
@epodivilov
epodivilov merged commit bb126fe into main Jul 22, 2026
1 check passed
@epodivilov
epodivilov deleted the fix/unify-remote-resolution branch July 22, 2026 07:18
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.

1 participant