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 9be50eb

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 9be50eb

File tree

8 files changed

+319
-300
lines changed

8 files changed

+319
-300
lines changed

‎src/Commands/CompareRevisions.cs

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
using System;
2-
using System.Collections.Generic;
1+
using System.Collections.Generic;
2+
using System.Diagnostics;
33
using System.Text.RegularExpressions;
44
using System.Threading.Tasks;
55

@@ -33,56 +33,62 @@ public CompareRevisions(string repo, string start, string end, string path)
3333
public async Task<List<Models.Change>> ReadAsync()
3434
{
3535
var changes = new List<Models.Change>();
36-
var rs = await ReadToEndAsync().ConfigureAwait(false);
37-
if (!rs.IsSuccess)
38-
return changes;
36+
try
37+
{
38+
using var proc = new Process();
39+
proc.StartInfo = CreateGitStartInfo(true);
40+
proc.Start();
3941

40-
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
41-
foreach (var line in lines)
42-
ParseLine(changes, line);
42+
while (await proc.StandardOutput.ReadLineAsync() is { } line)
43+
{
44+
var match = REG_FORMAT().Match(line);
45+
if (!match.Success)
46+
{
47+
match = REG_RENAME_FORMAT().Match(line);
48+
if (match.Success)
49+
{
50+
var renamed = new Models.Change() { Path = match.Groups[1].Value };
51+
renamed.Set(Models.ChangeState.Renamed);
52+
changes.Add(renamed);
53+
}
4354

44-
changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
45-
return changes;
46-
}
55+
continue;
56+
}
4757

48-
private void ParseLine(List<Models.Change> outs, string line)
49-
{
50-
var match = REG_FORMAT().Match(line);
51-
if (!match.Success)
52-
{
53-
match = REG_RENAME_FORMAT().Match(line);
54-
if (match.Success)
55-
{
56-
var renamed = new Models.Change() { Path = match.Groups[1].Value };
57-
renamed.Set(Models.ChangeState.Renamed);
58-
outs.Add(renamed);
59-
}
58+
var change = new Models.Change() { Path = match.Groups[2].Value };
59+
var status = match.Groups[1].Value;
6060

61-
return;
62-
}
61+
switch (status[0])
62+
{
63+
case 'M':
64+
change.Set(Models.ChangeState.Modified);
65+
changes.Add(change);
66+
break;
67+
case 'A':
68+
change.Set(Models.ChangeState.Added);
69+
changes.Add(change);
70+
break;
71+
case 'D':
72+
change.Set(Models.ChangeState.Deleted);
73+
changes.Add(change);
74+
break;
75+
case 'C':
76+
change.Set(Models.ChangeState.Copied);
77+
changes.Add(change);
78+
break;
79+
}
80+
}
6381

64-
var change = new Models.Change() { Path = match.Groups[2].Value };
65-
var status = match.Groups[1].Value;
82+
await proc.WaitForExitAsync().ConfigureAwait(false);
6683

67-
switch (status[0])
84+
changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
85+
}
86+
catch
6887
{
69-
case 'M':
70-
change.Set(Models.ChangeState.Modified);
71-
outs.Add(change);
72-
break;
73-
case 'A':
74-
change.Set(Models.ChangeState.Added);
75-
outs.Add(change);
76-
break;
77-
case 'D':
78-
change.Set(Models.ChangeState.Deleted);
79-
outs.Add(change);
80-
break;
81-
case 'C':
82-
change.Set(Models.ChangeState.Copied);
83-
outs.Add(change);
84-
break;
88+
//ignore changes;
8589
}
90+
91+
return changes;
8692
}
8793
}
8894
}

‎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 によって変換されたページ (->オリジナル) /