Translates a raw notify event into dirty-set marks. Does NOT re-derive git state — it only records *what kind of path changed* so the debounce drain can resolve the actual git state once, after quiescence.
(state: &Arc<WatchState>, event: ¬ify::Event)
| 454 | /// state — it only records *what kind of path changed* so the debounce drain |
| 455 | /// can resolve the actual git state once, after quiescence. |
| 456 | fn classify_and_mark(state: &Arc<WatchState>, event: ¬ify::Event) { |
| 457 | let is_remove = matches!(event.kind, EventKind::Remove(_)); |
| 458 | let is_create = matches!(event.kind, EventKind::Create(_)); |
| 459 | |
| 460 | // Cheap synchronous classification into the dirty set. We use `try_lock` to |
| 461 | // stay non-blocking in the notify thread; on contention we still wake the |
| 462 | // loop, which rechecks git state anyway, so no event is lost. |
| 463 | if let Ok(mut dirty) = state.dirty.try_lock() { |
| 464 | let now = Instant::now(); |
| 465 | dirty.dirty = true; |
| 466 | if dirty.first_event.is_none() { |
| 467 | dirty.first_event = Some(now); |
| 468 | } |
| 469 | dirty.last_event = Some(now); |
| 470 | |
| 471 | for path in &event.paths { |
| 472 | let s = path.to_string_lossy(); |
| 473 | if let Some(idx) = s.find("/refs/heads/") { |
| 474 | let branch = &s[idx + "/refs/heads/".len()..]; |
| 475 | if !branch.is_empty() { |
| 476 | dirty.branches.insert(branch.to_string()); |
| 477 | } |
| 478 | if is_remove { |
| 479 | dirty.gc_eligible = true; |
| 480 | } |
| 481 | } else if let Some(idx) = s.find("/worktrees/") { |
| 482 | let rest = &s[idx + "/worktrees/".len()..]; |
| 483 | let name = rest.split('/').next().unwrap_or(""); |
| 484 | if !name.is_empty() { |
| 485 | if is_create { |
| 486 | dirty.new_worktrees.insert(name.to_string()); |
| 487 | } |
| 488 | if is_remove { |
| 489 | dirty.gc_eligible = true; |
| 490 | } |
| 491 | } |
| 492 | } |
| 493 | } |
| 494 | } |
| 495 | state.wake.notify_one(); |
| 496 | } |
| 497 | |
| 498 | /// The debounce state machine for a healthy watcher. Wakes on events, sleeps |
| 499 | /// until the quiet deadline or the hard cap (whichever comes first), then |