Runs branch-store GC for a project, logging what it removed. The layout resolution is async; the GC sweep itself is blocking fs work, so it runs on the blocking pool to avoid stalling the reactor.
(root: &Path, opts: &TraceDecayOpenOptions, config: &SyncConfig)
| 725 | /// The layout resolution is async; the GC sweep itself is blocking fs work, so |
| 726 | /// it runs on the blocking pool to avoid stalling the reactor. |
| 727 | async fn run_gc(root: &Path, opts: &TraceDecayOpenOptions, config: &SyncConfig) { |
| 728 | let data_root = TraceDecay::initialized_store_layout_with_options(root, opts) |
| 729 | .await |
| 730 | .map(|layout| layout.data_root); |
| 731 | let Some(data_root) = data_root else { |
| 732 | return; |
| 733 | }; |
| 734 | let root_owned = root.to_path_buf(); |
| 735 | let branch_gc_days = config.branch_gc_days; |
| 736 | let orphan_db_gc_days = config.orphan_db_gc_days; |
| 737 | let Ok(report) = tokio::task::spawn_blocking(move || { |
| 738 | crate::branch::gc_dead_branch_stores( |
| 739 | &root_owned, |
| 740 | &data_root, |
| 741 | branch_gc_days, |
| 742 | orphan_db_gc_days, |
| 743 | ) |
| 744 | }) |
| 745 | .await |
| 746 | else { |
| 747 | return; |
| 748 | }; |
| 749 | if !report.removed_tracked.is_empty() || !report.removed_orphan_dbs.is_empty() { |
| 750 | log_daemon_event( |
| 751 | "git_watch_synced", |
| 752 | &[ |
| 753 | ("project", root.display().to_string()), |
| 754 | ("action", "gc".to_string()), |
| 755 | ("removed_tracked", report.removed_tracked.len().to_string()), |
| 756 | ( |
| 757 | "removed_orphans", |
| 758 | report.removed_orphan_dbs.len().to_string(), |
| 759 | ), |
| 760 | ], |
| 761 | ); |
| 762 | } |
| 763 | } |
| 764 | |
| 765 | /// The degraded fallback: mtime-poll HEAD + packed-refs every 5 minutes and |
| 766 | /// sync when they advance. Used when the inotify watcher cannot be built or |
no test coverage detected