Skip to content

First sync exhausts retries when active watcher is running #7

Description

@rupertsworld

Bug

On first sync of a large repo with an active stash watch on another machine, sync fails with "Remote main moved during push" and exhausts all 5 retries.

Cause

First sync has no local snapshot, so fetch() downloads all blob metadata and file content via GraphQL + raw API calls. This makes the window between fetch() and push() very wide. An active watcher consistently lands a commit during this window. Each retry repeats the full expensive fetch, so the window stays wide across all attempts.

Subsequent syncs are unaffected — they diff against the local snapshot and only fetch the delta, keeping the window small. If a normal sync does hit this, the next attempt self-heals.

Proposed fix

Split first sync (empty local snapshot) into two passes:

Pass 1 — pull only:

  1. fetch() — download remote state (expensive, but no push follows)
  2. reconcile() — compute mutations
  3. Skip push — don't push snapshot.json yet
  4. apply() — write remote files to local disk
  5. saveSnapshot() — write local snapshot only

Pass 2 — push snapshot (immediate, automatic):

  1. fetch() — fast, local snapshot now matches remote, most files skip
  2. reconcile() — only snapshot.json needs pushing
  3. push() — tiny payload, tiny contention window
  4. saveSnapshot() — update local snapshot

Only triggers when local snapshot is empty at sync start. All other syncs unchanged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions