Skip to content

Commit 9e45a8a

Browse files
committed
enhance: only store subject in commits.
It has several advantages: * reduce the memory costed by histories * higher performance while parsing commits * no need to calculate subject every time, which is invoked most frequently to render histories
1 parent 6426da3 commit 9e45a8a

12 files changed

+67
-65
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace SourceGit.Commands
2+
{
3+
public class QueryCommitFullMessage : Command
4+
{
5+
public QueryCommitFullMessage(string repo, string sha)
6+
{
7+
WorkingDirectory = repo;
8+
Context = repo;
9+
Args = $"show --no-show-signature --pretty=format:%B -s {sha}";
10+
}
11+
12+
public string Result()
13+
{
14+
var rs = ReadToEnd();
15+
if (rs.IsSuccess) return rs.StdOut.TrimEnd();
16+
return string.Empty;
17+
}
18+
}
19+
}

src/Commands/QueryCommits.cs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ public class QueryCommits : Command
77
{
88
public QueryCommits(string repo, string limits, bool needFindHead = true)
99
{
10-
_endOfBodyToken = $"----- END OF BODY {Guid.NewGuid()} -----";
11-
1210
WorkingDirectory = repo;
1311
Context = repo;
14-
Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_endOfBodyToken}\" " + limits;
12+
Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s " + limits;
1513
_findFirstMerged = needFindHead;
1614
}
1715

@@ -24,7 +22,6 @@ public QueryCommits(string repo, string limits, bool needFindHead = true)
2422
var nextPartIdx = 0;
2523
var start = 0;
2624
var end = rs.StdOut.IndexOf('\n', start);
27-
var max = rs.StdOut.Length;
2825
while (end > 0)
2926
{
3027
var line = rs.StdOut.Substring(start, end - start);
@@ -51,24 +48,17 @@ public QueryCommits(string repo, string limits, bool needFindHead = true)
5148
break;
5249
case 6:
5350
_current.CommitterTime = ulong.Parse(line);
54-
start = end + 1;
55-
end = rs.StdOut.IndexOf(_endOfBodyToken, start, StringComparison.Ordinal);
56-
if (end > 0)
57-
{
58-
if (end > start)
59-
_current.Body = rs.StdOut.Substring(start, end - start).TrimEnd();
60-
61-
start = end + _endOfBodyToken.Length + 1;
62-
end = start >= max ? -1 : rs.StdOut.IndexOf('\n', start);
63-
}
64-
65-
nextPartIdx = 0;
66-
continue;
51+
break;
52+
case 7:
53+
_current.Subject = line;
54+
break;
6755
default:
6856
break;
6957
}
7058

7159
nextPartIdx++;
60+
if (nextPartIdx == 8) nextPartIdx = 0;
61+
7262
start = end + 1;
7363
end = rs.StdOut.IndexOf('\n', start);
7464
}
@@ -157,7 +147,7 @@ private void ParseDecorators(string data)
157147
if (l.Type != r.Type)
158148
return (int)l.Type - (int)r.Type;
159149
else
160-
return l.Name.CompareTo(r.Name);
150+
return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
161151
});
162152

163153
if (_current.IsMerged && !_isHeadFounded)
@@ -187,7 +177,6 @@ private void MarkFirstMerged()
187177
}
188178
}
189179

190-
private string _endOfBodyToken = string.Empty;
191180
private List<Models.Commit> _commits = new List<Models.Commit>();
192181
private Models.Commit _current = null;
193182
private bool _findFirstMerged = false;

src/Commands/QuerySingleCommit.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public QuerySingleCommit(string repo, string sha)
1010
{
1111
WorkingDirectory = repo;
1212
Context = repo;
13-
Args = $"show --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B -s {sha}";
13+
Args = $"show --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s -s {sha}";
1414
}
1515

1616
public Models.Commit Result()
@@ -32,11 +32,7 @@ public Models.Commit Result()
3232
commit.AuthorTime = ulong.Parse(lines[4]);
3333
commit.Committer = Models.User.FindOrAdd(lines[5]);
3434
commit.CommitterTime = ulong.Parse(lines[6]);
35-
36-
StringBuilder builder = new StringBuilder();
37-
for (int i = 7; i < lines.Length; i++)
38-
builder.AppendLine(lines[i]);
39-
commit.Body = builder.ToString().TrimEnd();
35+
commit.Subject = lines[7];
4036

4137
return commit;
4238
}
@@ -105,7 +101,7 @@ private bool ParseDecorators(List<Models.Decorator> decorators, string data)
105101
if (l.Type != r.Type)
106102
return (int)l.Type - (int)r.Type;
107103
else
108-
return l.Name.CompareTo(r.Name);
104+
return string.Compare(l.Name, r.Name, StringComparison.Ordinal);
109105
});
110106

111107
return isHeadOfCurrent;

src/Models/Commit.cs

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,13 @@ public class Commit
1212
public ulong AuthorTime { get; set; } = 0;
1313
public User Committer { get; set; } = User.Invalid;
1414
public ulong CommitterTime { get; set; } = 0;
15-
public string Body { get; set; } = string.Empty;
15+
public string Subject { get; set; } = string.Empty;
1616
public List<string> Parents { get; set; } = new List<string>();
1717
public List<Decorator> Decorators { get; set; } = new List<Decorator>();
1818
public bool HasDecorators => Decorators.Count > 0;
1919
public bool IsMerged { get; set; } = false;
2020
public Thickness Margin { get; set; } = new Thickness(0);
2121

22-
public string Subject
23-
{
24-
get
25-
{
26-
var end = Body.IndexOf("\r\n\r\n", StringComparison.Ordinal);
27-
if (end == -1)
28-
{
29-
end = Body.IndexOf("\n\n", StringComparison.Ordinal);
30-
if (end > 0)
31-
return Body.Substring(0, end).Replace("\n", "", StringComparison.Ordinal);
32-
33-
return Body.Replace("\n", " ", StringComparison.Ordinal);
34-
}
35-
36-
return Body.Substring(0, end).Replace("\r\n", " ", StringComparison.Ordinal);
37-
}
38-
}
39-
4022
public string AuthorTimeStr => _utcStart.AddSeconds(AuthorTime).ToString("yyyy/MM/dd HH:mm:ss");
4123
public string CommitterTimeStr => _utcStart.AddSeconds(CommitterTime).ToString("yyyy/MM/dd HH:mm:ss");
4224
public string AuthorTimeShortStr => _utcStart.AddSeconds(AuthorTime).ToString("yyyy/MM/dd");

src/ViewModels/CommitDetail.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ public Models.Commit Commit
3636
}
3737
}
3838

39+
public string FullMessage
40+
{
41+
get => _fullMessage;
42+
private set => SetProperty(ref _fullMessage, value);
43+
}
44+
3945
public List<Models.Change> Changes
4046
{
4147
get => _changes;
@@ -376,6 +382,7 @@ public ContextMenu CreateRevisionFileContextMenu(Models.Object file)
376382
private void Refresh()
377383
{
378384
_changes = null;
385+
FullMessage = string.Empty;
379386
VisibleChanges = null;
380387
SelectedChanges = null;
381388

@@ -389,6 +396,7 @@ private void Refresh()
389396

390397
Task.Run(() =>
391398
{
399+
var fullMessage = new Commands.QueryCommitFullMessage(_repo, _commit.SHA).Result();
392400
var parent = _commit.Parents.Count == 0 ? "4b825dc642cb6eb9a060e54bf8d69288fbee4904" : _commit.Parents[0];
393401
var cmdChanges = new Commands.CompareRevisions(_repo, parent, _commit.SHA) { Cancel = _cancelToken };
394402
var changes = cmdChanges.Result();
@@ -407,6 +415,7 @@ private void Refresh()
407415
{
408416
Dispatcher.UIThread.Post(() =>
409417
{
418+
FullMessage = fullMessage;
410419
Changes = changes;
411420
VisibleChanges = visible;
412421
});
@@ -444,6 +453,7 @@ private void RefreshVisibleChanges()
444453
private string _repo = string.Empty;
445454
private int _activePageIndex = 0;
446455
private Models.Commit _commit = null;
456+
private string _fullMessage = string.Empty;
447457
private List<Models.Change> _changes = null;
448458
private List<Models.Change> _visibleChanges = null;
449459
private List<Models.Change> _selectedChanges = null;

src/ViewModels/Repository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ public void StartSearchCommits()
429429
foreach (var c in _histories.Commits)
430430
{
431431
if (c.SHA.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
432-
|| c.Body.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
432+
|| c.Subject.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
433433
|| c.Author.Name.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
434434
|| c.Committer.Name.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)
435435
|| c.Author.Email.Contains(_searchCommitFilter, StringComparison.OrdinalIgnoreCase)

src/ViewModels/Reword.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.ComponentModel.DataAnnotations;
1+
using System;
2+
using System.ComponentModel.DataAnnotations;
23
using System.Threading.Tasks;
34

45
namespace SourceGit.ViewModels
@@ -21,14 +22,16 @@ public string Message
2122
public Reword(Repository repo, Models.Commit head)
2223
{
2324
_repo = repo;
25+
_oldMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, head.SHA).Result();
26+
_message = _oldMessage;
27+
2428
Head = head;
25-
Message = head.Body;
2629
View = new Views.Reword() { DataContext = this };
2730
}
2831

2932
public override Task<bool> Sure()
3033
{
31-
if (_message == Head.Body)
34+
if (string.Compare(_message, _oldMessage, StringComparison.Ordinal) == 0)
3235
return null;
3336

3437
_repo.SetWatcherEnabled(false);
@@ -44,5 +47,6 @@ public override Task<bool> Sure()
4447

4548
private readonly Repository _repo = null;
4649
private string _message = string.Empty;
50+
private string _oldMessage = string.Empty;
4751
}
4852
}

src/ViewModels/Squash.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public string Message
2727
public Squash(Repository repo, Models.Commit head, Models.Commit parent)
2828
{
2929
_repo = repo;
30-
_message = parent.Body;
30+
_message = new Commands.QueryCommitFullMessage(_repo.FullPath, parent.SHA).Result();
31+
3132
Head = head;
3233
Parent = parent;
3334
View = new Views.Squash() { DataContext = this };

src/ViewModels/WorkingCopy.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,7 @@ public bool UseAmend
9393
return;
9494
}
9595

96-
var head = new Commands.QuerySingleCommit(_repo.FullPath, currentBranch.Head).Result();
97-
if (head == null)
98-
{
99-
App.RaiseException(_repo.FullPath, "No commits to amend!!!");
100-
_useAmend = false;
101-
OnPropertyChanged();
102-
return;
103-
}
104-
105-
CommitMessage = head.Body;
96+
CommitMessage = new Commands.QueryCommitFullMessage(_repo.FullPath, currentBranch.Head).Result();
10697
}
10798

10899
OnPropertyChanged(nameof(IsCommitWithPushVisible));

src/Views/CommitBaseInfo.axaml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
xmlns:v="using:SourceGit.Views"
88
xmlns:c="using:SourceGit.Converters"
99
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
10-
x:Class="SourceGit.Views.CommitBaseInfo">
10+
x:Class="SourceGit.Views.CommitBaseInfo"
11+
x:Name="ThisControl">
1112
<UserControl.DataTemplates>
1213
<DataTemplate DataType="m:Commit">
1314
<StackPanel Orientation="Vertical">
1415
<!-- Author & Committer -->
1516
<UniformGrid Rows="1" Margin="0,8">
1617
<!-- Author -->
17-
<Grid Grid.Column="0" ColumnDefinitions="96,*">
18+
<Grid ColumnDefinitions="96,*">
1819
<v:Avatar Grid.Column="0" Width="64" Height="64" HorizontalAlignment="Right" User="{Binding Author}"/>
1920
<StackPanel Grid.Column="1" Margin="16,0,8,0" Orientation="Vertical">
2021
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.CommitDetail.Info.Author}"/>
@@ -30,7 +31,7 @@
3031
</Grid>
3132

3233
<!-- Committer -->
33-
<Grid Grid.Column="1" ColumnDefinitions="96,*" IsVisible="{Binding IsCommitterVisible}">
34+
<Grid ColumnDefinitions="96,*" IsVisible="{Binding IsCommitterVisible}">
3435
<v:Avatar Grid.Column="0" Width="64" Height="64" HorizontalAlignment="Right" User="{Binding Committer}"/>
3536
<StackPanel Grid.Column="1" Margin="16,0,8,0" Orientation="Vertical">
3637
<TextBlock Classes="group_header_label" Margin="0" Text="{DynamicResource Text.CommitDetail.Info.Committer}"/>
@@ -104,7 +105,7 @@
104105
<!-- Messages -->
105106
<TextBlock Grid.Row="3" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Message}" VerticalAlignment="Top" Margin="0,4,0,0" />
106107
<ScrollViewer Grid.Row="3" Grid.Column="1" Margin="12,5,8,0" MaxHeight="64" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
107-
<SelectableTextBlock Text="{Binding Body}" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}" TextWrapping="Wrap"/>
108+
<SelectableTextBlock Text="{Binding #ThisControl.Message}" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}" TextWrapping="Wrap"/>
108109
</ScrollViewer>
109110
</Grid>
110111
</StackPanel>

0 commit comments

Comments
 (0)