Skip to content

Commit eb437df

Browse files
committed
enhance: reduce commits loading time for interactive rebase
1 parent 7891b11 commit eb437df

File tree

3 files changed

+101
-13
lines changed

3 files changed

+101
-13
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace SourceGit.Commands
5+
{
6+
public class QueryCommitsWithFullMessage : Command
7+
{
8+
public QueryCommitsWithFullMessage(string repo, string args)
9+
{
10+
_boundary = $"----- BOUNDARY OF COMMIT {Guid.NewGuid()} -----";
11+
12+
WorkingDirectory = repo;
13+
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{_boundary}\" {args}";
15+
}
16+
17+
public List<Models.CommitWithMessage> Result()
18+
{
19+
var rs = ReadToEnd();
20+
if (!rs.IsSuccess)
21+
return _commits;
22+
23+
var nextPartIdx = 0;
24+
var start = 0;
25+
var end = rs.StdOut.IndexOf('\n', start);
26+
while (end > 0)
27+
{
28+
var line = rs.StdOut.Substring(start, end - start);
29+
switch (nextPartIdx)
30+
{
31+
case 0:
32+
_current = new Models.CommitWithMessage();
33+
_current.Commit.SHA = line;
34+
_commits.Add(_current);
35+
break;
36+
case 1:
37+
ParseParent(line);
38+
break;
39+
case 2:
40+
_current.Commit.ParseDecorators(line);
41+
break;
42+
case 3:
43+
_current.Commit.Author = Models.User.FindOrAdd(line);
44+
break;
45+
case 4:
46+
_current.Commit.AuthorTime = ulong.Parse(line);
47+
break;
48+
case 5:
49+
_current.Commit.Committer = Models.User.FindOrAdd(line);
50+
break;
51+
case 6:
52+
_current.Commit.CommitterTime = ulong.Parse(line);
53+
break;
54+
default:
55+
if (line.Equals(_boundary, StringComparison.Ordinal))
56+
nextPartIdx = -1;
57+
else
58+
_current.Message += line;
59+
break;
60+
}
61+
62+
nextPartIdx++;
63+
64+
start = end + 1;
65+
end = rs.StdOut.IndexOf('\n', start);
66+
}
67+
68+
return _commits;
69+
}
70+
71+
private void ParseParent(string data)
72+
{
73+
if (data.Length < 8)
74+
return;
75+
76+
var idx = data.IndexOf(' ', StringComparison.Ordinal);
77+
if (idx == -1)
78+
{
79+
_current.Commit.Parents.Add(data);
80+
return;
81+
}
82+
83+
_current.Commit.Parents.Add(data.Substring(0, idx));
84+
_current.Commit.Parents.Add(data.Substring(idx + 1));
85+
}
86+
87+
private List<Models.CommitWithMessage> _commits = new List<Models.CommitWithMessage>();
88+
private Models.CommitWithMessage _current = null;
89+
private string _boundary = "";
90+
}
91+
}

src/Models/Commit.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,10 @@ public void ParseDecorators(string data)
104104
});
105105
}
106106
}
107+
108+
public class CommitWithMessage
109+
{
110+
public Commit Commit { get; set; } = new Commit();
111+
public string Message { get; set; } = "";
112+
}
107113
}

src/ViewModels/InteractiveRebase.cs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ public string FullMessage
5151
public InteractiveRebaseItem(Models.Commit c, string message)
5252
{
5353
Commit = c;
54-
55-
_subject = c.Subject;
56-
_fullMessage = message;
54+
FullMessage = message;
5755
}
5856

5957
public void SetAction(object param)
@@ -120,21 +118,14 @@ public InteractiveRebase(Repository repo, Models.Branch current, Models.Commit o
120118

121119
Task.Run(() =>
122120
{
123-
var commits = new Commands.QueryCommits(repoPath, $"{on.SHA}...HEAD", false).Result();
124-
var messages = new Dictionary<string, string>();
121+
var commits = new Commands.QueryCommitsWithFullMessage(repoPath, $"{on.SHA}...HEAD").Result();
122+
var list = new List<InteractiveRebaseItem>();
125123

126124
foreach (var c in commits)
127-
{
128-
var fullMessage = new Commands.QueryCommitFullMessage(repoPath, c.SHA).Result();
129-
messages.Add(c.SHA, fullMessage);
130-
}
125+
list.Add(new InteractiveRebaseItem(c.Commit, c.Message));
131126

132127
Dispatcher.UIThread.Invoke(() =>
133128
{
134-
var list = new List<InteractiveRebaseItem>();
135-
foreach (var c in commits)
136-
list.Add(new InteractiveRebaseItem(c, messages[c.SHA]));
137-
138129
Items.AddRange(list);
139130
IsLoading = false;
140131
});

0 commit comments

Comments
 (0)