From dcf50934061e1e9549b8073b7c87dede6873096c Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 4 Nov 2024 18:21:07 +0800 Subject: [PATCH] enhance: avoid that diff view refresh more than one times Signed-off-by: leo --- src/Commands/Diff.cs | 32 ++++++++++++++++++------ src/Models/DiffResult.cs | 2 ++ src/ViewModels/DiffContext.cs | 46 ++++++++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/Commands/Diff.cs b/src/Commands/Diff.cs index b9b6e064..04103d68 100644 --- a/src/Commands/Diff.cs +++ b/src/Commands/Diff.cs @@ -8,6 +8,10 @@ namespace SourceGit.Commands { [GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")] private static partial Regex REG_INDICATOR(); + + [GeneratedRegex(@"^index\s([0-9a-f]{6,40})\.\.([0-9a-f]{6,40})(\s[1-9]{6})?")] + private static partial Regex REG_HASH_CHANGE(); + private const string PREFIX_LFS_NEW = "+version https://git-lfs.github.com/spec/"; private const string PREFIX_LFS_DEL = "-version https://git-lfs.github.com/spec/"; private const string PREFIX_LFS_MODIFY = " version https://git-lfs.github.com/spec/"; @@ -101,17 +105,31 @@ namespace SourceGit.Commands if (_result.TextDiff.Lines.Count == 0) { - var match = REG_INDICATOR().Match(line); - if (!match.Success) + if (line.StartsWith("Binary", StringComparison.Ordinal)) { - if (line.StartsWith("Binary", StringComparison.Ordinal)) - _result.IsBinary = true; + _result.IsBinary = true; return; } - _oldLine = int.Parse(match.Groups[1].Value); - _newLine = int.Parse(match.Groups[2].Value); - _result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0)); + if (string.IsNullOrEmpty(_result.OldHash)) + { + var match = REG_HASH_CHANGE().Match(line); + if (!match.Success) + return; + + _result.OldHash = match.Groups[1].Value; + _result.NewHash = match.Groups[2].Value; + } + else + { + var match = REG_INDICATOR().Match(line); + if (!match.Success) + return; + + _oldLine = int.Parse(match.Groups[1].Value); + _newLine = int.Parse(match.Groups[2].Value); + _result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0)); + } } else { diff --git a/src/Models/DiffResult.cs b/src/Models/DiffResult.cs index 61255ae9..e0ae82e0 100644 --- a/src/Models/DiffResult.cs +++ b/src/Models/DiffResult.cs @@ -674,6 +674,8 @@ namespace SourceGit.Models { public bool IsBinary { get; set; } = false; public bool IsLFS { get; set; } = false; + public string OldHash { get; set; } = string.Empty; + public string NewHash { get; set; } = string.Empty; public string OldMode { get; set; } = string.Empty; public string NewMode { get; set; } = string.Empty; public TextDiff TextDiff { get; set; } = null; diff --git a/src/ViewModels/DiffContext.cs b/src/ViewModels/DiffContext.cs index cfb9fa79..87b1a6de 100644 --- a/src/ViewModels/DiffContext.cs +++ b/src/ViewModels/DiffContext.cs @@ -33,12 +33,6 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _fileModeChange, value); } - public bool IsLoading - { - get => _isLoading; - private set => SetProperty(ref _isLoading, value); - } - public bool IsTextDiff { get => _isTextDiff; @@ -68,6 +62,7 @@ namespace SourceGit.ViewModels _content = previous._content; _unifiedLines = previous._unifiedLines; _ignoreWhitespace = previous._ignoreWhitespace; + _info = previous._info; } if (string.IsNullOrEmpty(_option.OrgPath) || _option.OrgPath == "/dev/null") @@ -109,7 +104,6 @@ namespace SourceGit.ViewModels { Content = null; IsTextDiff = false; - IsLoading = false; return; } @@ -119,10 +113,14 @@ namespace SourceGit.ViewModels // There is no way to tell a git-diff to use "ALL lines of context", // so instead we set a very high number for the "lines of context" parameter. var numLines = Preference.Instance.UseFullTextDiff ? 999999999 : _unifiedLines; - var latest = new Commands.Diff(_repo, _option, numLines, _ignoreWhitespace).Result(); - var rs = null as object; + var info = new Info(_option, numLines, _ignoreWhitespace, latest); + if (_info != null && info.IsSame(_info)) + return; + _info = info; + + var rs = null as object; if (latest.TextDiff != null) { var count = latest.TextDiff.Lines.Count; @@ -219,7 +217,6 @@ namespace SourceGit.ViewModels FileModeChange = latest.FileModeChange; Content = rs; IsTextDiff = rs is Models.TextDiff; - IsLoading = false; }); }); } @@ -252,14 +249,41 @@ namespace SourceGit.ViewModels ".ico", ".bmp", ".jpg", ".png", ".jpeg", ".webp" }; + private class Info + { + public string Argument { get; set; } + public int UnifiedLines { get; set; } + public bool IgnoreWhitespace { get; set; } + public string OldHash { get; set; } + public string NewHash { get; set; } + + public Info(Models.DiffOption option, int unifiedLines, bool ignoreWhitespace, Models.DiffResult result) + { + Argument = option.ToString(); + UnifiedLines = unifiedLines; + IgnoreWhitespace = ignoreWhitespace; + OldHash = result.OldHash; + NewHash = result.NewHash; + } + + public bool IsSame(Info other) + { + return Argument.Equals(other.Argument, StringComparison.Ordinal) && + UnifiedLines == other.UnifiedLines && + IgnoreWhitespace == other.IgnoreWhitespace && + OldHash.Equals(other.OldHash, StringComparison.Ordinal) && + NewHash.Equals(other.NewHash, StringComparison.Ordinal); + } + } + private readonly string _repo; private readonly Models.DiffOption _option = null; private string _title; private string _fileModeChange = string.Empty; private int _unifiedLines = 4; - private bool _isLoading = true; private bool _isTextDiff = false; private bool _ignoreWhitespace = false; private object _content = null; + private Info _info = null; } }