@@ -24,12 +24,12 @@ type BlamePart struct {
2424
2525// BlameReader returns part of file blame one by one
2626type BlameReader struct {
27- cmd * exec.Cmd
28- output io.ReadCloser
29- reader * bufio. Reader
30- lastSha * string
31- cancel context. CancelFunc // Cancels the context that this reader runs in
32- finished process. FinishedFunc // Tells the process manager we're finished and it can remove the associated process from the process table
27+ cmd * exec.Cmd
28+ reader io.ReadCloser
29+ lastSha * string
30+ cancel context. CancelFunc // Cancels the context that this reader runs in
31+ finished process. FinishedFunc // Tells the process manager we're finished and it can remove the associated process from the process table
32+ bufferedReader * bufio. Reader
3333}
3434
3535var shaLineRegex = regexp .MustCompile ("^([a-z0-9]{40})" )
@@ -38,8 +38,6 @@ var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")
3838func (r * BlameReader ) NextPart () (* BlamePart , error ) {
3939 var blamePart * BlamePart
4040
41- reader := r .reader
42-
4341 if r .lastSha != nil {
4442 blamePart = & BlamePart {* r .lastSha , make ([]string , 0 )}
4543 }
@@ -49,7 +47,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
4947 var err error
5048
5149 for err != io .EOF {
52- line , isPrefix , err = reader .ReadLine ()
50+ line , isPrefix , err = r . bufferedReader .ReadLine ()
5351 if err != nil && err != io .EOF {
5452 return blamePart , err
5553 }
@@ -71,7 +69,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
7169 r .lastSha = & sha1
7270 // need to munch to end of line...
7371 for isPrefix {
74- _ , isPrefix , err = reader .ReadLine ()
72+ _ , isPrefix , err = r . bufferedReader .ReadLine ()
7573 if err != nil && err != io .EOF {
7674 return blamePart , err
7775 }
@@ -86,7 +84,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
8684
8785 // need to munch to end of line...
8886 for isPrefix {
89- _ , isPrefix , err = reader .ReadLine ()
87+ _ , isPrefix , err = r . bufferedReader .ReadLine ()
9088 if err != nil && err != io .EOF {
9189 return blamePart , err
9290 }
@@ -102,9 +100,9 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
102100func (r * BlameReader ) Close () error {
103101 defer r .finished () // Only remove the process from the process table when the underlying command is closed
104102 r .cancel () // However, first cancel our own context early
103+ r .bufferedReader = nil
105104
106- _ = r .output .Close ()
107-
105+ _ = r .reader .Close ()
108106 if err := r .cmd .Wait (); err != nil {
109107 return fmt .Errorf ("Wait: %w" , err )
110108 }
@@ -126,25 +124,27 @@ func createBlameReader(ctx context.Context, dir string, command ...string) (*Bla
126124 cmd .Stderr = os .Stderr
127125 process .SetSysProcAttribute (cmd )
128126
129- stdout , err := cmd . StdoutPipe ()
127+ reader , stdout , err := os . Pipe ()
130128 if err != nil {
131129 defer finished ()
132130 return nil , fmt .Errorf ("StdoutPipe: %w" , err )
133131 }
132+ cmd .Stdout = stdout
134133
135134 if err = cmd .Start (); err != nil {
136135 defer finished ()
137136 _ = stdout .Close ()
138137 return nil , fmt .Errorf ("Start: %w" , err )
139138 }
139+ _ = stdout .Close ()
140140
141- reader := bufio .NewReader (stdout )
141+ bufferedReader := bufio .NewReader (reader )
142142
143143 return & BlameReader {
144- cmd : cmd ,
145- output : stdout ,
146- reader : reader ,
147- cancel : cancel ,
148- finished : finished ,
144+ cmd : cmd ,
145+ reader : reader ,
146+ cancel : cancel ,
147+ finished : finished ,
148+ bufferedReader : bufferedReader ,
149149 }, nil
150150}
0 commit comments