Skip to content

Wait for the watch set in git engine tests instead of reading it once - #113

Open
mgasner wants to merge 1 commit into
yas-run:mainfrom
indent-com:fix/git-watch-test-race
Open

mgasner wants to merge 1 commit into
yas-run:mainfrom
indent-com:fix/git-watch-test-race

Conversation

@mgasner

@mgasner mgasner commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

index_changes_reconcile_tracked_exceptions_to_ignore_pruning fails intermittently on Windows CI, at assert!(watches().contains(.../generated/nested)).

The engine reconciles its worktree watches before it cuts a snapshot. If git add -f finishes writing the index between those two steps, the snapshot already shows the file as added while the watch set still predates it, and the next pass arms the directory. The test read the debug watch set once, right after that snapshot.

A new Repository::wait_for_watch helper polls the watch set for up to 5 s. This test now waits for the watch to be armed before writing into generated/nested, and for it to be disarmed after git rm --cached. reattached_status_selection_observes_changes_made_while_pruned already did the same wait inline, so it now uses the helper too. Test-only change.

View in Indent
Tag @indent to continue the conversation here.

@indent
indent Bot force-pushed the fix/git-watch-test-race branch from 649e9b7 to ffe1bd4 Compare October 14, 2026 23:45
@indent
indent Bot deleted the fix/git-watch-test-race branch October 15, 2026 13:07
@indent
indent Bot force-pushed the fix/git-watch-test-race branch 2 times, most recently from ffe1bd4 to 422e8df Compare October 15, 2026 13:10

@ultimator-ai ultimator-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ultimator's review of 422e8df

Replaces one-shot reads of the debug watch set with a Condvar-backed debug_wait_worktree_watches that the engine notifies on every publish, and uses it in the two git engine tests that raced the follow-up reconcile pass. The wait checks its predicate before blocking and under the same mutex the engine writes through, so no notification is lost, and the test helper compares canonical paths the same way worktree_watches does. I found no defects. I couldn't read the CI results for 422e8df from here, so they are unverified.

No issues found.

Reviewed in 1m 9s · Session · @ultimator-ai review reviews again · @ultimator-ai fix fixes the open issues

A status snapshot can reflect an index written after its pass reconciled
the watch set; the set catches up on the pass that index event triggers.
Tests that asserted the set right after the snapshot raced that pass. The
debug hook now signals each published set, and the tests wait on it.
@indent
indent Bot force-pushed the fix/git-watch-test-race branch from 422e8df to 4ca6369 Compare October 15, 2026 13:11

@ultimator-ai ultimator-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ultimator's review of 4ca6369

Round 2 (4ca6369, force-pushed): same change as 422e8df, except debug_wait_worktree_watches now blocks with wait_while and no timeout. The lost-wakeup reasoning still holds. But a watch that is never armed or disarmed now hangs the test until the CI job's own timeout, instead of failing within 5 s as the old inline loop and 422e8df did. The description still says the helper waits "for up to 5 s". CI for 4ca6369 has just restarted and has no results yet.

1 issue: 1 nit

Open issues: check the ones to fix, then Fix.

  • ⚪ #1 Watch wait lost its timeout: a regression hangs CI · crates/git/src/state.rs:232-236
  • 🔧 Fix the checked issues (all of them if none is checked)

Reviewed in 18s · Session · @ultimator-ai review reviews again · @ultimator-ai fix fixes the open issues

Comment thread crates/git/src/state.rs
Comment on lines +232 to +236
pub fn debug_wait_worktree_watches(gitdir: &Path, mut done: impl FnMut(&[PathBuf]) -> bool) {
let (sets, published) = worktree_watch_sets();
drop(
published
.wait_while(sets.lock().unwrap(), |sets| {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚪ Nit · Watch wait lost its timeout: a regression hangs CI

422e8df used wait_timeout_while with the caller's 5 s, and the polling loop this replaces in reattached_status_selection_observes_changes_made_while_pruned asserted after 5 s. wait_while has no deadline. If the engine never publishes a matching set (the regression these tests exist to catch), wait_for_watch blocks forever. The test binary then sits until the CI job is killed, with no failing assertion or test name, and the Windows job is the one that flakes. The PR description still says it waits "for up to 5 s".

Ultimator · issue #1 · reply @ultimator-ai fix 1 to have it fixed

This branch has not been deployed

No deployments
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