feature: show branches count in branch tree (#1306)

This commit is contained in:
leo 2025-05-13 19:28:52 +08:00
parent 57d15dc6d3
commit 7bb4e355bd
No known key found for this signature in database
5 changed files with 38 additions and 6 deletions

View file

@ -17,8 +17,10 @@ namespace SourceGit.Commands
Args = "branch -l --all -v --format=\"%(refname)%00%(committerdate:unix)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\""; Args = "branch -l --all -v --format=\"%(refname)%00%(committerdate:unix)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\"";
} }
public List<Models.Branch> Result() public List<Models.Branch> Result(out int localBranchesCount)
{ {
localBranchesCount = 0;
var branches = new List<Models.Branch>(); var branches = new List<Models.Branch>();
var rs = ReadToEnd(); var rs = ReadToEnd();
if (!rs.IsSuccess) if (!rs.IsSuccess)
@ -34,6 +36,8 @@ namespace SourceGit.Commands
branches.Add(b); branches.Add(b);
if (!b.IsLocal) if (!b.IsLocal)
remoteBranches.Add(b.FullName); remoteBranches.Add(b.FullName);
else
localBranchesCount++;
} }
} }

View file

@ -14,6 +14,7 @@ namespace SourceGit.ViewModels
public int Depth { get; set; } = 0; public int Depth { get; set; } = 0;
public bool IsSelected { get; set; } = false; public bool IsSelected { get; set; } = false;
public List<BranchTreeNode> Children { get; private set; } = new List<BranchTreeNode>(); public List<BranchTreeNode> Children { get; private set; } = new List<BranchTreeNode>();
public int Counter { get; set; } = 0;
public Models.FilterMode FilterMode public Models.FilterMode FilterMode
{ {
@ -48,6 +49,11 @@ namespace SourceGit.ViewModels
get => Backend is Models.Branch { IsUpstreamGone: true }; get => Backend is Models.Branch { IsUpstreamGone: true };
} }
public string BranchesCount
{
get => Counter > 0 ? $"({Counter})" : string.Empty;
}
public string Tooltip public string Tooltip
{ {
get => Backend is Models.Branch b ? b.FriendlyName : null; get => Backend is Models.Branch b ? b.FriendlyName : null;
@ -107,8 +113,11 @@ namespace SourceGit.ViewModels
var rk = $"refs/remotes/{branch.Remote}"; var rk = $"refs/remotes/{branch.Remote}";
if (folders.TryGetValue(rk, out var remote)) if (folders.TryGetValue(rk, out var remote))
{
remote.Counter++;
MakeBranchNode(branch, remote.Children, folders, rk, bForceExpanded); MakeBranchNode(branch, remote.Children, folders, rk, bForceExpanded);
} }
}
foreach (var path in _expanded) foreach (var path in _expanded)
{ {
@ -157,6 +166,7 @@ namespace SourceGit.ViewModels
if (folders.TryGetValue(folder, out var val)) if (folders.TryGetValue(folder, out var val))
{ {
lastFolder = val; lastFolder = val;
lastFolder.Counter++;
lastFolder.TimeToSort = Math.Max(lastFolder.TimeToSort, time); lastFolder.TimeToSort = Math.Max(lastFolder.TimeToSort, time);
if (!lastFolder.IsExpanded) if (!lastFolder.IsExpanded)
lastFolder.IsExpanded |= (branch.IsCurrent || _expanded.Contains(folder)); lastFolder.IsExpanded |= (branch.IsCurrent || _expanded.Contains(folder));
@ -169,6 +179,7 @@ namespace SourceGit.ViewModels
Path = folder, Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
TimeToSort = time, TimeToSort = time,
Counter = 1,
}; };
roots.Add(lastFolder); roots.Add(lastFolder);
folders.Add(folder, lastFolder); folders.Add(folder, lastFolder);
@ -181,6 +192,7 @@ namespace SourceGit.ViewModels
Path = folder, Path = folder,
IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder), IsExpanded = bForceExpanded || branch.IsCurrent || _expanded.Contains(folder),
TimeToSort = time, TimeToSort = time,
Counter = 1,
}; };
lastFolder.Children.Add(cur); lastFolder.Children.Add(cur);
folders.Add(folder, cur); folders.Add(folder, cur);

View file

@ -228,6 +228,12 @@ namespace SourceGit.ViewModels
private set => SetProperty(ref _stashesCount, value); private set => SetProperty(ref _stashesCount, value);
} }
public int LocalBranchesCount
{
get => _localBranchesCount;
private set => SetProperty(ref _localBranchesCount, value);
}
public bool IncludeUntracked public bool IncludeUntracked
{ {
get => _settings.IncludeUntrackedInLocalChanges; get => _settings.IncludeUntrackedInLocalChanges;
@ -1020,7 +1026,7 @@ namespace SourceGit.ViewModels
public void RefreshBranches() public void RefreshBranches()
{ {
var branches = new Commands.QueryBranches(_fullpath).Result(); var branches = new Commands.QueryBranches(_fullpath).Result(out var localBranchesCount);
var remotes = new Commands.QueryRemotes(_fullpath).Result(); var remotes = new Commands.QueryRemotes(_fullpath).Result();
var builder = BuildBranchTree(branches, remotes); var builder = BuildBranchTree(branches, remotes);
@ -1033,6 +1039,7 @@ namespace SourceGit.ViewModels
CurrentBranch = branches.Find(x => x.IsCurrent); CurrentBranch = branches.Find(x => x.IsCurrent);
LocalBranchTrees = builder.Locals; LocalBranchTrees = builder.Locals;
RemoteBranchTrees = builder.Remotes; RemoteBranchTrees = builder.Remotes;
LocalBranchesCount = localBranchesCount;
if (_workingCopy != null) if (_workingCopy != null)
_workingCopy.HasRemotes = remotes.Count > 0; _workingCopy.HasRemotes = remotes.Count > 0;
@ -2726,6 +2733,7 @@ namespace SourceGit.ViewModels
private int _selectedViewIndex = 0; private int _selectedViewIndex = 0;
private object _selectedView = null; private object _selectedView = null;
private int _localBranchesCount = 0;
private int _localChangesCount = 0; private int _localChangesCount = 0;
private int _stashesCount = 0; private int _stashesCount = 0;

View file

@ -60,9 +60,11 @@
<!-- Name --> <!-- Name -->
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
Classes="primary" Classes="primary"
Text="{Binding Name}"
FontWeight="{Binding IsCurrent, Converter={x:Static c:BoolConverters.IsBoldToFontWeight}}" FontWeight="{Binding IsCurrent, Converter={x:Static c:BoolConverters.IsBoldToFontWeight}}"
TextTrimming="CharacterEllipsis"/> TextTrimming="CharacterEllipsis">
<Run Text="{Binding Name}"/>
<Run Text="{Binding BranchesCount}" Foreground="{DynamicResource Brush.FG2}"/>
</TextBlock>
<!-- Upstream invalid tip --> <!-- Upstream invalid tip -->
<Border Grid.Column="2" <Border Grid.Column="2"

View file

@ -204,7 +204,10 @@
<ToggleButton Grid.Row="0" Classes="group_expander" IsChecked="{Binding IsLocalBranchGroupExpanded, Mode=TwoWay}"> <ToggleButton Grid.Row="0" Classes="group_expander" IsChecked="{Binding IsLocalBranchGroupExpanded, Mode=TwoWay}">
<Grid ColumnDefinitions="16,*,Auto,Auto"> <Grid ColumnDefinitions="16,*,Auto,Auto">
<Path Grid.Column="0" Width="11" Height="11" HorizontalAlignment="Left" Data="{StaticResource Icons.Local}" Fill="{DynamicResource Brush.FG2}"/> <Path Grid.Column="0" Width="11" Height="11" HorizontalAlignment="Left" Data="{StaticResource Icons.Local}" Fill="{DynamicResource Brush.FG2}"/>
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.LocalBranches}"/> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0">
<Run Text="{DynamicResource Text.Repository.LocalBranches}"/>
<Run Text="{Binding LocalBranchesCount, StringFormat='({0})'}"/>
</TextBlock>
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="icon_button" Classes="icon_button"
Width="14" Width="14"
@ -231,7 +234,10 @@
<ToggleButton Grid.Row="2" Classes="group_expander" IsChecked="{Binding IsRemoteGroupExpanded, Mode=TwoWay}"> <ToggleButton Grid.Row="2" Classes="group_expander" IsChecked="{Binding IsRemoteGroupExpanded, Mode=TwoWay}">
<Grid ColumnDefinitions="16,*,Auto,Auto"> <Grid ColumnDefinitions="16,*,Auto,Auto">
<Path Grid.Column="0" Width="12" Height="12" HorizontalAlignment="Left" Data="{StaticResource Icons.Remotes}" Fill="{DynamicResource Brush.FG2}"/> <Path Grid.Column="0" Width="12" Height="12" HorizontalAlignment="Left" Data="{StaticResource Icons.Remotes}" Fill="{DynamicResource Brush.FG2}"/>
<TextBlock Grid.Column="1" Classes="group_header_label" Margin="0" Text="{DynamicResource Text.Repository.Remotes}"/> <TextBlock Grid.Column="1" Classes="group_header_label" Margin="0">
<Run Text="{DynamicResource Text.Repository.Remotes}"/>
<Run Text="{Binding Remotes, Converter={x:Static c:ListConverters.ToCount}}"/>
</TextBlock>
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="icon_button" Classes="icon_button"
Width="14" Width="14"