Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3ec6ef9

Browse files
enhance: do not create temp string for large output of some git command
Signed-off-by: leo <longshuang@msn.cn>
1 parent 632e394 commit 3ec6ef9

File tree

5 files changed

+216
-223
lines changed

5 files changed

+216
-223
lines changed

‎src/Commands/Diff.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
3+
using System.Diagnostics;
44
using System.Text.RegularExpressions;
55
using System.Threading.Tasks;
66

@@ -35,10 +35,21 @@ public Diff(string repo, Models.DiffOption opt, int unified, bool ignoreWhitespa
3535

3636
public async Task<Models.DiffResult> ReadAsync()
3737
{
38-
var rs = await ReadToEndAsync().ConfigureAwait(false);
39-
var sr = new StringReader(rs.StdOut);
40-
while (sr.ReadLine() is { } line)
41-
ParseLine(line);
38+
try
39+
{
40+
using var proc = new Process();
41+
proc.StartInfo = CreateGitStartInfo(true);
42+
proc.Start();
43+
44+
while (await proc.StandardOutput.ReadLineAsync() is { } line)
45+
ParseLine(line);
46+
47+
await proc.WaitForExitAsync().ConfigureAwait(false);
48+
}
49+
catch
50+
{
51+
// Ignore exceptions.
52+
}
4253

4354
if (_result.IsBinary || _result.IsLFS || _result.TextDiff.Lines.Count == 0)
4455
{

‎src/Commands/QueryCommits.cs

Lines changed: 37 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.Text;
45
using System.Threading.Tasks;
56

@@ -11,7 +12,7 @@ public QueryCommits(string repo, string limits, bool needFindHead = true)
1112
{
1213
WorkingDirectory = repo;
1314
Context = repo;
14-
Args = $"log --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s {limits}";
15+
Args = $"log --no-show-signature --decorate=full --format=%H%x00%P%x00%D%x00%aN±%aE%x00%at%x00%cN±%cE%x00%ct%x00%s {limits}";
1516
_findFirstMerged = needFindHead;
1617
}
1718

@@ -50,80 +51,55 @@ public QueryCommits(string repo, string filter, Models.CommitSearchMethod method
5051

5152
WorkingDirectory = repo;
5253
Context = repo;
53-
Args = $"log -1000 --date-order --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s {search}";
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}";
5455
_findFirstMerged = false;
5556
}
5657

5758
public async Task<List<Models.Commit>> GetResultAsync()
5859
{
59-
var rs = await ReadToEndAsync().ConfigureAwait(false);
60-
if (!rs.IsSuccess)
61-
return _commits;
62-
63-
var nextPartIdx = 0;
64-
var start = 0;
65-
var end = rs.StdOut.IndexOf('\n', start);
66-
while (end > 0)
60+
var commits = new List<Models.Commit>();
61+
try
6762
{
68-
var line = rs.StdOut.Substring(start, end - start);
69-
switch (nextPartIdx)
63+
using var proc = new Process();
64+
proc.StartInfo = CreateGitStartInfo(true);
65+
proc.Start();
66+
67+
while (await proc.StandardOutput.ReadLineAsync() is { } line)
7068
{
71-
case 0:
72-
_current = new Models.Commit() { SHA = line };
73-
_commits.Add(_current);
74-
break;
75-
case 1:
76-
ParseParent(line);
77-
break;
78-
case 2:
79-
_current.ParseDecorators(line);
80-
if (_current.IsMerged && !_isHeadFound)
81-
_isHeadFound = true;
82-
break;
83-
case 3:
84-
_current.Author = Models.User.FindOrAdd(line);
85-
break;
86-
case 4:
87-
_current.AuthorTime = ulong.Parse(line);
88-
break;
89-
case 5:
90-
_current.Committer = Models.User.FindOrAdd(line);
91-
break;
92-
case 6:
93-
_current.CommitterTime = ulong.Parse(line);
94-
break;
95-
case 7:
96-
_current.Subject = line;
97-
nextPartIdx = -1;
98-
break;
69+
var parts = line.Split('0円');
70+
if (parts.Length != 8)
71+
continue;
72+
73+
var commit = new Models.Commit() { SHA = parts[0] };
74+
commit.ParseParents(parts[1]);
75+
commit.ParseDecorators(parts[2]);
76+
commit.Author = Models.User.FindOrAdd(parts[3]);
77+
commit.AuthorTime = ulong.Parse(parts[4]);
78+
commit.Committer = Models.User.FindOrAdd(parts[5]);
79+
commit.CommitterTime = ulong.Parse(parts[6]);
80+
commit.Subject = parts[7];
81+
commits.Add(commit);
82+
83+
if (commit.IsMerged && !_isHeadFound)
84+
_isHeadFound = true;
9985
}
10086

101-
nextPartIdx++;
87+
awaitproc.WaitForExitAsync().ConfigureAwait(false);
10288

103-
start = end + 1;
104-
end = rs.StdOut.IndexOf('\n', start);
89+
if (_findFirstMerged && !_isHeadFound && commits.Count > 0)
90+
await MarkFirstMergedAsync(commits).ConfigureAwait(false);
91+
}
92+
catch (Exception e)
93+
{
94+
App.RaiseException(Context, $"Failed to query commits. Reason: {e.Message}");
10595
}
10696

107-
if (start < rs.StdOut.Length)
108-
_current.Subject = rs.StdOut.Substring(start);
109-
110-
if (_findFirstMerged && !_isHeadFound && _commits.Count > 0)
111-
await MarkFirstMergedAsync().ConfigureAwait(false);
112-
113-
return _commits;
114-
}
115-
116-
private void ParseParent(string data)
117-
{
118-
if (data.Length < 8)
119-
return;
120-
121-
_current.Parents.AddRange(data.Split(' ', StringSplitOptions.RemoveEmptyEntries));
97+
return commits;
12298
}
12399

124-
private async Task MarkFirstMergedAsync()
100+
private async Task MarkFirstMergedAsync(List<Models.Commit>commits)
125101
{
126-
Args = $"log --since={_commits[^1].CommitterTimeStr.Quoted()} --format=\"%H\"";
102+
Args = $"log --since={commits[^1].CommitterTimeStr.Quoted()} --format=\"%H\"";
127103

128104
var rs = await ReadToEndAsync().ConfigureAwait(false);
129105
var shas = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
@@ -132,7 +108,7 @@ private async Task MarkFirstMergedAsync()
132108

133109
var set = new HashSet<string>(shas);
134110

135-
foreach (var c in _commits)
111+
foreach (var c in commits)
136112
{
137113
if (set.Contains(c.SHA))
138114
{
@@ -142,8 +118,6 @@ private async Task MarkFirstMergedAsync()
142118
}
143119
}
144120

145-
private List<Models.Commit> _commits = new List<Models.Commit>();
146-
private Models.Commit _current = null;
147121
private bool _findFirstMerged = false;
148122
private bool _isHeadFound = false;
149123
}

‎src/Commands/QueryCommitsForInteractiveRebase.cs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@ public QueryCommitsForInteractiveRebase(string repo, string on)
1717

1818
public async Task<List<Models.InteractiveCommit>> GetResultAsync()
1919
{
20+
var commits = new List<Models.InteractiveCommit>();
2021
var rs = await ReadToEndAsync().ConfigureAwait(false);
2122
if (!rs.IsSuccess)
22-
return _commits;
23+
{
24+
App.RaiseException(Context, $"Failed to query commits for interactive-rebase. Reason: {rs.StdErr}");
25+
return commits;
26+
}
27+
28+
Models.InteractiveCommit current = null;
2329

2430
var nextPartIdx = 0;
2531
var start = 0;
@@ -30,38 +36,38 @@ public QueryCommitsForInteractiveRebase(string repo, string on)
3036
switch (nextPartIdx)
3137
{
3238
case 0:
33-
_current = new Models.InteractiveCommit();
34-
_current.Commit.SHA = line;
35-
_commits.Add(_current);
39+
current = new Models.InteractiveCommit();
40+
current.Commit.SHA = line;
41+
commits.Add(current);
3642
break;
3743
case 1:
38-
ParseParent(line);
44+
current.Commit.ParseParents(line);
3945
break;
4046
case 2:
41-
_current.Commit.ParseDecorators(line);
47+
current.Commit.ParseDecorators(line);
4248
break;
4349
case 3:
44-
_current.Commit.Author = Models.User.FindOrAdd(line);
50+
current.Commit.Author = Models.User.FindOrAdd(line);
4551
break;
4652
case 4:
47-
_current.Commit.AuthorTime = ulong.Parse(line);
53+
current.Commit.AuthorTime = ulong.Parse(line);
4854
break;
4955
case 5:
50-
_current.Commit.Committer = Models.User.FindOrAdd(line);
56+
current.Commit.Committer = Models.User.FindOrAdd(line);
5157
break;
5258
case 6:
53-
_current.Commit.CommitterTime = ulong.Parse(line);
59+
current.Commit.CommitterTime = ulong.Parse(line);
5460
break;
5561
default:
5662
var boundary = rs.StdOut.IndexOf(_boundary, end + 1, StringComparison.Ordinal);
5763
if (boundary > end)
5864
{
59-
_current.Message = rs.StdOut.Substring(start, boundary - start - 1);
65+
current.Message = rs.StdOut.Substring(start, boundary - start - 1);
6066
end = boundary + _boundary.Length;
6167
}
6268
else
6369
{
64-
_current.Message = rs.StdOut.Substring(start);
70+
current.Message = rs.StdOut.Substring(start);
6571
end = rs.StdOut.Length - 2;
6672
}
6773

@@ -78,19 +84,9 @@ public QueryCommitsForInteractiveRebase(string repo, string on)
7884
end = rs.StdOut.IndexOf('\n', start);
7985
}
8086

81-
return _commits;
82-
}
83-
84-
private void ParseParent(string data)
85-
{
86-
if (data.Length < 8)
87-
return;
88-
89-
_current.Commit.Parents.AddRange(data.Split(' ', StringSplitOptions.RemoveEmptyEntries));
87+
return commits;
9088
}
9189

92-
private List<Models.InteractiveCommit> _commits = [];
93-
private Models.InteractiveCommit _current = null;
9490
private readonly string _boundary;
9591
}
9692
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /