diff --git a/src/Models/Watcher.cs b/src/Models/Watcher.cs index b881807b0c..66e246bc07 100644 --- a/src/Models/Watcher.cs +++ b/src/Models/Watcher.cs @@ -43,6 +43,7 @@ public Watcher(IRepository repo, string fullpath, string gitDir) combined.Renamed += OnRepositoryChanged; combined.Changed += OnRepositoryChanged; combined.Deleted += OnRepositoryChanged; + combined.Error += OnWatcherError; combined.EnableRaisingEvents = false; _watchers.Add(combined); @@ -58,6 +59,7 @@ public Watcher(IRepository repo, string fullpath, string gitDir) wc.Renamed += OnWorkingCopyChanged; wc.Changed += OnWorkingCopyChanged; wc.Deleted += OnWorkingCopyChanged; + wc.Error += OnWatcherError; wc.EnableRaisingEvents = false; var git = new FileSystemWatcher(); @@ -69,6 +71,7 @@ public Watcher(IRepository repo, string fullpath, string gitDir) git.Renamed += OnGitDirChanged; git.Changed += OnGitDirChanged; git.Deleted += OnGitDirChanged; + git.Error += OnWatcherError; git.EnableRaisingEvents = false; _watchers.Add(wc); @@ -240,6 +243,21 @@ private void OnRepositoryChanged(object o, FileSystemEventArgs e) HandleWorkingCopyFileChanged(name, e.FullPath); } + /// + /// The internal buffer overflowed (a large fetch or checkout writes thousands of files), so + /// some events were dropped and we cannot know which. Reload everything once things settle. + /// + private void OnWatcherError(object o, ErrorEventArgs e) + { + var desired = DateTime.Now.AddSeconds(1).ToFileTime(); + Interlocked.Exchange(ref _updateBranch, desired); + Interlocked.Exchange(ref _updateTags, desired); + Interlocked.Exchange(ref _updateStashes, desired); + Interlocked.Exchange(ref _updateWC, desired); + if (_repo.MayHaveSubmodules()) + Interlocked.Exchange(ref _updateSubmodules, desired); + } + private void OnGitDirChanged(object o, FileSystemEventArgs e) { if (string.IsNullOrEmpty(e.Name)) @@ -302,6 +320,12 @@ private void HandleGitDirFileChanged(string name) { Interlocked.Exchange(ref _updateBranch, DateTime.Now.AddSeconds(.5).ToFileTime()); } + else if (name.Equals("packed-refs", StringComparison.Ordinal)) + { + var desired = DateTime.Now.AddSeconds(.5).ToFileTime(); + Interlocked.Exchange(ref _updateBranch, desired); + Interlocked.Exchange(ref _updateTags, desired); + } else if (name.StartsWith("reftable/", StringComparison.Ordinal)) { var desired = DateTime.Now.AddSeconds(.5).ToFileTime(); diff --git a/src/ViewModels/Fetch.cs b/src/ViewModels/Fetch.cs index 330dd5d763..e2c609023c 100644 --- a/src/ViewModels/Fetch.cs +++ b/src/ViewModels/Fetch.cs @@ -105,6 +105,10 @@ public override async Task Sure() log.Complete(); + _repo.MarkBranchesDirtyManually(); + if (!notags) + _repo.MarkTagsDirtyManually(); + if (navigateToUpstreamHEAD && !token.IsCancellationRequested) { var upstream = _repo.CurrentBranch?.Upstream; diff --git a/src/ViewModels/FetchInto.cs b/src/ViewModels/FetchInto.cs index 816687ec7a..f99facadcb 100644 --- a/src/ViewModels/FetchInto.cs +++ b/src/ViewModels/FetchInto.cs @@ -43,6 +43,7 @@ public override async Task Sure() .ExecAsync(); log.Complete(); + _repo.MarkBranchesDirtyManually(); if (_repo.SelectedViewIndex == 0 && !token.IsCancellationRequested) { diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index aa58226d97..4c288dc178 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -1929,6 +1929,8 @@ private async Task AutoFetchOnUIThread() await new Commands.Fetch(FullPath, remote).Use(log).ExecAsync(); _lastFetchTime = DateTime.Now; + MarkBranchesDirtyManually(); + MarkTagsDirtyManually(); } catch {