fix(multi): Suppress VGitSync during staging; 95%+ performance improvement #425
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Builds on top of #422 and #423.
Description
Fixes performance degradation during staging operations by suppressing redundant VGitSync events. Achieves 99.6% reduction in buffer refresh calls (1,380 -> 6 LiveGutter:fetch calls) and 95% reduction in total git operations (10,421 -> 564 calls across 41 staging operations).
When staging hunks in the diff view, DiffScreen already manually fetches and renders the current buffer, making VGitSync's refresh of all tracked buffers unnecessary and wasteful. Every staging operation (
s,S,u,U,r,Rkeys in diff view) triggered a cascade: git index changes -> filesystem watcher detects change -> VGitSync event fires ->git_buffer_store.for_each()iterates all tracked buffers -> each buffer runsLiveGutter:fetch()->GitBuffer:diff()-> 3-4 git commands per buffer. With 15 tracked buffers, this meant 15x unnecessary buffer refreshes per stage operation, resulting in thousands of redundant git command calls.This adds
suppress_sync_for(ms)API togit_buffer_storethat temporarily disables VGitSync events. Applied this 200ms suppression window to all DiffScreen staging methods (stage_hunk, unstage_hunk, reset_hunk, stage, unstage, reset), preventing the cascade while DiffScreen handles its own refresh. Also includeswith_selective_staging()API for future use cases where only specific buffers should refresh.Tested with 15 tracked buffers over 41 staging operations. No functional regressions observed - all git operations complete successfully, gutter signs update correctly, and UI remains responsive.
Performance Summary
Improvement:
Profiling Details
Environment: 15 tracked buffers, ~40 stage operations (DiffScreen:stage_hunk)
Before:
After: