mirror of
https://fastgit.cc/github.com/sourcegit-scm/sourcegit
synced 2026-04-21 13:20:30 +08:00
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)
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia.Collections;
|
||||
|
||||
@@ -68,15 +72,12 @@ namespace SourceGit.Models
|
||||
set;
|
||||
} = [];
|
||||
|
||||
public static RepositorySettings Get(string repo, string gitCommonDir)
|
||||
public static RepositorySettings Get(string gitCommonDir)
|
||||
{
|
||||
var fileInfo = new FileInfo(Path.Combine(gitCommonDir, "sourcegit.settings"));
|
||||
var fullpath = fileInfo.FullName;
|
||||
if (_cache.TryGetValue(fullpath, out var setting))
|
||||
{
|
||||
setting._usedBy.Add(repo);
|
||||
return setting;
|
||||
}
|
||||
|
||||
if (!File.Exists(fullpath))
|
||||
{
|
||||
@@ -96,28 +97,26 @@ namespace SourceGit.Models
|
||||
}
|
||||
|
||||
setting._file = fullpath;
|
||||
setting._usedBy.Add(repo);
|
||||
setting._orgHash = HashContent(JsonSerializer.Serialize(setting, JsonCodeGen.Default.RepositorySettings));
|
||||
_cache.Add(fullpath, setting);
|
||||
return setting;
|
||||
}
|
||||
|
||||
public void TryUnload(string repo)
|
||||
public async Task SaveAsync()
|
||||
{
|
||||
_usedBy.Remove(repo);
|
||||
|
||||
if (_usedBy.Count == 0)
|
||||
try
|
||||
{
|
||||
try
|
||||
string content = JsonSerializer.Serialize(this, JsonCodeGen.Default.RepositorySettings);
|
||||
string hash = HashContent(content);
|
||||
if (!hash.Equals(_orgHash, StringComparison.Ordinal))
|
||||
{
|
||||
using var stream = File.Create(_file);
|
||||
JsonSerializer.Serialize(stream, this, JsonCodeGen.Default.RepositorySettings);
|
||||
await File.WriteAllTextAsync(_file, content);
|
||||
_orgHash = hash;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore save errors
|
||||
}
|
||||
|
||||
_cache.Remove(_file);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Ignore save errors
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,8 +166,17 @@ namespace SourceGit.Models
|
||||
CustomActions.Move(idx + 1, idx);
|
||||
}
|
||||
|
||||
private static string HashContent(string source)
|
||||
{
|
||||
var hash = MD5.HashData(Encoding.Default.GetBytes(source));
|
||||
var builder = new StringBuilder(hash.Length * 2);
|
||||
foreach (var c in hash)
|
||||
builder.Append(c.ToString("x2"));
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private static Dictionary<string, RepositorySettings> _cache = new();
|
||||
private string _file = string.Empty;
|
||||
private HashSet<string> _usedBy = new();
|
||||
private string _orgHash = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,10 +426,10 @@ namespace SourceGit.ViewModels
|
||||
GitDir = gitDir.Replace('\\', '/').TrimEnd('/');
|
||||
|
||||
var commonDirFile = Path.Combine(GitDir, "commondir");
|
||||
_isWorktree = GitDir.IndexOf("/worktrees/", StringComparison.Ordinal) > 0 &&
|
||||
var isWorktree = GitDir.IndexOf("/worktrees/", StringComparison.Ordinal) > 0 &&
|
||||
File.Exists(commonDirFile);
|
||||
|
||||
if (_isWorktree)
|
||||
if (isWorktree)
|
||||
{
|
||||
var commonDir = File.ReadAllText(commonDirFile).Trim();
|
||||
if (!Path.IsPathRooted(commonDir))
|
||||
@@ -445,7 +445,7 @@ namespace SourceGit.ViewModels
|
||||
|
||||
public void Open()
|
||||
{
|
||||
_settings = Models.RepositorySettings.Get(FullPath, _gitCommonDir);
|
||||
_settings = Models.RepositorySettings.Get(_gitCommonDir);
|
||||
_uiStates = Models.RepositoryUIStates.Load(GitDir);
|
||||
|
||||
try
|
||||
@@ -484,7 +484,6 @@ namespace SourceGit.ViewModels
|
||||
SelectedView = null; // Do NOT modify. Used to remove exists widgets for GC.Collect
|
||||
Logs.Clear();
|
||||
|
||||
_settings.TryUnload(FullPath);
|
||||
_uiStates.Unload(_workingCopy.CommitMessage);
|
||||
|
||||
if (_cancellationRefreshBranches is { IsCancellationRequested: false })
|
||||
@@ -1775,6 +1774,9 @@ namespace SourceGit.ViewModels
|
||||
|
||||
private async Task AutoFetchOnUIThread()
|
||||
{
|
||||
if (_uiStates == null)
|
||||
return;
|
||||
|
||||
CommandLog log = null;
|
||||
|
||||
try
|
||||
@@ -1829,7 +1831,6 @@ namespace SourceGit.ViewModels
|
||||
log?.Complete();
|
||||
}
|
||||
|
||||
private readonly bool _isWorktree = false;
|
||||
private readonly string _gitCommonDir = null;
|
||||
private Models.RepositorySettings _settings = null;
|
||||
private Models.RepositoryUIStates _uiStates = null;
|
||||
|
||||
@@ -295,6 +295,7 @@ namespace SourceGit.ViewModels
|
||||
await SetIfChangedAsync("fetch.prune", EnablePruneOnFetch ? "true" : "false", "false");
|
||||
|
||||
await ApplyIssueTrackerChangesAsync();
|
||||
await _repo.Settings.SaveAsync();
|
||||
}
|
||||
|
||||
private async Task SetIfChangedAsync(string key, string value, string defValue)
|
||||
@@ -359,8 +360,8 @@ namespace SourceGit.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Repository _repo = null;
|
||||
private readonly Dictionary<string, string> _cached = null;
|
||||
private readonly Repository _repo;
|
||||
private readonly Dictionary<string, string> _cached;
|
||||
private string _httpProxy;
|
||||
private Models.CommitTemplate _selectedCommitTemplate = null;
|
||||
private Models.IssueTracker _selectedIssueTracker = null;
|
||||
|
||||
Reference in New Issue
Block a user