Skip to content

Commit cc40f55

Browse files
committed
refactor: saving time about repo's shared settings (#2108)
- Save repo's settings only when user changed it from `Repository Configuration` dialog and is closing this dialog - Never unload repo's settings (it is very small in memory)
1 parent ef17743 commit cc40f55

File tree

3 files changed

+36
-26
lines changed

3 files changed

+36
-26
lines changed

src/Models/RepositorySettings.cs

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,7 @@ public static RepositorySettings Get(string repo, string gitCommonDir)
7373
var fileInfo = new FileInfo(Path.Combine(gitCommonDir, "sourcegit.settings"));
7474
var fullpath = fileInfo.FullName;
7575
if (_cache.TryGetValue(fullpath, out var setting))
76-
{
77-
setting._usedBy.Add(repo);
7876
return setting;
79-
}
8077

8178
if (!File.Exists(fullpath))
8279
{
@@ -96,28 +93,20 @@ public static RepositorySettings Get(string repo, string gitCommonDir)
9693
}
9794

9895
setting._file = fullpath;
99-
setting._usedBy.Add(repo);
10096
_cache.Add(fullpath, setting);
10197
return setting;
10298
}
10399

104-
public void TryUnload(string repo)
100+
public void Save()
105101
{
106-
_usedBy.Remove(repo);
107-
108-
if (_usedBy.Count == 0)
102+
try
109103
{
110-
try
111-
{
112-
using var stream = File.Create(_file);
113-
JsonSerializer.Serialize(stream, this, JsonCodeGen.Default.RepositorySettings);
114-
}
115-
catch
116-
{
117-
// Ignore save errors
118-
}
119-
120-
_cache.Remove(_file);
104+
using var stream = File.Create(_file);
105+
JsonSerializer.Serialize(stream, this, JsonCodeGen.Default.RepositorySettings);
106+
}
107+
catch
108+
{
109+
// Ignore save errors
121110
}
122111
}
123112

@@ -169,6 +158,5 @@ public void MoveCustomActionDown(CustomAction act)
169158

170159
private static Dictionary<string, RepositorySettings> _cache = new();
171160
private string _file = string.Empty;
172-
private HashSet<string> _usedBy = new();
173161
}
174162
}

src/ViewModels/Repository.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,10 @@ public Repository(bool isBare, string path, string gitDir)
426426
GitDir = gitDir.Replace('\\', '/').TrimEnd('/');
427427

428428
var commonDirFile = Path.Combine(GitDir, "commondir");
429-
_isWorktree = GitDir.IndexOf("/worktrees/", StringComparison.Ordinal) > 0 &&
429+
var isWorktree = GitDir.IndexOf("/worktrees/", StringComparison.Ordinal) > 0 &&
430430
File.Exists(commonDirFile);
431431

432-
if (_isWorktree)
432+
if (isWorktree)
433433
{
434434
var commonDir = File.ReadAllText(commonDirFile).Trim();
435435
if (!Path.IsPathRooted(commonDir))
@@ -484,7 +484,6 @@ public void Close()
484484
SelectedView = null; // Do NOT modify. Used to remove exists widgets for GC.Collect
485485
Logs.Clear();
486486

487-
_settings.TryUnload(FullPath);
488487
_uiStates.Unload(_workingCopy.CommitMessage);
489488

490489
if (_cancellationRefreshBranches is { IsCancellationRequested: false })
@@ -1775,6 +1774,9 @@ private void AutoFetchByTimer(object sender)
17751774

17761775
private async Task AutoFetchOnUIThread()
17771776
{
1777+
if (_uiStates == null)
1778+
return;
1779+
17781780
CommandLog log = null;
17791781

17801782
try
@@ -1829,7 +1831,6 @@ private async Task AutoFetchOnUIThread()
18291831
log?.Complete();
18301832
}
18311833

1832-
private readonly bool _isWorktree = false;
18331834
private readonly string _gitCommonDir = null;
18341835
private Models.RepositorySettings _settings = null;
18351836
private Models.RepositoryUIStates _uiStates = null;

src/ViewModels/RepositoryConfigure.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Security.Cryptography;
4+
using System.Text;
5+
using System.Text.Json;
36
using System.Threading.Tasks;
47

58
using Avalonia.Collections;
@@ -170,6 +173,9 @@ public RepositoryConfigure(Repository repo)
170173
{
171174
_repo = repo;
172175

176+
var oldSettingsData = JsonSerializer.Serialize(_repo.Settings, JsonCodeGen.Default.RepositorySettings);
177+
_orgSettingsHash = HashString(oldSettingsData);
178+
173179
Remotes = new List<string>();
174180
foreach (var remote in _repo.Remotes)
175181
Remotes.Add(remote.Name);
@@ -295,6 +301,20 @@ public async Task SaveAsync()
295301
await SetIfChangedAsync("fetch.prune", EnablePruneOnFetch ? "true" : "false", "false");
296302

297303
await ApplyIssueTrackerChangesAsync();
304+
305+
var newSettingsData = JsonSerializer.Serialize(_repo.Settings, JsonCodeGen.Default.RepositorySettings);
306+
var newSettingsHash = HashString(newSettingsData);
307+
if (!_orgSettingsHash.Equals(newSettingsHash, StringComparison.Ordinal))
308+
_repo.Settings.Save();
309+
}
310+
311+
private string HashString(string source)
312+
{
313+
var hash = MD5.HashData(Encoding.Default.GetBytes(source));
314+
var builder = new StringBuilder(hash.Length * 2);
315+
foreach (var c in hash)
316+
builder.Append(c.ToString("x2"));
317+
return builder.ToString();
298318
}
299319

300320
private async Task SetIfChangedAsync(string key, string value, string defValue)
@@ -359,8 +379,9 @@ private async Task ApplyIssueTrackerChangesAsync()
359379
}
360380
}
361381

362-
private readonly Repository _repo = null;
363-
private readonly Dictionary<string, string> _cached = null;
382+
private readonly Repository _repo;
383+
private readonly string _orgSettingsHash;
384+
private readonly Dictionary<string, string> _cached;
364385
private string _httpProxy;
365386
private Models.CommitTemplate _selectedCommitTemplate = null;
366387
private Models.IssueTracker _selectedIssueTracker = null;

0 commit comments

Comments
 (0)