Skip to content

Commit c67e8e3

Browse files
committed
enhance: create only one filesystem watcher when repo's $GIT_DIR is the same as $REPO_ROOT/.git
Signed-off-by: leo <[email protected]>
1 parent 5ec8ae1 commit c67e8e3

File tree

1 file changed

+86
-48
lines changed

1 file changed

+86
-48
lines changed

src/Models/Watcher.cs

Lines changed: 86 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,50 @@ public Watcher(IRepository repo, string fullpath, string gitDir)
1212
{
1313
_repo = repo;
1414

15-
_wcWatcher = new FileSystemWatcher();
16-
_wcWatcher.Path = fullpath;
17-
_wcWatcher.Filter = "*";
18-
_wcWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime;
19-
_wcWatcher.IncludeSubdirectories = true;
20-
_wcWatcher.Created += OnWorkingCopyChanged;
21-
_wcWatcher.Renamed += OnWorkingCopyChanged;
22-
_wcWatcher.Changed += OnWorkingCopyChanged;
23-
_wcWatcher.Deleted += OnWorkingCopyChanged;
24-
_wcWatcher.EnableRaisingEvents = true;
25-
26-
_repoWatcher = new FileSystemWatcher();
27-
_repoWatcher.Path = gitDir;
28-
_repoWatcher.Filter = "*";
29-
_repoWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName;
30-
_repoWatcher.IncludeSubdirectories = true;
31-
_repoWatcher.Created += OnRepositoryChanged;
32-
_repoWatcher.Renamed += OnRepositoryChanged;
33-
_repoWatcher.Changed += OnRepositoryChanged;
34-
_repoWatcher.Deleted += OnRepositoryChanged;
35-
_repoWatcher.EnableRaisingEvents = true;
15+
var testGitDir = new DirectoryInfo(Path.Combine(fullpath, ".git")).FullName;
16+
var desiredDir = new DirectoryInfo(gitDir).FullName;
17+
if (testGitDir.Equals(desiredDir, StringComparison.Ordinal))
18+
{
19+
var combined = new FileSystemWatcher();
20+
combined.Path = fullpath;
21+
combined.Filter = "*";
22+
combined.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime;
23+
combined.IncludeSubdirectories = true;
24+
combined.Created += OnRepositoryChanged;
25+
combined.Renamed += OnRepositoryChanged;
26+
combined.Changed += OnRepositoryChanged;
27+
combined.Deleted += OnRepositoryChanged;
28+
combined.EnableRaisingEvents = true;
29+
30+
_watchers.Add(combined);
31+
}
32+
else
33+
{
34+
var wc = new FileSystemWatcher();
35+
wc.Path = fullpath;
36+
wc.Filter = "*";
37+
wc.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.CreationTime;
38+
wc.IncludeSubdirectories = true;
39+
wc.Created += OnWorkingCopyChanged;
40+
wc.Renamed += OnWorkingCopyChanged;
41+
wc.Changed += OnWorkingCopyChanged;
42+
wc.Deleted += OnWorkingCopyChanged;
43+
wc.EnableRaisingEvents = true;
44+
45+
var git = new FileSystemWatcher();
46+
git.Path = gitDir;
47+
git.Filter = "*";
48+
git.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.DirectoryName | NotifyFilters.FileName;
49+
git.IncludeSubdirectories = true;
50+
git.Created += OnGitDirChanged;
51+
git.Renamed += OnGitDirChanged;
52+
git.Changed += OnGitDirChanged;
53+
git.Deleted += OnGitDirChanged;
54+
git.EnableRaisingEvents = true;
55+
56+
_watchers.Add(wc);
57+
_watchers.Add(git);
58+
}
3659

3760
_timer = new Timer(Tick, null, 100, 100);
3861
}
@@ -77,22 +100,13 @@ public void MarkWorkingCopyDirtyManually()
77100

78101
public void Dispose()
79102
{
80-
_repoWatcher.EnableRaisingEvents = false;
81-
_repoWatcher.Created -= OnRepositoryChanged;
82-
_repoWatcher.Renamed -= OnRepositoryChanged;
83-
_repoWatcher.Changed -= OnRepositoryChanged;
84-
_repoWatcher.Deleted -= OnRepositoryChanged;
85-
_repoWatcher.Dispose();
86-
_repoWatcher = null;
87-
88-
_wcWatcher.EnableRaisingEvents = false;
89-
_wcWatcher.Created -= OnWorkingCopyChanged;
90-
_wcWatcher.Renamed -= OnWorkingCopyChanged;
91-
_wcWatcher.Changed -= OnWorkingCopyChanged;
92-
_wcWatcher.Deleted -= OnWorkingCopyChanged;
93-
_wcWatcher.Dispose();
94-
_wcWatcher = null;
103+
foreach (var watcher in _watchers)
104+
{
105+
watcher.EnableRaisingEvents = false;
106+
watcher.Dispose();
107+
}
95108

109+
_watchers.Clear();
96110
_timer.Dispose();
97111
_timer = null;
98112
}
@@ -153,11 +167,45 @@ private void Tick(object sender)
153167
}
154168

155169
private void OnRepositoryChanged(object o, FileSystemEventArgs e)
170+
{
171+
if (string.IsNullOrEmpty(e.Name) || e.Name.Equals(".git", StringComparison.Ordinal))
172+
return;
173+
174+
var name = e.Name.Replace('\\', '/').TrimEnd('/');
175+
if (name.EndsWith("/.git", StringComparison.Ordinal))
176+
return;
177+
178+
if (name.StartsWith(".git/", StringComparison.Ordinal))
179+
HandleGitDirFileChanged(name.Substring(5));
180+
else
181+
HandleWorkingCopyFileChanged(name);
182+
}
183+
184+
private void OnGitDirChanged(object o, FileSystemEventArgs e)
156185
{
157186
if (string.IsNullOrEmpty(e.Name))
158187
return;
159188

160189
var name = e.Name.Replace('\\', '/').TrimEnd('/');
190+
HandleGitDirFileChanged(name);
191+
}
192+
193+
private void OnWorkingCopyChanged(object o, FileSystemEventArgs e)
194+
{
195+
if (string.IsNullOrEmpty(e.Name))
196+
return;
197+
198+
var name = e.Name.Replace('\\', '/').TrimEnd('/');
199+
if (name.Equals(".git", StringComparison.Ordinal) ||
200+
name.StartsWith(".git/", StringComparison.Ordinal) ||
201+
name.EndsWith("/.git", StringComparison.Ordinal))
202+
return;
203+
204+
HandleWorkingCopyFileChanged(name);
205+
}
206+
207+
private void HandleGitDirFileChanged(string name)
208+
{
161209
if (name.Contains("fsmonitor--daemon/", StringComparison.Ordinal) ||
162210
name.EndsWith(".lock", StringComparison.Ordinal) ||
163211
name.StartsWith("lfs/", StringComparison.Ordinal))
@@ -200,17 +248,8 @@ private void OnRepositoryChanged(object o, FileSystemEventArgs e)
200248
}
201249
}
202250

203-
private void OnWorkingCopyChanged(object o, FileSystemEventArgs e)
251+
private void HandleWorkingCopyFileChanged(string name)
204252
{
205-
if (string.IsNullOrEmpty(e.Name))
206-
return;
207-
208-
var name = e.Name.Replace('\\', '/').TrimEnd('/');
209-
if (name.Equals(".git", StringComparison.Ordinal) ||
210-
name.StartsWith(".git/", StringComparison.Ordinal) ||
211-
name.EndsWith("/.git", StringComparison.Ordinal))
212-
return;
213-
214253
if (name.StartsWith(".vs/", StringComparison.Ordinal))
215254
return;
216255

@@ -236,8 +275,7 @@ private void OnWorkingCopyChanged(object o, FileSystemEventArgs e)
236275
}
237276

238277
private readonly IRepository _repo = null;
239-
private FileSystemWatcher _repoWatcher = null;
240-
private FileSystemWatcher _wcWatcher = null;
278+
private List<FileSystemWatcher> _watchers = [];
241279
private Timer _timer = null;
242280
private int _lockCount = 0;
243281
private long _updateWC = 0;

0 commit comments

Comments
 (0)