Skip to content

Commit 3056287

Browse files
committed
feature: add a check icon for commits contained in current branch in search results (#1773)
Signed-off-by: leo <[email protected]>
1 parent be915a2 commit 3056287

File tree

5 files changed

+116
-37
lines changed

5 files changed

+116
-37
lines changed

src/Commands/IsAncestor.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using System.Threading.Tasks;
2+
3+
namespace SourceGit.Commands
4+
{
5+
public class IsAncestor : Command
6+
{
7+
public IsAncestor(string repo, string checkPoint, string endPoint)
8+
{
9+
WorkingDirectory = repo;
10+
Context = repo;
11+
Args = $"merge-base --is-ancestor {checkPoint} {endPoint}";
12+
}
13+
14+
public async Task<bool> GetResultAsync()
15+
{
16+
var rs = await ReadToEndAsync().ConfigureAwait(false);
17+
return rs.IsSuccess;
18+
}
19+
}
20+
}

src/Commands/QueryCommits.cs

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,40 +18,39 @@ public QueryCommits(string repo, string limits, bool needFindHead = true)
1818

1919
public QueryCommits(string repo, string filter, Models.CommitSearchMethod method, bool onlyCurrentBranch)
2020
{
21-
string search = onlyCurrentBranch ? string.Empty : "--branches --remotes ";
21+
var builder = new StringBuilder();
22+
builder.Append("log -1000 --date-order --no-show-signature --decorate=full --format=%H%x00%P%x00%D%x00%aN±%aE%x00%at%x00%cN±%cE%x00%ct%x00%s ");
23+
24+
if (!onlyCurrentBranch)
25+
builder.Append("--branches --remotes ");
2226

2327
if (method == Models.CommitSearchMethod.ByAuthor)
2428
{
25-
search += $"-i --author={filter.Quoted()}";
29+
builder.Append("-i --author=").Append(filter.Quoted());
2630
}
2731
else if (method == Models.CommitSearchMethod.ByCommitter)
2832
{
29-
search += $"-i --committer={filter.Quoted()}";
33+
builder.Append("-i --committer=").Append(filter.Quoted());
3034
}
3135
else if (method == Models.CommitSearchMethod.ByMessage)
3236
{
33-
var argsBuilder = new StringBuilder();
34-
argsBuilder.Append(search);
35-
3637
var words = filter.Split([' ', '\t', '\r'], StringSplitOptions.RemoveEmptyEntries);
3738
foreach (var word in words)
38-
argsBuilder.Append("--grep=").Append(word.Trim().Quoted()).Append(' ');
39-
argsBuilder.Append("--all-match -i");
40-
41-
search = argsBuilder.ToString();
39+
builder.Append("--grep=").Append(word.Trim().Quoted()).Append(' ');
40+
builder.Append("--all-match -i");
4241
}
4342
else if (method == Models.CommitSearchMethod.ByPath)
4443
{
45-
search += $"-- {filter.Quoted()}";
44+
builder.Append("-- ").Append(filter.Quoted());
4645
}
4746
else
4847
{
49-
search = $"-G{filter.Quoted()}";
48+
builder.Append("-G").Append(filter.Quoted());
5049
}
5150

5251
WorkingDirectory = repo;
5352
Context = repo;
54-
Args = $"log -1000 --date-order --no-show-signature --decorate=full --format=%H%x00%P%x00%D%x00%aN±%aE%x00%at%x00%cN±%cE%x00%ct%x00%s {search}";
53+
Args = builder.ToString();
5554
_findFirstMerged = false;
5655
}
5756

@@ -87,7 +86,20 @@ public QueryCommits(string repo, string filter, Models.CommitSearchMethod method
8786
await proc.WaitForExitAsync().ConfigureAwait(false);
8887

8988
if (_findFirstMerged && !_isHeadFound && commits.Count > 0)
90-
await MarkFirstMergedAsync(commits).ConfigureAwait(false);
89+
{
90+
var set = await new QueryCurrentBranchCommitHashes(WorkingDirectory, commits[^1].CommitterTime)
91+
.GetResultAsync()
92+
.ConfigureAwait(false);
93+
94+
foreach (var c in commits)
95+
{
96+
if (set.Contains(c.SHA))
97+
{
98+
c.IsMerged = true;
99+
break;
100+
}
101+
}
102+
}
91103
}
92104
catch (Exception e)
93105
{
@@ -97,27 +109,6 @@ public QueryCommits(string repo, string filter, Models.CommitSearchMethod method
97109
return commits;
98110
}
99111

100-
private async Task MarkFirstMergedAsync(List<Models.Commit> commits)
101-
{
102-
Args = $"log --since={commits[^1].CommitterTimeStr.Quoted()} --format=\"%H\"";
103-
104-
var rs = await ReadToEndAsync().ConfigureAwait(false);
105-
var shas = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
106-
if (shas.Length == 0)
107-
return;
108-
109-
var set = new HashSet<string>(shas);
110-
111-
foreach (var c in commits)
112-
{
113-
if (set.Contains(c.SHA))
114-
{
115-
c.IsMerged = true;
116-
break;
117-
}
118-
}
119-
}
120-
121112
private bool _findFirstMerged = false;
122113
private bool _isHeadFound = false;
123114
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Threading.Tasks;
5+
6+
namespace SourceGit.Commands
7+
{
8+
public class QueryCurrentBranchCommitHashes : Command
9+
{
10+
public QueryCurrentBranchCommitHashes(string repo, ulong sinceTimestamp)
11+
{
12+
var since = DateTime.UnixEpoch.AddSeconds(sinceTimestamp).ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss");
13+
WorkingDirectory = repo;
14+
Context = repo;
15+
Args = $"log --since={since.Quoted()} --format=%H";
16+
}
17+
18+
public async Task<HashSet<string>> GetResultAsync()
19+
{
20+
var outs = new HashSet<string>();
21+
22+
try
23+
{
24+
using var proc = new Process();
25+
proc.StartInfo = CreateGitStartInfo(true);
26+
proc.Start();
27+
28+
while (await proc.StandardOutput.ReadLineAsync() is { Length: > 8 } line)
29+
outs.Add(line);
30+
31+
await proc.WaitForExitAsync().ConfigureAwait(false);
32+
}
33+
catch
34+
{
35+
// Ignore exceptions;
36+
}
37+
38+
return outs;
39+
}
40+
}
41+
}

src/ViewModels/Repository.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,14 +905,38 @@ public void StartSearchCommits()
905905
var commit = await new Commands.QuerySingleCommit(FullPath, _searchCommitFilter)
906906
.GetResultAsync()
907907
.ConfigureAwait(false);
908+
909+
commit.IsMerged = await new Commands.IsAncestor(FullPath, commit.SHA, "HEAD")
910+
.GetResultAsync()
911+
.ConfigureAwait(false);
912+
908913
visible.Add(commit);
909914
}
910915
}
916+
else if (_onlySearchCommitsInCurrentBranch)
917+
{
918+
visible = await new Commands.QueryCommits(FullPath, _searchCommitFilter, method, true)
919+
.GetResultAsync()
920+
.ConfigureAwait(false);
921+
922+
foreach (var c in visible)
923+
c.IsMerged = true;
924+
}
911925
else
912926
{
913-
visible = await new Commands.QueryCommits(FullPath, _searchCommitFilter, method, _onlySearchCommitsInCurrentBranch)
927+
visible = await new Commands.QueryCommits(FullPath, _searchCommitFilter, method, false)
914928
.GetResultAsync()
915929
.ConfigureAwait(false);
930+
931+
if (visible.Count > 0)
932+
{
933+
var set = await new Commands.QueryCurrentBranchCommitHashes(FullPath, visible[^1].CommitterTime)
934+
.GetResultAsync()
935+
.ConfigureAwait(false);
936+
937+
foreach (var c in visible)
938+
c.IsMerged = set.Contains(c.SHA);
939+
}
916940
}
917941

918942
Dispatcher.UIThread.Post(() =>

src/Views/Repository.axaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,10 @@
581581
<ColumnDefinition Width="Auto" SharedSizeGroup="SearchCommitTimeColumn"/>
582582
</Grid.ColumnDefinitions>
583583
<v:Avatar Grid.Column="0" Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False" User="{Binding Author}"/>
584-
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Subject}" Margin="2,0,0,0" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"/>
584+
<Grid Grid.Column="1" ColumnDefinitions="Auto,*">
585+
<Path Grid.Column="0" Width="14" Height="14" Margin="0,2,2,0" Data="{StaticResource Icons.Check}" Fill="Green" IsVisible="{Binding IsMerged, Mode=OneWay}"/>
586+
<TextBlock Grid.Column="1" Classes="primary" Text="{Binding Subject}" Margin="2,0,0,0" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"/>
587+
</Grid>
585588
<TextBlock Grid.Column="2"
586589
Classes="primary"
587590
Margin="4,0"

0 commit comments

Comments
 (0)