Fast-forward local branch refs at the end of each poll cycle
Build worktrees share the primary checkout's .git, so build tools can read refs/heads there. Since the rewrite never moved those refs, they stayed frozen at the last checkout: hs.hsadmin.ng's prQuickCheck compares master with origin/master and therefore failed every build once origin moved on. The sync runs after the enqueue decision on purpose — a local ref lagging behind origin is exactly how the watcher recognizes new commits, so keeping the refs in sync earlier (cron job, mirroring refspec, or this step moved up) would silence the branch instead of building it. Fast-forward only, as a compare-and-swap against the commit just read: diverged or ahead branches stay untouched, and the checked-out branch is advanced with merge --ff-only, which refuses to overwrite conflicting uncommitted changes. Switched off with watcher.fastForwardLocalRefs: false. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -62,7 +62,8 @@ The runtime is selected per branch behind the `BuildRunner` interface: `Dispatch
|
||||
|
||||
## Watcher
|
||||
|
||||
`Watcher` replaces the legacy blocking main loop with a non-blocking fixed-delay poll cycle: fetch origin, enqueue due branches (changed local, recent new origin, due auto-build slots) via `BuildExecutor`, then prune results, artifacts, and stale worktrees. Branches with `branches.<name>.requirePullRequest` are enqueued only while their head commit matches a pull-request head, detected without an API token by listing `refs/pull/*/head` via `git ls-remote` (lazily, at most once per poll cycle); manual `build` commands bypass this gate, and `watcher.pullRequestGate: false` disables it globally for plain-git origins without pull-request refs. Nothing is scheduled until `Watcher.start()` is called explicitly (server/watch mode) — CLI commands and tests never start the loop. "Already built" is tracked via the result repository, not by moving local branch refs. Auto-build slot state lives in `.git/gittally/auto-builds.json`; watcher health is exposed via `Watcher.state()`.
|
||||
`Watcher` replaces the legacy blocking main loop with a non-blocking fixed-delay poll cycle: fetch origin, enqueue due branches (changed local, recent new origin, due auto-build slots) via `BuildExecutor`, then prune results, artifacts, and stale worktrees. Branches with `branches.<name>.requirePullRequest` are enqueued only while their head commit matches a pull-request head, detected without an API token by listing `refs/pull/*/head` via `git ls-remote` (lazily, at most once per poll cycle); manual `build` commands bypass this gate, and `watcher.pullRequestGate: false` disables it globally for plain-git origins without pull-request refs. Nothing is scheduled until `Watcher.start()` is called explicitly (server/watch mode) — CLI commands and tests never start the loop. "Already built" is tracked via the result repository, not by moving local branch refs.
|
||||
After the enqueue decision — and only after it, because a local ref lagging behind origin *is* the change signal — the cycle fast-forwards the primary checkout's local branch refs to their origin counterparts (`watcher.fastForwardLocalRefs`, `GitService.fastForwardLocalBranches`), so build tools reading the shared `.git` from a worktree see the refs they expect; diverged or ahead branches are never touched. Auto-build slot state lives in `.git/gittally/auto-builds.json`; watcher health is exposed via `Watcher.state()`.
|
||||
|
||||
## System Metrics
|
||||
|
||||
|
||||
Reference in New Issue
Block a user