mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-23 05:05:00 +00:00
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().
This commit is contained in:
parent
ac7b02590b
commit
a37c6b29ec
2 changed files with 92 additions and 17 deletions
|
@ -109,12 +109,28 @@ namespace SourceGit.ViewModels
|
||||||
if (_isLoadingData)
|
if (_isLoadingData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VisibleUnstaged = GetVisibleUnstagedChanges(_unstaged);
|
VisibleUnstaged = GetVisibleChanges(_unstaged, _unstagedFilter);
|
||||||
SelectedUnstaged = [];
|
SelectedUnstaged = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string StagedFilter
|
||||||
|
{
|
||||||
|
get => _stagedFilter;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _stagedFilter, value))
|
||||||
|
{
|
||||||
|
if (_isLoadingData)
|
||||||
|
return;
|
||||||
|
|
||||||
|
VisibleStaged = GetVisibleChanges(_staged, _stagedFilter);
|
||||||
|
SelectedStaged = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<Models.Change> Unstaged
|
public List<Models.Change> Unstaged
|
||||||
{
|
{
|
||||||
get => _unstaged;
|
get => _unstaged;
|
||||||
|
@ -133,6 +149,12 @@ namespace SourceGit.ViewModels
|
||||||
private set => SetProperty(ref _staged, value);
|
private set => SetProperty(ref _staged, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Models.Change> VisibleStaged
|
||||||
|
{
|
||||||
|
get => _visibleStaged;
|
||||||
|
private set => SetProperty(ref _visibleStaged, value);
|
||||||
|
}
|
||||||
|
|
||||||
public List<Models.Change> SelectedUnstaged
|
public List<Models.Change> SelectedUnstaged
|
||||||
{
|
{
|
||||||
get => _selectedUnstaged;
|
get => _selectedUnstaged;
|
||||||
|
@ -216,6 +238,9 @@ namespace SourceGit.ViewModels
|
||||||
_visibleUnstaged.Clear();
|
_visibleUnstaged.Clear();
|
||||||
OnPropertyChanged(nameof(VisibleUnstaged));
|
OnPropertyChanged(nameof(VisibleUnstaged));
|
||||||
|
|
||||||
|
_visibleStaged.Clear();
|
||||||
|
OnPropertyChanged(nameof(VisibleStaged));
|
||||||
|
|
||||||
_unstaged.Clear();
|
_unstaged.Clear();
|
||||||
OnPropertyChanged(nameof(Unstaged));
|
OnPropertyChanged(nameof(Unstaged));
|
||||||
|
|
||||||
|
@ -269,7 +294,7 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var visibleUnstaged = GetVisibleUnstagedChanges(unstaged);
|
var visibleUnstaged = GetVisibleChanges(unstaged, _unstagedFilter);
|
||||||
var selectedUnstaged = new List<Models.Change>();
|
var selectedUnstaged = new List<Models.Change>();
|
||||||
foreach (var c in visibleUnstaged)
|
foreach (var c in visibleUnstaged)
|
||||||
{
|
{
|
||||||
|
@ -278,8 +303,10 @@ namespace SourceGit.ViewModels
|
||||||
}
|
}
|
||||||
|
|
||||||
var staged = GetStagedChanges();
|
var staged = GetStagedChanges();
|
||||||
|
|
||||||
|
var visibleStaged = GetVisibleChanges(staged, _stagedFilter);
|
||||||
var selectedStaged = new List<Models.Change>();
|
var selectedStaged = new List<Models.Change>();
|
||||||
foreach (var c in staged)
|
foreach (var c in visibleStaged)
|
||||||
{
|
{
|
||||||
if (lastSelectedStaged.Contains(c.Path))
|
if (lastSelectedStaged.Contains(c.Path))
|
||||||
selectedStaged.Add(c);
|
selectedStaged.Add(c);
|
||||||
|
@ -290,6 +317,7 @@ namespace SourceGit.ViewModels
|
||||||
_isLoadingData = true;
|
_isLoadingData = true;
|
||||||
HasUnsolvedConflicts = hasConflict;
|
HasUnsolvedConflicts = hasConflict;
|
||||||
VisibleUnstaged = visibleUnstaged;
|
VisibleUnstaged = visibleUnstaged;
|
||||||
|
VisibleStaged = visibleStaged;
|
||||||
Unstaged = unstaged;
|
Unstaged = unstaged;
|
||||||
Staged = staged;
|
Staged = staged;
|
||||||
SelectedUnstaged = selectedUnstaged;
|
SelectedUnstaged = selectedUnstaged;
|
||||||
|
@ -337,7 +365,7 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
public void UnstageAll()
|
public void UnstageAll()
|
||||||
{
|
{
|
||||||
UnstageChanges(_staged, null);
|
UnstageChanges(_visibleStaged, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Discard(List<Models.Change> changes)
|
public void Discard(List<Models.Change> changes)
|
||||||
|
@ -351,6 +379,11 @@ namespace SourceGit.ViewModels
|
||||||
UnstagedFilter = string.Empty;
|
UnstagedFilter = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearStagedFilter()
|
||||||
|
{
|
||||||
|
StagedFilter = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
public async void UseTheirs(List<Models.Change> changes)
|
public async void UseTheirs(List<Models.Change> changes)
|
||||||
{
|
{
|
||||||
_repo.SetWatcherEnabled(false);
|
_repo.SetWatcherEnabled(false);
|
||||||
|
@ -1472,16 +1505,16 @@ namespace SourceGit.ViewModels
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Models.Change> GetVisibleUnstagedChanges(List<Models.Change> unstaged)
|
private List<Models.Change> GetVisibleChanges(List<Models.Change> changes, string filter)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_unstagedFilter))
|
if (string.IsNullOrEmpty(filter))
|
||||||
return unstaged;
|
return changes;
|
||||||
|
|
||||||
var visible = new List<Models.Change>();
|
var visible = new List<Models.Change>();
|
||||||
|
|
||||||
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);
|
visible.Add(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1599,7 +1632,8 @@ namespace SourceGit.ViewModels
|
||||||
|
|
||||||
private async void UnstageChanges(List<Models.Change> changes, Models.Change next)
|
private async void UnstageChanges(List<Models.Change> changes, Models.Change next)
|
||||||
{
|
{
|
||||||
if (changes.Count == 0)
|
var count = changes.Count;
|
||||||
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Use `_selectedStaged` instead of `SelectedStaged` to avoid UI refresh.
|
// 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());
|
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());
|
await Task.Run(() => new Commands.Reset(_repo.FullPath).Exec());
|
||||||
}
|
}
|
||||||
else
|
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, Math.Min(10, count - i));
|
||||||
var step = changes.GetRange(i, count);
|
|
||||||
await Task.Run(() => new Commands.Reset(_repo.FullPath, step).Exec());
|
await Task.Run(() => new Commands.Reset(_repo.FullPath, step).Exec());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1650,6 +1683,13 @@ namespace SourceGit.ViewModels
|
||||||
return;
|
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))
|
if (string.IsNullOrWhiteSpace(_commitMessage))
|
||||||
{
|
{
|
||||||
App.RaiseException(_repo.FullPath, "Commit without message is NOT allowed!");
|
App.RaiseException(_repo.FullPath, "Commit without message is NOT allowed!");
|
||||||
|
@ -1729,11 +1769,13 @@ namespace SourceGit.ViewModels
|
||||||
private List<Models.Change> _unstaged = [];
|
private List<Models.Change> _unstaged = [];
|
||||||
private List<Models.Change> _visibleUnstaged = [];
|
private List<Models.Change> _visibleUnstaged = [];
|
||||||
private List<Models.Change> _staged = [];
|
private List<Models.Change> _staged = [];
|
||||||
|
private List<Models.Change> _visibleStaged = [];
|
||||||
private List<Models.Change> _selectedUnstaged = [];
|
private List<Models.Change> _selectedUnstaged = [];
|
||||||
private List<Models.Change> _selectedStaged = [];
|
private List<Models.Change> _selectedStaged = [];
|
||||||
private int _count = 0;
|
private int _count = 0;
|
||||||
private object _detailContext = null;
|
private object _detailContext = null;
|
||||||
private string _unstagedFilter = string.Empty;
|
private string _unstagedFilter = string.Empty;
|
||||||
|
private string _stagedFilter = string.Empty;
|
||||||
private string _commitMessage = string.Empty;
|
private string _commitMessage = string.Empty;
|
||||||
|
|
||||||
private bool _hasUnsolvedConflicts = false;
|
private bool _hasUnsolvedConflicts = false;
|
||||||
|
|
|
@ -129,7 +129,7 @@
|
||||||
Background="{DynamicResource Brush.Border0}"/>
|
Background="{DynamicResource Brush.Border0}"/>
|
||||||
|
|
||||||
<!-- Staged -->
|
<!-- Staged -->
|
||||||
<Grid Grid.Row="2" RowDefinitions="28,*">
|
<Grid Grid.Row="2" RowDefinitions="28,36,*">
|
||||||
<!-- Staged Toolbar -->
|
<!-- Staged Toolbar -->
|
||||||
<Border Grid.Row="0" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}">
|
<Border Grid.Row="0" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}">
|
||||||
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto,Auto">
|
<Grid ColumnDefinitions="Auto,Auto,Auto,Auto,*,Auto,Auto,Auto">
|
||||||
|
@ -156,14 +156,47 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
<!-- Staged Filter -->
|
||||||
|
<Border Grid.Row="1" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}">
|
||||||
|
<TextBox Height="24"
|
||||||
|
Margin="4,0"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="12"
|
||||||
|
Text="{Binding StagedFilter, Mode=TwoWay}"
|
||||||
|
BorderBrush="{DynamicResource Brush.Border2}"
|
||||||
|
VerticalContentAlignment="Center">
|
||||||
|
<TextBox.InnerLeftContent>
|
||||||
|
<Path Width="14" Height="14"
|
||||||
|
Margin="6,0,0,0"
|
||||||
|
Fill="{DynamicResource Brush.FG2}"
|
||||||
|
Data="{StaticResource Icons.Search}"/>
|
||||||
|
</TextBox.InnerLeftContent>
|
||||||
|
|
||||||
|
<TextBox.InnerRightContent>
|
||||||
|
<Button Classes="icon_button"
|
||||||
|
Width="16"
|
||||||
|
Margin="0,0,6,0"
|
||||||
|
Command="{Binding ClearStagedFilter}"
|
||||||
|
IsVisible="{Binding StagedFilter, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"
|
||||||
|
HorizontalAlignment="Right">
|
||||||
|
<Path Width="14" Height="14"
|
||||||
|
Margin="0,1,0,0"
|
||||||
|
Fill="{DynamicResource Brush.FG1}"
|
||||||
|
Data="{StaticResource Icons.Clear}"/>
|
||||||
|
</Button>
|
||||||
|
</TextBox.InnerRightContent>
|
||||||
|
</TextBox>
|
||||||
|
</Border>
|
||||||
|
|
||||||
<!-- Staged Changes -->
|
<!-- Staged Changes -->
|
||||||
<v:ChangeCollectionView Grid.Row="1"
|
<v:ChangeCollectionView Grid.Row="2"
|
||||||
x:Name="StagedChangesView"
|
x:Name="StagedChangesView"
|
||||||
Focusable="True"
|
Focusable="True"
|
||||||
|
IsUnstagedChange="False"
|
||||||
SelectionMode="Multiple"
|
SelectionMode="Multiple"
|
||||||
Background="{DynamicResource Brush.Contents}"
|
Background="{DynamicResource Brush.Contents}"
|
||||||
ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=StagedChangeViewMode}"
|
ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=StagedChangeViewMode}"
|
||||||
Changes="{Binding Staged}"
|
Changes="{Binding VisibleStaged}"
|
||||||
SelectedChanges="{Binding SelectedStaged, Mode=TwoWay}"
|
SelectedChanges="{Binding SelectedStaged, Mode=TwoWay}"
|
||||||
ContextRequested="OnStagedContextRequested"
|
ContextRequested="OnStagedContextRequested"
|
||||||
ChangeDoubleTapped="OnStagedChangeDoubleTapped"
|
ChangeDoubleTapped="OnStagedChangeDoubleTapped"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue