enhance: create only one filesystem watcher when repo's $GIT_DIR is the same as $REPO_ROOT/.git

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-06-18 17:12:50 +08:00
parent 5ec8ae1296
commit c67e8e3c64
No known key found for this signature in database

View file

@ -12,27 +12,50 @@ namespace SourceGit.Models
{ {
_repo = repo; _repo = repo;
_wcWatcher = new FileSystemWatcher(); var testGitDir = new DirectoryInfo(Path.Combine(fullpath, ".git")).FullName;
_wcWatcher.Path = fullpath; var desiredDir = new DirectoryInfo(gitDir).FullName;
_wcWatcher.Filter = "*"; if (testGitDir.Equals(desiredDir, StringComparison.Ordinal))
_wcWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime; {
_wcWatcher.IncludeSubdirectories = true; var combined = new FileSystemWatcher();
_wcWatcher.Created += OnWorkingCopyChanged; combined.Path = fullpath;
_wcWatcher.Renamed += OnWorkingCopyChanged; combined.Filter = "*";
_wcWatcher.Changed += OnWorkingCopyChanged; combined.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime;
_wcWatcher.Deleted += OnWorkingCopyChanged; combined.IncludeSubdirectories = true;
_wcWatcher.EnableRaisingEvents = true; combined.Created += OnRepositoryChanged;
combined.Renamed += OnRepositoryChanged;
combined.Changed += OnRepositoryChanged;
combined.Deleted += OnRepositoryChanged;
combined.EnableRaisingEvents = true;
_repoWatcher = new FileSystemWatcher(); _watchers.Add(combined);
_repoWatcher.Path = gitDir; }
_repoWatcher.Filter = "*"; else
_repoWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName; {
_repoWatcher.IncludeSubdirectories = true; var wc = new FileSystemWatcher();
_repoWatcher.Created += OnRepositoryChanged; wc.Path = fullpath;
_repoWatcher.Renamed += OnRepositoryChanged; wc.Filter = "*";
_repoWatcher.Changed += OnRepositoryChanged; wc.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime;
_repoWatcher.Deleted += OnRepositoryChanged; wc.IncludeSubdirectories = true;
_repoWatcher.EnableRaisingEvents = true; wc.Created += OnWorkingCopyChanged;
wc.Renamed += OnWorkingCopyChanged;
wc.Changed += OnWorkingCopyChanged;
wc.Deleted += OnWorkingCopyChanged;
wc.EnableRaisingEvents = true;
var git = new FileSystemWatcher();
git.Path = gitDir;
git.Filter = "*";
git.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName;
git.IncludeSubdirectories = true;
git.Created += OnGitDirChanged;
git.Renamed += OnGitDirChanged;
git.Changed += OnGitDirChanged;
git.Deleted += OnGitDirChanged;
git.EnableRaisingEvents = true;
_watchers.Add(wc);
_watchers.Add(git);
}
_timer = new Timer(Tick, null, 100, 100); _timer = new Timer(Tick, null, 100, 100);
} }
@ -77,22 +100,13 @@ namespace SourceGit.Models
public void Dispose() public void Dispose()
{ {
_repoWatcher.EnableRaisingEvents = false; foreach (var watcher in _watchers)
_repoWatcher.Created -= OnRepositoryChanged; {
_repoWatcher.Renamed -= OnRepositoryChanged; watcher.EnableRaisingEvents = false;
_repoWatcher.Changed -= OnRepositoryChanged; watcher.Dispose();
_repoWatcher.Deleted -= OnRepositoryChanged; }
_repoWatcher.Dispose();
_repoWatcher = null;
_wcWatcher.EnableRaisingEvents = false;
_wcWatcher.Created -= OnWorkingCopyChanged;
_wcWatcher.Renamed -= OnWorkingCopyChanged;
_wcWatcher.Changed -= OnWorkingCopyChanged;
_wcWatcher.Deleted -= OnWorkingCopyChanged;
_wcWatcher.Dispose();
_wcWatcher = null;
_watchers.Clear();
_timer.Dispose(); _timer.Dispose();
_timer = null; _timer = null;
} }
@ -153,11 +167,45 @@ namespace SourceGit.Models
} }
private void OnRepositoryChanged(object o, FileSystemEventArgs e) private void OnRepositoryChanged(object o, FileSystemEventArgs e)
{
if (string.IsNullOrEmpty(e.Name) || e.Name.Equals(".git", StringComparison.Ordinal))
return;
var name = e.Name.Replace('\\', '/').TrimEnd('/');
if (name.EndsWith("/.git", StringComparison.Ordinal))
return;
if (name.StartsWith(".git/", StringComparison.Ordinal))
HandleGitDirFileChanged(name.Substring(5));
else
HandleWorkingCopyFileChanged(name);
}
private void OnGitDirChanged(object o, FileSystemEventArgs e)
{ {
if (string.IsNullOrEmpty(e.Name)) if (string.IsNullOrEmpty(e.Name))
return; return;
var name = e.Name.Replace('\\', '/').TrimEnd('/'); var name = e.Name.Replace('\\', '/').TrimEnd('/');
HandleGitDirFileChanged(name);
}
private void OnWorkingCopyChanged(object o, FileSystemEventArgs e)
{
if (string.IsNullOrEmpty(e.Name))
return;
var name = e.Name.Replace('\\', '/').TrimEnd('/');
if (name.Equals(".git", StringComparison.Ordinal) ||
name.StartsWith(".git/", StringComparison.Ordinal) ||
name.EndsWith("/.git", StringComparison.Ordinal))
return;
HandleWorkingCopyFileChanged(name);
}
private void HandleGitDirFileChanged(string name)
{
if (name.Contains("fsmonitor--daemon/", StringComparison.Ordinal) || if (name.Contains("fsmonitor--daemon/", StringComparison.Ordinal) ||
name.EndsWith(".lock", StringComparison.Ordinal) || name.EndsWith(".lock", StringComparison.Ordinal) ||
name.StartsWith("lfs/", StringComparison.Ordinal)) name.StartsWith("lfs/", StringComparison.Ordinal))
@ -200,17 +248,8 @@ namespace SourceGit.Models
} }
} }
private void OnWorkingCopyChanged(object o, FileSystemEventArgs e) private void HandleWorkingCopyFileChanged(string name)
{ {
if (string.IsNullOrEmpty(e.Name))
return;
var name = e.Name.Replace('\\', '/').TrimEnd('/');
if (name.Equals(".git", StringComparison.Ordinal) ||
name.StartsWith(".git/", StringComparison.Ordinal) ||
name.EndsWith("/.git", StringComparison.Ordinal))
return;
if (name.StartsWith(".vs/", StringComparison.Ordinal)) if (name.StartsWith(".vs/", StringComparison.Ordinal))
return; return;
@ -236,8 +275,7 @@ namespace SourceGit.Models
} }
private readonly IRepository _repo = null; private readonly IRepository _repo = null;
private FileSystemWatcher _repoWatcher = null; private List<FileSystemWatcher> _watchers = [];
private FileSystemWatcher _wcWatcher = null;
private Timer _timer = null; private Timer _timer = null;
private int _lockCount = 0; private int _lockCount = 0;
private long _updateWC = 0; private long _updateWC = 0;