From 11ad7f56d9a2ba99f079457b0d6ac5aa5c43f403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernat=20Borr=C3=A0s=20Civil?= <70479573+BernatBC@users.noreply.github.com> Date: Fri, 11 Apr 2025 16:43:20 +0200 Subject: [PATCH] Fix counter issue --- src/Commands/QueryCommitChangedLines.cs | 30 ++++++------- src/Models/Commit.cs | 41 +++++++++++++++-- src/ViewModels/CommitDetail.cs | 60 ++++++++++++++++++++----- src/Views/CommitBaseInfo.axaml.cs | 20 +++++++++ 4 files changed, 123 insertions(+), 28 deletions(-) diff --git a/src/Commands/QueryCommitChangedLines.cs b/src/Commands/QueryCommitChangedLines.cs index 018072cc..75a75c24 100644 --- a/src/Commands/QueryCommitChangedLines.cs +++ b/src/Commands/QueryCommitChangedLines.cs @@ -8,38 +8,38 @@ namespace SourceGit.Commands { WorkingDirectory = repo; Context = repo; - Args = $"show --numstat --oneline {sha}"; + // Use shortstat for faster results, which is enough for our needs + Args = $"show --shortstat --oneline {sha}"; + _pattern = new Regex(@"(\d+) files? changed(?:, (\d+) insertions?\(\+\))?(?:, (\d+) deletions?\(-\))?"); } public (int, int) Result() { _addedLines = 0; _removedLines = 0; - _firstLine = true; Exec(); return (_addedLines, _removedLines); } protected override void OnReadline(string line) { - if (_firstLine) { - _firstLine = false; - return; - } - - var parts = Regex.Split(line, @"\s+"); - - if (parts.Length >= 2) + var match = _pattern.Match(line); + if (match.Success) { - bool canParseAdded = int.TryParse(parts[0], out int addedLines); - bool canParseRemoved = int.TryParse(parts[1], out int removedLines); - if (canParseAdded) _addedLines += addedLines; - if (canParseRemoved) _removedLines += removedLines; + if (match.Groups[2].Success) + { + _addedLines = int.Parse(match.Groups[2].Value); + } + + if (match.Groups[3].Success) + { + _removedLines = int.Parse(match.Groups[3].Value); + } } } + private readonly Regex _pattern; private int _addedLines; private int _removedLines; - private bool _firstLine; } } diff --git a/src/Models/Commit.cs b/src/Models/Commit.cs index 3840f62e..5f401a14 100644 --- a/src/Models/Commit.cs +++ b/src/Models/Commit.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; using Avalonia; using Avalonia.Media; @@ -13,8 +15,15 @@ namespace SourceGit.Models ByFile, } - public class Commit + public class Commit : INotifyPropertyChanged { + public event PropertyChangedEventHandler PropertyChanged; + + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + public static double OpacityForNotMerged { get; @@ -45,8 +54,34 @@ namespace SourceGit.Models public Thickness Margin { get; set; } = new Thickness(0); public IBrush Brush => CommitGraph.Pens[Color].Brush; - public int AddedLines { get; set; } = 0; - public int RemovedLines { get; set; } = 0; + private int _addedLines = 0; + private int _removedLines = 0; + + public int AddedLines + { + get => _addedLines; + set + { + if (_addedLines != value) + { + _addedLines = value; + OnPropertyChanged(); + } + } + } + + public int RemovedLines + { + get => _removedLines; + set + { + if (_removedLines != value) + { + _removedLines = value; + OnPropertyChanged(); + } + } + } public void ParseDecorators(string data) { diff --git a/src/ViewModels/CommitDetail.cs b/src/ViewModels/CommitDetail.cs index d2cc0b06..639b9210 100644 --- a/src/ViewModels/CommitDetail.cs +++ b/src/ViewModels/CommitDetail.cs @@ -581,7 +581,7 @@ namespace SourceGit.ViewModels menu.Items.Add(resetToThisRevision); menu.Items.Add(resetToFirstParent); - menu.Items.Add(new MenuItem() { Header = "-" }); + menu.Items.Add(new MenuItem { Header = "-" }); if (File.Exists(Path.Combine(fullPath))) TryToAddContextMenuItemsForGitLFS(menu, file.Path); @@ -629,21 +629,41 @@ namespace SourceGit.ViewModels if (_commit == null) return; + // Load line count data immediately with higher priority + var sha = _commit.SHA; + + // Check if we already have the line count data cached + if (_lineCountCache.TryGetValue(sha, out var lineCount)) + { + // Update immediately in the UI thread + _commit.AddedLines = lineCount.added; + _commit.RemovedLines = lineCount.removed; + } + else + { + // Start loading line count data with high priority + Task.Run(() => + { + (var addedLines, var removedLines) = new Commands.QueryCommitChangedLines(_repo.FullPath, sha).Result(); + _lineCountCache[sha] = (addedLines, removedLines); + + Dispatcher.UIThread.Invoke(() => { + if (_commit != null && _commit.SHA == sha) + { + _commit.AddedLines = addedLines; + _commit.RemovedLines = removedLines; + } + }); + }); + } + + // Continue with other loading tasks... Task.Run(() => { var fullMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, _commit.SHA).Result(); Dispatcher.UIThread.Invoke(() => FullMessage = fullMessage); }); - Task.Run(() => - { - (var addedLines, var removedLines) = new Commands.QueryCommitChangedLines(_repo.FullPath, _commit.SHA).Result(); - Dispatcher.UIThread.Invoke(() => { - _commit.AddedLines = addedLines; - _commit.RemovedLines = removedLines; - }); - }); - Task.Run(() => { var signInfo = new Commands.QueryCommitSignInfo(_repo.FullPath, _commit.SHA, !_repo.HasAllowedSignersFile).Result(); @@ -694,6 +714,25 @@ namespace SourceGit.ViewModels }); } + // Add a method to preload line count data for visible commits + public void PreloadLineCountData(List commitSHAs) + { + if (commitSHAs == null || commitSHAs.Count == 0) + return; + + Task.Run(() => + { + foreach (var sha in commitSHAs) + { + if (!_lineCountCache.ContainsKey(sha)) + { + var (addedLines, removedLines) = new Commands.QueryCommitChangedLines(_repo.FullPath, sha).Result(); + _lineCountCache[sha] = (addedLines, removedLines); + } + } + }); + } + private void RefreshVisibleChanges() { if (_changes == null) @@ -841,5 +880,6 @@ namespace SourceGit.ViewModels private List _revisionFiles = []; private string _revisionFileSearchFilter = string.Empty; private bool _isRevisionFileSearchSuggestionOpen = false; + private Dictionary _lineCountCache = new Dictionary(); } } diff --git a/src/Views/CommitBaseInfo.axaml.cs b/src/Views/CommitBaseInfo.axaml.cs index ce1a7cfd..ea0c09d4 100644 --- a/src/Views/CommitBaseInfo.axaml.cs +++ b/src/Views/CommitBaseInfo.axaml.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Avalonia; @@ -70,6 +71,25 @@ namespace SourceGit.Views InitializeComponent(); } + protected override void OnDataContextChanged(EventArgs e) + { + base.OnDataContextChanged(e); + + // When the DataContext changes, we need to re-evaluate any bindings + // This ensures that when the Commit property changes, the UI is updated + if (DataContext is ViewModels.CommitDetail detail) + { + detail.PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(detail.Commit)) + { + // Force UI update for the commit lines + InvalidateVisual(); + } + }; + } + } + private void OnCopyCommitSHA(object sender, RoutedEventArgs e) { if (sender is Button { DataContext: Models.Commit commit })