Skip to content

Commit ca5bc4b

Browse files
committed
refactor: rewrite the histories filter function to supports both include and exclude modes (#690)
Signed-off-by: leo <[email protected]>
1 parent e3ffe3e commit ca5bc4b

27 files changed

+767
-309
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Avalonia.Data.Converters;
2+
using Avalonia.Media;
3+
4+
namespace SourceGit.Converters
5+
{
6+
public static class FilterModeConverters
7+
{
8+
public static readonly FuncValueConverter<Models.FilterMode, IBrush> ToBorderBrush =
9+
new FuncValueConverter<Models.FilterMode, IBrush>(v =>
10+
{
11+
switch (v)
12+
{
13+
case Models.FilterMode.Included:
14+
return Brushes.Green;
15+
case Models.FilterMode.Excluded:
16+
return Brushes.Red;
17+
default:
18+
return Brushes.Transparent;
19+
}
20+
});
21+
}
22+
}

src/Models/Filter.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using CommunityToolkit.Mvvm.ComponentModel;
2+
3+
namespace SourceGit.Models
4+
{
5+
public enum FilterType
6+
{
7+
LocalBranch = 0,
8+
LocalBranchFolder,
9+
RemoteBranch,
10+
RemoteBranchFolder,
11+
Tag,
12+
}
13+
14+
public enum FilterMode
15+
{
16+
None = 0,
17+
Included,
18+
Excluded,
19+
}
20+
21+
public class Filter : ObservableObject
22+
{
23+
public string Pattern
24+
{
25+
get => _pattern;
26+
set => SetProperty(ref _pattern, value);
27+
}
28+
29+
public FilterType Type
30+
{
31+
get;
32+
set;
33+
} = FilterType.LocalBranch;
34+
35+
public FilterMode Mode
36+
{
37+
get => _mode;
38+
set => SetProperty(ref _mode, value);
39+
}
40+
41+
public bool IsBranch
42+
{
43+
get => Type != FilterType.Tag;
44+
}
45+
46+
public Filter()
47+
{
48+
}
49+
50+
public Filter(string pattern, FilterType type, FilterMode mode)
51+
{
52+
_pattern = pattern;
53+
_mode = mode;
54+
Type = type;
55+
}
56+
57+
private string _pattern = string.Empty;
58+
private FilterMode _mode = FilterMode.None;
59+
}
60+
}

src/Models/RepositorySettings.cs

Lines changed: 181 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
using Avalonia.Collections;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
using Avalonia.Collections;
6+
using Avalonia.Threading;
27

38
namespace SourceGit.Models
49
{
@@ -76,11 +81,11 @@ public bool CheckoutBranchOnCreateBranch
7681
set;
7782
} = true;
7883

79-
public AvaloniaList<string> Filters
84+
public AvaloniaList<Filter> HistoriesFilters
8085
{
8186
get;
8287
set;
83-
} = new AvaloniaList<string>();
88+
} = new AvaloniaList<Filter>();
8489

8590
public AvaloniaList<CommitTemplate> CommitTemplates
8691
{
@@ -148,6 +153,179 @@ public string PreferedOpenAIService
148153
set;
149154
} = "---";
150155

156+
public FilterMode GetHistoriesFilterMode(string pattern, FilterType type)
157+
{
158+
foreach (var filter in HistoriesFilters)
159+
{
160+
if (filter.Type != type)
161+
continue;
162+
163+
if (filter.Pattern.Equals(pattern, StringComparison.Ordinal))
164+
return filter.Mode;
165+
}
166+
167+
return FilterMode.None;
168+
}
169+
170+
public bool UpdateHistoriesFilter(string pattern, FilterType type, FilterMode mode)
171+
{
172+
for (int i = 0; i < HistoriesFilters.Count; i++)
173+
{
174+
var filter = HistoriesFilters[i];
175+
if (filter.Type != type)
176+
continue;
177+
178+
if (filter.Pattern.Equals(pattern, StringComparison.Ordinal))
179+
{
180+
if (mode == FilterMode.None)
181+
{
182+
HistoriesFilters.RemoveAt(i);
183+
return true;
184+
}
185+
186+
if (mode != filter.Mode)
187+
{
188+
filter.Mode = mode;
189+
return true;
190+
}
191+
}
192+
}
193+
194+
if (mode != FilterMode.None)
195+
{
196+
HistoriesFilters.Add(new Filter(pattern, type, mode));
197+
return true;
198+
}
199+
200+
return false;
201+
}
202+
203+
public string BuildHistoriesFilter()
204+
{
205+
var builder = new StringBuilder();
206+
207+
var excludedBranches = new List<string>();
208+
var excludedRemotes = new List<string>();
209+
var excludedTags = new List<string>();
210+
var includedBranches = new List<string>();
211+
var includedRemotes = new List<string>();
212+
var includedTags = new List<string>();
213+
foreach (var filter in HistoriesFilters)
214+
{
215+
if (filter.Type == FilterType.LocalBranch)
216+
{
217+
var name = filter.Pattern.Substring(11);
218+
var b = $"{name.Substring(0, name.Length - 1)}[{name[^1]}]";
219+
220+
if (filter.Mode == FilterMode.Included)
221+
includedBranches.Add(b);
222+
else if (filter.Mode == FilterMode.Excluded)
223+
excludedBranches.Add(b);
224+
}
225+
else if (filter.Type == FilterType.LocalBranchFolder)
226+
{
227+
if (filter.Mode == FilterMode.Included)
228+
includedBranches.Add($"{filter.Pattern.Substring(11)}/*");
229+
else if (filter.Mode == FilterMode.Excluded)
230+
excludedBranches.Add($"{filter.Pattern.Substring(11)}/*");
231+
}
232+
else if (filter.Type == FilterType.RemoteBranch)
233+
{
234+
var name = filter.Pattern.Substring(13);
235+
var r = $"{name.Substring(0, name.Length - 1)}[{name[^1]}]";
236+
237+
if (filter.Mode == FilterMode.Included)
238+
includedRemotes.Add(r);
239+
else if (filter.Mode == FilterMode.Excluded)
240+
excludedRemotes.Add(r);
241+
}
242+
else if (filter.Type == FilterType.RemoteBranchFolder)
243+
{
244+
if (filter.Mode == FilterMode.Included)
245+
includedRemotes.Add($"{filter.Pattern.Substring(13)}/*");
246+
else if (filter.Mode == FilterMode.Excluded)
247+
excludedRemotes.Add($"{filter.Pattern.Substring(13)}/*");
248+
}
249+
else if (filter.Type == FilterType.Tag)
250+
{
251+
var name = filter.Pattern;
252+
var t = $"{name.Substring(0, name.Length - 1)}[{name[^1]}]";
253+
254+
if (filter.Mode == FilterMode.Included)
255+
includedTags.Add(t);
256+
else if (filter.Mode == FilterMode.Excluded)
257+
excludedTags.Add(t);
258+
}
259+
}
260+
261+
foreach (var b in excludedBranches)
262+
{
263+
builder.Append("--exclude=");
264+
builder.Append(b);
265+
builder.Append(' ');
266+
}
267+
268+
if (includedBranches.Count > 0)
269+
{
270+
foreach (var b in includedBranches)
271+
{
272+
builder.Append("--branches=");
273+
builder.Append(b);
274+
builder.Append(' ');
275+
}
276+
}
277+
else if (excludedBranches.Count > 0 || (includedRemotes.Count == 0 && includedTags.Count == 0))
278+
{
279+
builder.Append("--exclude=HEA[D] ");
280+
builder.Append("--branches ");
281+
}
282+
283+
foreach (var r in excludedRemotes)
284+
{
285+
builder.Append("--exclude=");
286+
builder.Append(r);
287+
builder.Append(' ');
288+
}
289+
290+
if (includedRemotes.Count > 0)
291+
{
292+
foreach (var r in includedRemotes)
293+
{
294+
builder.Append("--remotes=");
295+
builder.Append(r);
296+
builder.Append(' ');
297+
}
298+
}
299+
else if (excludedRemotes.Count > 0 || (includedBranches.Count == 0 && includedTags.Count == 0))
300+
{
301+
builder.Append("--exclude=origin/HEA[D] ");
302+
builder.Append("--remotes ");
303+
}
304+
305+
foreach (var t in excludedTags)
306+
{
307+
builder.Append("--exclude=");
308+
builder.Append(t);
309+
builder.Append(' ');
310+
}
311+
312+
if (includedTags.Count > 0)
313+
{
314+
foreach (var t in includedTags)
315+
{
316+
builder.Append("--tags=");
317+
builder.Append(t);
318+
builder.Append(' ');
319+
}
320+
}
321+
else if (excludedTags.Count > 0 || (includedBranches.Count == 0 && includedRemotes.Count == 0))
322+
{
323+
builder.Append("--tags ");
324+
}
325+
326+
return builder.ToString();
327+
}
328+
151329
public void PushCommitMessage(string message)
152330
{
153331
var existIdx = CommitMessages.IndexOf(message);

src/Models/Tag.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,19 @@
1-
namespace SourceGit.Models
1+
using CommunityToolkit.Mvvm.ComponentModel;
2+
3+
namespace SourceGit.Models
24
{
3-
public class Tag
5+
public class Tag : ObservableObject
46
{
5-
public string Name { get; set; }
6-
public string SHA { get; set; }
7-
public string Message { get; set; }
8-
public bool IsFiltered { get; set; }
7+
public string Name { get; set; } = string.Empty;
8+
public string SHA { get; set; } = string.Empty;
9+
public string Message { get; set; } = string.Empty;
10+
11+
public FilterMode FilterMode
12+
{
13+
get => _filterMode;
14+
set => SetProperty(ref _filterMode, value);
15+
}
16+
17+
private FilterMode _filterMode = FilterMode.None;
918
}
1019
}

src/Models/Watcher.cs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,11 @@ private void Tick(object sender)
113113
if (_updateTags > 0)
114114
{
115115
_updateTags = 0;
116-
Task.Run(() =>
117-
{
118-
_repo.RefreshTags();
119-
_repo.RefreshBranches();
120-
_repo.RefreshCommits();
121-
});
122-
}
123-
else
124-
{
125-
Task.Run(() =>
126-
{
127-
_repo.RefreshBranches();
128-
_repo.RefreshCommits();
129-
});
116+
Task.Run(_repo.RefreshTags);
130117
}
131118

119+
Task.Run(_repo.RefreshBranches);
120+
Task.Run(_repo.RefreshCommits);
132121
Task.Run(_repo.RefreshWorkingCopyChanges);
133122
Task.Run(_repo.RefreshWorktrees);
134123
}

src/Resources/Locales/de_DE.axaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,6 @@
292292
<x:String x:Key="Text.FileHistory" xml:space="preserve">Datei Historie</x:String>
293293
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">INHALT</x:String>
294294
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">ÄNDERUNGEN</x:String>
295-
<x:String x:Key="Text.Filter" xml:space="preserve">FILTER</x:String>
296295
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-Flow</x:String>
297296
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Development-Branch:</x:String>
298297
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
@@ -544,7 +543,7 @@
544543
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Aktiviere '--reflog' Option</x:String>
545544
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Öffne im Datei-Browser</x:String>
546545
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Suche Branches/Tags/Submodule</x:String>
547-
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">GEFILTERT:</x:String>
546+
<x:String x:Key="Text.Repository.FilterCommits.Prefix" xml:space="preserve">GEFILTERT:</x:String>
548547
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">LOKALE BRANCHES</x:String>
549548
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Zum HEAD wechseln</x:String>
550549
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Aktiviere '--first-parent' Option</x:String>

src/Resources/Locales/en_US.axaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@
289289
<x:String x:Key="Text.FileHistory" xml:space="preserve">File History</x:String>
290290
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">CONTENT</x:String>
291291
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">CHANGE</x:String>
292-
<x:String x:Key="Text.Filter" xml:space="preserve">FILTER</x:String>
293292
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-Flow</x:String>
294293
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Development Branch:</x:String>
295294
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
@@ -541,7 +540,10 @@
541540
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Enable '--reflog' Option</x:String>
542541
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Open in File Browser</x:String>
543542
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Search Branches/Tags/Submodules</x:String>
544-
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">FILTERED BY:</x:String>
543+
<x:String x:Key="Text.Repository.FilterCommits.Default" xml:space="preserve">Unset (Default)</x:String>
544+
<x:String x:Key="Text.Repository.FilterCommits.Exclude" xml:space="preserve">Hide in commit graph</x:String>
545+
<x:String x:Key="Text.Repository.FilterCommits.Include" xml:space="preserve">Filter in commit graph</x:String>
546+
<x:String x:Key="Text.Repository.FilterCommits.Prefix" xml:space="preserve">FILTERED BY:</x:String>
545547
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">LOCAL BRANCHES</x:String>
546548
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Navigate to HEAD</x:String>
547549
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Enable '--first-parent' Option</x:String>

src/Resources/Locales/es_ES.axaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,6 @@
294294
<x:String x:Key="Text.FileHistory" xml:space="preserve">Historial de Archivos</x:String>
295295
<x:String x:Key="Text.FileHistory.FileContent" xml:space="preserve">CONTENIDO</x:String>
296296
<x:String x:Key="Text.FileHistory.FileChange" xml:space="preserve">CAMBIO</x:String>
297-
<x:String x:Key="Text.Filter" xml:space="preserve">FILTRO</x:String>
298297
<x:String x:Key="Text.GitFlow" xml:space="preserve">Git-Flow</x:String>
299298
<x:String x:Key="Text.GitFlow.DevelopBranch" xml:space="preserve">Rama de Desarrollo:</x:String>
300299
<x:String x:Key="Text.GitFlow.Feature" xml:space="preserve">Feature:</x:String>
@@ -542,7 +541,7 @@
542541
<x:String x:Key="Text.Repository.EnableReflog" xml:space="preserve">Habilitar Opción '--reflog'</x:String>
543542
<x:String x:Key="Text.Repository.Explore" xml:space="preserve">Abrir en el Explorador</x:String>
544543
<x:String x:Key="Text.Repository.Filter" xml:space="preserve">Buscar Ramas/Etiquetas/Submódulos</x:String>
545-
<x:String x:Key="Text.Repository.FilterCommitPrefix" xml:space="preserve">FILTRAR POR:</x:String>
544+
<x:String x:Key="Text.Repository.FilterCommits.Prefix" xml:space="preserve">FILTRAR POR:</x:String>
546545
<x:String x:Key="Text.Repository.LocalBranches" xml:space="preserve">RAMAS LOCALES</x:String>
547546
<x:String x:Key="Text.Repository.NavigateToCurrentHead" xml:space="preserve">Navegar a HEAD</x:String>
548547
<x:String x:Key="Text.Repository.FirstParentFilterToggle" xml:space="preserve">Habilitar Opción '--first-parent'</x:String>

0 commit comments

Comments
 (0)