@@ -2,7 +2,7 @@ import { spawn } from 'child_process';
22import * as iconv from 'iconv-lite' ;
33import { injectable , multiInject } from 'inversify' ;
44import { Writable } from 'stream' ;
5- import { extensions } from 'vscode' ;
5+ import { Disposable , extensions } from 'vscode' ;
66import { IGitCommandExecutor } from './types' ;
77import { GitExtension } from '../repository/git.d' ;
88import { StopWatch } from '../../common/stopWatch' ;
@@ -39,47 +39,55 @@ export class GitCommandExecutor implements IGitCommandExecutor {
3939 const gitPathCommand = childProcOptions . shell && gitPath . indexOf ( ' ' ) > 0 ? `"${ gitPath } "` : gitPath ;
4040 const stopWatch = new StopWatch ( ) ;
4141 const gitShow = spawn ( gitPathCommand , args , childProcOptions ) ;
42-
43- let stdout : Buffer = new Buffer ( '' ) ;
44- let stderr : Buffer = new Buffer ( '' ) ;
45-
4642 if ( binaryOuput ) {
4743 gitShow . stdout . pipe ( destination ) ;
48- } else {
49- gitShow . stdout . on ( 'data' , data => {
50- stdout = Buffer . concat ( [ stdout , data as Buffer ] ) ;
51- } ) ;
5244 }
45+ const disposables : Disposable [ ] = [ ] ;
46+ const on = ( ee : NodeJS . EventEmitter , name : string , fn : Function ) => {
47+ ee . on ( name , fn ) ;
48+ disposables . push ( { dispose : ( ) => ee . removeListener ( name , fn ) } ) ;
49+ } ;
5350
54- gitShow . stderr . on ( 'data' , data => {
55- stderr = Buffer . concat ( [ stderr , data as Buffer ] ) ;
56- } ) ;
51+ const buffers : Buffer [ ] = [ ] ;
52+ if ( ! binaryOuput ) {
53+ on ( gitShow . stdout , 'data' , ( data : Buffer ) => buffers . push ( data ) ) ;
54+ }
55+ const errBuffers : Buffer [ ] = [ ] ;
56+ on ( gitShow . stderr , 'data' , ( data : Buffer ) => errBuffers . push ( data ) ) ;
5757
58+ // tslint:disable-next-line:no-any
5859 return new Promise < any > ( ( resolve , reject ) => {
59- gitShow . on ( 'error' , reject )
60- gitShow . on ( 'exit' , code => {
61- this . loggers . forEach ( logger => {
62- logger . log ( 'git' , ...args , ` (completed in ${ stopWatch . elapsedTime / 1000 } s)` ) ;
63- } ) ;
64-
65- if ( code === 0 ) {
66- const stdOut = binaryOuput ? undefined : decode ( stdout , childProcOptions . encoding ) ;
60+ gitShow . once ( 'close' , ( ) => {
61+ if ( errBuffers . length > 0 ) {
62+ let stdErr = decode ( errBuffers , childProcOptions . encoding ) ;
63+ stdErr = stdErr . startsWith ( 'error: ' ) ? stdErr . substring ( 'error: ' . length ) : stdErr ;
6764 this . loggers . forEach ( logger => {
68- logger . trace ( binaryOuput ? '<binary>' : stdout ) ;
65+ logger . log ( 'git' , ...args , ` (completed in ${ stopWatch . elapsedTime / 1000 } s)` ) ;
66+ logger . error ( stdErr ) ;
6967 } ) ;
70- resolve ( stdOut ) ;
68+ reject ( stdErr ) ;
7169 } else {
72- const stdErr = binaryOuput ? undefined : decode ( stderr , childProcOptions . encoding ) ;
70+ const stdOut = binaryOuput ? undefined : decode ( buffers , childProcOptions . encoding ) ;
7371 this . loggers . forEach ( logger => {
74- logger . error ( stdErr ) ;
72+ logger . log ( 'git' , ...args , ` (completed in ${ stopWatch . elapsedTime / 1000 } s)` ) ;
73+ logger . trace ( binaryOuput ? '<binary>' : stdOut ) ;
7574 } ) ;
76- reject ( { code , error : stdErr } ) ;
75+ resolve ( stdOut ) ;
7776 }
78- } )
77+ disposables . forEach ( disposable => disposable . dispose ( ) ) ;
78+ } ) ;
79+ gitShow . once ( 'error' , ex => {
80+ reject ( ex ) ;
81+ this . loggers . forEach ( logger => {
82+ logger . log ( 'git' , ...args , ` (completed in ${ stopWatch . elapsedTime / 1000 } s)` ) ;
83+ logger . error ( ex ) ;
84+ } ) ;
85+ disposables . forEach ( disposable => disposable . dispose ( ) ) ;
86+ } ) ;
7987 } ) ;
8088 }
8189}
8290
83- function decode ( buffers : Buffer , encoding : string ) : string {
84- return iconv . decode ( buffers , encoding ) ;
85- }
91+ function decode ( buffers : Buffer [ ] , encoding : string ) : string {
92+ return iconv . decode ( Buffer . concat ( buffers ) , encoding ) ;
93+ }
0 commit comments