Skip to content

Commit 8b9b477

Browse files
author
ole1986
committed
Recovered gitCommandExec.ts due to async issues
1 parent 4bf49a0 commit 8b9b477

File tree

1 file changed

+37
-29
lines changed

1 file changed

+37
-29
lines changed

src/adapter/exec/gitCommandExec.ts

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { spawn } from 'child_process';
22
import * as iconv from 'iconv-lite';
33
import { injectable, multiInject } from 'inversify';
44
import { Writable } from 'stream';
5-
import { extensions } from 'vscode';
5+
import { Disposable, extensions } from 'vscode';
66
import { IGitCommandExecutor } from './types';
77
import { GitExtension } from '../repository/git.d';
88
import { 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

Comments
 (0)