From a37c6b29ec41fd6d5c7bea08cb5b127abb4b1a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6ran=20W?= <44604769+goran-w@users.noreply.github.com> Date: Mon, 7 Apr 2025 04:37:58 +0200 Subject: [PATCH] In Local Changes, added filter-box in Staged area, to match Unstaged area (#1153) Also added minimal handling (RaiseException) if trying to commit with active filter (might commit more changes than visible, so disallow). Minor unification in unstageChanges() to make it more similar to StageChanges(). --- src/ViewModels/WorkingCopy.cs | 70 ++++++++++++++++++++++++++++------- src/Views/WorkingCopy.axaml | 39 +++++++++++++++++-- 2 files changed, 92 insertions(+), 17 deletions(-) diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 40b4c50c..3e6f6fbd 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -109,12 +109,28 @@ namespace SourceGit.ViewModels if (_isLoadingData) return; - VisibleUnstaged = GetVisibleUnstagedChanges(_unstaged); + VisibleUnstaged = GetVisibleChanges(_unstaged, _unstagedFilter); SelectedUnstaged = []; } } } + public string StagedFilter + { + get => _stagedFilter; + set + { + if (SetProperty(ref _stagedFilter, value)) + { + if (_isLoadingData) + return; + + VisibleStaged = GetVisibleChanges(_staged, _stagedFilter); + SelectedStaged = []; + } + } + } + public List Unstaged { get => _unstaged; @@ -133,6 +149,12 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _staged, value); } + public List VisibleStaged + { + get => _visibleStaged; + private set => SetProperty(ref _visibleStaged, value); + } + public List SelectedUnstaged { get => _selectedUnstaged; @@ -216,6 +238,9 @@ namespace SourceGit.ViewModels _visibleUnstaged.Clear(); OnPropertyChanged(nameof(VisibleUnstaged)); + _visibleStaged.Clear(); + OnPropertyChanged(nameof(VisibleStaged)); + _unstaged.Clear(); OnPropertyChanged(nameof(Unstaged)); @@ -269,7 +294,7 @@ namespace SourceGit.ViewModels } } - var visibleUnstaged = GetVisibleUnstagedChanges(unstaged); + var visibleUnstaged = GetVisibleChanges(unstaged, _unstagedFilter); var selectedUnstaged = new List(); foreach (var c in visibleUnstaged) { @@ -278,8 +303,10 @@ namespace SourceGit.ViewModels } var staged = GetStagedChanges(); + + var visibleStaged = GetVisibleChanges(staged, _stagedFilter); var selectedStaged = new List(); - foreach (var c in staged) + foreach (var c in visibleStaged) { if (lastSelectedStaged.Contains(c.Path)) selectedStaged.Add(c); @@ -290,6 +317,7 @@ namespace SourceGit.ViewModels _isLoadingData = true; HasUnsolvedConflicts = hasConflict; VisibleUnstaged = visibleUnstaged; + VisibleStaged = visibleStaged; Unstaged = unstaged; Staged = staged; SelectedUnstaged = selectedUnstaged; @@ -337,7 +365,7 @@ namespace SourceGit.ViewModels public void UnstageAll() { - UnstageChanges(_staged, null); + UnstageChanges(_visibleStaged, null); } public void Discard(List changes) @@ -350,6 +378,11 @@ namespace SourceGit.ViewModels { UnstagedFilter = string.Empty; } + + public void ClearStagedFilter() + { + StagedFilter = string.Empty; + } public async void UseTheirs(List changes) { @@ -1472,16 +1505,16 @@ namespace SourceGit.ViewModels return menu; } - private List GetVisibleUnstagedChanges(List unstaged) + private List GetVisibleChanges(List changes, string filter) { - if (string.IsNullOrEmpty(_unstagedFilter)) - return unstaged; + if (string.IsNullOrEmpty(filter)) + return changes; var visible = new List(); - foreach (var c in unstaged) + foreach (var c in changes) { - if (c.Path.Contains(_unstagedFilter, StringComparison.OrdinalIgnoreCase)) + if (c.Path.Contains(filter, StringComparison.OrdinalIgnoreCase)) visible.Add(c); } @@ -1599,7 +1632,8 @@ namespace SourceGit.ViewModels private async void UnstageChanges(List changes, Models.Change next) { - if (changes.Count == 0) + var count = changes.Count; + if (count == 0) return; // Use `_selectedStaged` instead of `SelectedStaged` to avoid UI refresh. @@ -1611,16 +1645,15 @@ namespace SourceGit.ViewModels { await Task.Run(() => new Commands.UnstageChangesForAmend(_repo.FullPath, changes).Exec()); } - else if (changes.Count == _staged.Count) + else if (count == _staged.Count) { await Task.Run(() => new Commands.Reset(_repo.FullPath).Exec()); } else { - for (int i = 0; i < changes.Count; i += 10) + for (int i = 0; i < count; i += 10) { - var count = Math.Min(10, changes.Count - i); - var step = changes.GetRange(i, count); + var step = changes.GetRange(i, Math.Min(10, count - i)); await Task.Run(() => new Commands.Reset(_repo.FullPath, step).Exec()); } } @@ -1650,6 +1683,13 @@ namespace SourceGit.ViewModels return; } + if (!string.IsNullOrEmpty(_stagedFilter)) + { + // FIXME - make this a proper warning message-box "Staged-area filter will not be applied to commit. Continue?" Yes/No + App.RaiseException(_repo.FullPath, "Committing with staged-area filter applied is NOT allowed!"); + return; + } + if (string.IsNullOrWhiteSpace(_commitMessage)) { App.RaiseException(_repo.FullPath, "Commit without message is NOT allowed!"); @@ -1729,11 +1769,13 @@ namespace SourceGit.ViewModels private List _unstaged = []; private List _visibleUnstaged = []; private List _staged = []; + private List _visibleStaged = []; private List _selectedUnstaged = []; private List _selectedStaged = []; private int _count = 0; private object _detailContext = null; private string _unstagedFilter = string.Empty; + private string _stagedFilter = string.Empty; private string _commitMessage = string.Empty; private bool _hasUnsolvedConflicts = false; diff --git a/src/Views/WorkingCopy.axaml b/src/Views/WorkingCopy.axaml index 4d79135d..6af2b448 100644 --- a/src/Views/WorkingCopy.axaml +++ b/src/Views/WorkingCopy.axaml @@ -129,7 +129,7 @@ Background="{DynamicResource Brush.Border0}"/> - + @@ -156,14 +156,47 @@ + + + + + + + + + + + + + -