Skip to content

Commit 1fe2be1

Browse files
committed
refactor: rewrite submodule to support IsDirty state (#339)
1 parent eb44185 commit 1fe2be1

File tree

10 files changed

+110
-19
lines changed

10 files changed

+110
-19
lines changed

src/Commands/QuerySubmodules.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ public QuerySubmodules(string repo)
1717
Args = "submodule status";
1818
}
1919

20-
public List<string> Result()
20+
public List<Models.Submodule> Result()
2121
{
2222
Exec();
23+
new UpdateSubmoduleStatus(WorkingDirectory, _submodules).Result();
2324
return _submodules;
2425
}
2526

@@ -28,17 +29,17 @@ protected override void OnReadline(string line)
2829
var match = REG_FORMAT1().Match(line);
2930
if (match.Success)
3031
{
31-
_submodules.Add(match.Groups[1].Value);
32+
_submodules.Add(new Models.Submodule() { Path = match.Groups[1].Value });
3233
return;
3334
}
3435

3536
match = REG_FORMAT2().Match(line);
3637
if (match.Success)
3738
{
38-
_submodules.Add(match.Groups[1].Value);
39+
_submodules.Add(new Models.Submodule() { Path = match.Groups[1].Value });
3940
}
4041
}
4142

42-
private readonly List<string> _submodules = new List<string>();
43+
private readonly List<Models.Submodule> _submodules = new List<Models.Submodule>();
4344
}
4445
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Collections.Generic;
2+
using System.Text;
3+
using System.Text.RegularExpressions;
4+
5+
namespace SourceGit.Commands
6+
{
7+
public partial class UpdateSubmoduleStatus : Command
8+
{
9+
[GeneratedRegex(@"^\s?[\w\?]{1,4}\s+(.+)$")]
10+
private static partial Regex REG_FORMAT();
11+
12+
public UpdateSubmoduleStatus(string repo, List<Models.Submodule> submodules)
13+
{
14+
var pathes = new StringBuilder();
15+
foreach (var submodule in submodules)
16+
pathes.Append($"\"{submodule.Path}\" ");
17+
18+
_submodules = submodules;
19+
20+
WorkingDirectory = repo;
21+
Context = repo;
22+
Args = $"status -uno --porcelain -- {pathes}";
23+
}
24+
25+
public void Result()
26+
{
27+
Exec();
28+
29+
foreach (var submodule in _submodules)
30+
submodule.IsDirty = _changed.Contains(submodule.Path);
31+
}
32+
33+
protected override void OnReadline(string line)
34+
{
35+
var match = REG_FORMAT().Match(line);
36+
if (match.Success)
37+
_changed.Add(match.Groups[1].Value);
38+
}
39+
40+
private List<Models.Submodule> _submodules = null;
41+
private HashSet<string> _changed = new HashSet<string>();
42+
}
43+
}

src/Models/IssueTrackerRule.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System.Collections.Generic;
22
using System.Text.RegularExpressions;
33

4-
using Avalonia.Collections;
5-
64
using CommunityToolkit.Mvvm.ComponentModel;
75

86
namespace SourceGit.Models

src/Models/Submodule.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace SourceGit.Models
2+
{
3+
public class Submodule
4+
{
5+
public string Path { get; set; } = "";
6+
public bool IsDirty { get; set; } = false;
7+
}
8+
}

src/Models/Watcher.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Threading;
45
using System.Threading.Tasks;
@@ -70,6 +71,16 @@ public void SetEnabled(bool enabled)
7071
}
7172
}
7273

74+
public void UpdateSubmodules(List<Submodule> submodules)
75+
{
76+
lock (_lockSubmodule)
77+
{
78+
_submodules.Clear();
79+
foreach (var submodule in submodules)
80+
_submodules.Add(submodule.Path);
81+
}
82+
}
83+
7384
public void MarkBranchDirtyManually()
7485
{
7586
_updateBranch = DateTime.Now.ToFileTime() - 1;
@@ -168,7 +179,7 @@ private void OnRepositoryChanged(object o, FileSystemEventArgs e)
168179
return;
169180

170181
var name = e.Name.Replace("\\", "/");
171-
if (name.StartsWith("modules", StringComparison.Ordinal))
182+
if (name.StartsWith("modules", StringComparison.Ordinal) && name.EndsWith("HEAD", StringComparison.Ordinal))
172183
{
173184
_updateSubmodules = DateTime.Now.AddSeconds(1).ToFileTime();
174185
}
@@ -201,6 +212,19 @@ private void OnWorkingCopyChanged(object o, FileSystemEventArgs e)
201212
var name = e.Name.Replace("\\", "/");
202213
if (name == ".git" || name.StartsWith(".git/", StringComparison.Ordinal))
203214
return;
215+
216+
lock (_submodules)
217+
{
218+
foreach (var submodule in _submodules)
219+
{
220+
if (name.StartsWith(submodule, StringComparison.Ordinal))
221+
{
222+
_updateSubmodules = DateTime.Now.AddSeconds(1).ToFileTime();
223+
return;
224+
}
225+
}
226+
}
227+
204228
_updateWC = DateTime.Now.AddSeconds(1).ToFileTime();
205229
}
206230

@@ -214,5 +238,8 @@ private void OnWorkingCopyChanged(object o, FileSystemEventArgs e)
214238
private long _updateSubmodules = 0;
215239
private long _updateStashes = 0;
216240
private long _updateTags = 0;
241+
242+
private object _lockSubmodule = new object();
243+
private List<string> _submodules = new List<string>();
217244
}
218245
}

src/Resources/Icons.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<StreamGeometry x:Key="Icons.MacOS.Maximize">M0 4 0 20 16 20 0 4M4 0 20 0 20 16 4 0z</StreamGeometry>
6969
<StreamGeometry x:Key="Icons.Menu">M192 192m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0ZM192 512m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0ZM192 832m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0ZM864 160H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32zM864 480H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32zM864 800H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h512c17.7 0 32-14.3 32-32s-14.3-32-32-32z</StreamGeometry>
7070
<StreamGeometry x:Key="Icons.Merge">M824 645V307c0-56-46-102-102-102h-102V102l-154 154 154 154V307h102v338c-46 20-82 67-82 123 0 72 61 133 133 133 72 0 133-61 133-133 0-56-36-102-82-123zm-51 195c-41 0-72-31-72-72s31-72 72-72c41 0 72 31 72 72s-31 72-72 72zM384 256c0-72-61-133-133-133-72 0-133 61-133 133 0 56 36 102 82 123v266C154 666 118 712 118 768c0 72 61 133 133 133 72 0 133-61 133-133 0-56-36-102-82-123V379C348 358 384 312 384 256zM323 768c0 41-31 72-72 72-41 0-72-31-72-72s31-72 72-72c41 0 72 31 72 72zM251 328c-41 0-72-31-72-72s31-72 72-72c41 0 72 31 72 72s-31 72-72 72z</StreamGeometry>
71+
<StreamGeometry x:Key="Icons.Modified">M896 64H128C96 64 64 96 64 128v768c0 32 32 64 64 64h768c32 0 64-32 64-64V128c0-32-32-64-64-64z m-64 736c0 16-17 32-32 32H224c-18 0-32-12-32-32V224c0-16 16-32 32-32h576c15 0 32 16 32 32v576zM512 384c-71 0-128 57-128 128s57 128 128 128 128-57 128-128-57-128-128-128z</StreamGeometry>
7172
<StreamGeometry x:Key="Icons.Move">M299 811 299 725 384 725 384 811 299 811M469 811 469 725 555 725 555 811 469 811M640 811 640 725 725 725 725 811 640 811M299 640 299 555 384 555 384 640 299 640M469 640 469 555 555 555 555 640 469 640M640 640 640 555 725 555 725 640 640 640M299 469 299 384 384 384 384 469 299 469M469 469 469 384 555 384 555 469 469 469M640 469 640 384 725 384 725 469 640 469M299 299 299 213 384 213 384 299 299 299M469 299 469 213 555 213 555 299 469 299M640 299 640 213 725 213 725 299 640 299Z</StreamGeometry>
7273
<StreamGeometry x:Key="Icons.OpenWith">M683 409v204L1024 308 683 0v191c-413 0-427 526-427 526c117-229 203-307 427-307zm85 492H102V327h153s38-63 114-122H51c-28 0-51 27-51 61v697c0 34 23 61 51 61h768c28 0 51-27 51-61V614l-102 100v187z</StreamGeometry>
7374
<StreamGeometry x:Key="Icons.Paste">M544 85c49 0 90 37 95 85h75a96 96 0 0196 89L811 267a32 32 0 01-28 32L779 299a32 32 0 01-32-28L747 267a32 32 0 00-28-32L715 235h-91a96 96 0 01-80 42H395c-33 0-62-17-80-42L224 235a32 32 0 00-32 28L192 267v576c0 16 12 30 28 32l4 0h128a32 32 0 0132 28l0 4a32 32 0 01-32 32h-128a96 96 0 01-96-89L128 843V267a96 96 0 0189-96L224 171h75a96 96 0 0195-85h150zm256 256a96 96 0 0196 89l0 7v405a96 96 0 01-89 96L800 939h-277a96 96 0 01-96-89L427 843v-405a96 96 0 0189-96L523 341h277zm-256-192H395a32 32 0 000 64h150a32 32 0 100-64z</StreamGeometry>

src/ViewModels/Repository.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public List<Models.Tag> VisibleTags
136136
private set => SetProperty(ref _visibleTags, value);
137137
}
138138

139-
public List<string> Submodules
139+
public List<Models.Submodule> Submodules
140140
{
141141
get => _submodules;
142142
private set => SetProperty(ref _submodules, value);
@@ -778,6 +778,9 @@ public void RefreshCommits()
778778
public void RefreshSubmodules()
779779
{
780780
var submodules = new Commands.QuerySubmodules(_fullpath).Result();
781+
if (_watcher != null)
782+
_watcher.UpdateSubmodules(submodules);
783+
781784
Dispatcher.UIThread.Invoke(() => Submodules = submodules);
782785
}
783786

@@ -1992,7 +1995,7 @@ private void UpdateCurrentRevisionFilesForSearchSuggestion()
19921995
private List<Models.Worktree> _worktrees = new List<Models.Worktree>();
19931996
private List<Models.Tag> _tags = new List<Models.Tag>();
19941997
private List<Models.Tag> _visibleTags = new List<Models.Tag>();
1995-
private List<string> _submodules = new List<string>();
1998+
private List<Models.Submodule> _submodules = new List<Models.Submodule>();
19961999
private bool _includeUntracked = true;
19972000

19982001
private InProgressContext _inProgressContext = null;

src/ViewModels/UpdateSubmodules.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ public class UpdateSubmodules : Popup
77
{
88
public List<string> Submodules
99
{
10-
get => _repo.Submodules;
11-
}
10+
get;
11+
private set;
12+
} = new List<string>();
1213

1314
public string SelectedSubmodule
1415
{
@@ -43,7 +44,11 @@ public bool EnableRemote
4344
public UpdateSubmodules(Repository repo)
4445
{
4546
_repo = repo;
46-
SelectedSubmodule = repo.Submodules.Count > 0 ? repo.Submodules[0] : string.Empty;
47+
48+
foreach (var submodule in _repo.Submodules)
49+
Submodules.Add(submodule.Path);
50+
51+
SelectedSubmodule = Submodules.Count > 0 ? Submodules[0] : string.Empty;
4752
View = new Views.UpdateSubmodules() { DataContext = this };
4853
}
4954

src/Views/Repository.axaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,14 @@
349349
<DataGridTemplateColumn Width="*" Header="NAME">
350350
<DataGridTemplateColumn.CellTemplate>
351351
<DataTemplate>
352-
<Border Padding="0,0,4,0">
353-
<TextBlock Text="{Binding}" ClipToBounds="True" Classes="primary" TextTrimming="CharacterEllipsis"/>
354-
</Border>
352+
<Grid Background="Transparent" Margin="0,0,4,0" ColumnDefinitions="*,8">
353+
<TextBlock Grid.Column="0" Text="{Binding Path}" ClipToBounds="True" Classes="primary" TextTrimming="CharacterEllipsis"/>
354+
<Path Grid.Column="1"
355+
Width="8" Height="8"
356+
Fill="Goldenrod"
357+
Data="{StaticResource Icons.Modified}"
358+
IsVisible="{Binding IsDirty}"/>
359+
</Grid>
355360
</DataTemplate>
356361
</DataGridTemplateColumn.CellTemplate>
357362
</DataGridTemplateColumn>

src/Views/Repository.axaml.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@ private void OnTagFilterIsCheckedChanged(object sender, RoutedEventArgs e)
123123

124124
private void OnSubmoduleContextRequested(object sender, ContextRequestedEventArgs e)
125125
{
126-
if (sender is DataGrid { SelectedItem: string submodule } grid && DataContext is ViewModels.Repository repo)
126+
if (sender is DataGrid { SelectedItem: Models.Submodule submodule } grid && DataContext is ViewModels.Repository repo)
127127
{
128-
var menu = repo.CreateContextMenuForSubmodule(submodule);
128+
var menu = repo.CreateContextMenuForSubmodule(submodule.Path);
129129
grid.OpenContextMenu(menu);
130130
}
131131

@@ -134,9 +134,9 @@ private void OnSubmoduleContextRequested(object sender, ContextRequestedEventArg
134134

135135
private void OnDoubleTappedSubmodule(object sender, TappedEventArgs e)
136136
{
137-
if (sender is DataGrid { SelectedItem: string submodule } && DataContext is ViewModels.Repository repo)
137+
if (sender is DataGrid { SelectedItem: Models.Submodule submodule } && DataContext is ViewModels.Repository repo)
138138
{
139-
repo.OpenSubmodule(submodule);
139+
repo.OpenSubmodule(submodule.Path);
140140
}
141141

142142
e.Handled = true;

0 commit comments

Comments
 (0)