Automatic Git status refreshing for file tree indicators and status bar branch display.
Ferrite automatically refreshes Git status information to keep the UI in sync with the actual repository state. This ensures that file tree status badges and the branch indicator remain accurate without requiring manual refresh.
When a file is saved (Ctrl+S or File > Save), git status is refreshed to update indicators for the saved file and any dependent status (e.g., staging area changes).
When the Ferrite window regains focus (e.g., after switching back from another application), git status is refreshed. This catches changes made by external tools like git add, git commit, or other editors.
While a workspace is open with a git repository, status is refreshed every 10 seconds. This catches external changes from:
- Other applications modifying files
- Background processes (build tools, formatters)
- Other git operations
When the file watcher detects file tree changes (create, delete, rename), a git refresh is also triggered to update status badges.
To prevent excessive git2 calls that could impact performance, refresh requests are debounced with a 500ms delay. Multiple rapid triggers (e.g., saving multiple files quickly) are batched into a single refresh operation.
Request 1 →
[500ms wait] → Single refresh
Request 2 →
| File | Component | Purpose |
|---|---|---|
src/vcs/git.rs |
GitAutoRefresh |
Manages refresh timing, debouncing, focus tracking |
src/vcs/git.rs |
GitService::refresh_status() |
Performs actual git2 status query |
src/app.rs |
handle_git_auto_refresh() |
Called each frame in update loop |
src/app.rs |
request_git_refresh() |
Triggers debounced refresh |
pub struct GitAutoRefresh {
last_refresh: Option<Instant>, // For periodic timer
last_request: Option<Instant>, // For debounce calculation
pending_refresh: bool, // Whether refresh is queued
was_focused: bool, // Previous focus state
}| Constant | Value | Purpose |
|---|---|---|
GIT_REFRESH_INTERVAL |
10 seconds | Periodic refresh timer |
GIT_DEBOUNCE_DURATION |
500ms | Minimum time between refreshes |
- Target: Less than 5% CPU impact during refresh cycles
- Git status queries are lightweight for typical repository sizes
- Debouncing prevents refresh storms
- Status cache is stored in
GitService::file_statusesHashMap - Cache is invalidated on each refresh (full refresh, not incremental)
- Only non-clean files are stored (clean files = no entry)
For very large repositories (10,000+ files), the 10-second periodic refresh may cause brief UI pauses.
Potential optimizations (deferred unless needed):
- Make
GIT_REFRESH_INTERVALconfigurable via settings - Implement incremental status updates (track changed files, partial cache invalidation)
- Use file watcher events to target specific paths instead of full refresh
These are noted in CHANGELOG.md under "Deferred" for v0.2.5.
Located in src/vcs/git.rs:
#[test] fn test_git_auto_refresh_new()
#[test] fn test_git_auto_refresh_focus_gained()
#[test] fn test_git_auto_refresh_periodic_refresh_never_refreshed()
#[test] fn test_git_auto_refresh_periodic_refresh_recent()
#[test] fn test_git_auto_refresh_mark_refreshed()
#[test] fn test_git_auto_refresh_tick_no_workspace()
#[test] fn test_git_auto_refresh_tick_with_workspace_first_time()
#[test] fn test_git_auto_refresh_debounce_not_ready()
#[test] fn test_git_auto_refresh_debounce_no_pending()| Test | Steps | Expected |
|---|---|---|
| Auto-refresh | 1. Open workspace with git repo 2. Modify a file externally 3. Wait up to 10 seconds |
File tree badge updates |
| Save trigger | 1. Modify and save a file | Status badge updates immediately |
| Focus trigger | 1. Switch to terminal, run git add .2. Switch back to Ferrite |
Badges update on focus |
| Debounce | 1. Save files rapidly | Only one refresh executes |
- Git Integration - Overall git integration architecture
- Workspace Folder Support - File tree and workspace features