11using System ;
22using System . Collections . Generic ;
3+ using System . Diagnostics ;
34using System . Text ;
45using 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+ await proc . 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 }
0 commit comments