extensions/git/src/git.ts/Repository/getStatus
class Repository:	async getStatus(opts?: { limit?: number; ignoreSubmodules?: boolean; untrackedChanges?: 'mixed' | 'separate' | 'hidden'; cancellationToken?: CancellationToken }): Promise<{ status: IFileStatus[]; statusLength: number; didHitLimit: boolean }> {
		if (opts?.cancellationToken && opts?.cancellationToken.isCancellationRequested) {
			throw new CancellationError();
		}

		const disposables: IDisposable[] = [];

		const env = { GIT_OPTIONAL_LOCKS: '0' };
		const args = ['status', '-z'];

		if (opts?.untrackedChanges === 'hidden') {
			args.push('-uno');
		} else {
			args.push('-uall');
		}

		if (opts?.ignoreSubmodules) {
			args.push('--ignore-submodules');
		}

		const child = this.stream(args, { env });

		let result = new Promise<{ status: IFileStatus[]; statusLength: number; didHitLimit: boolean }>((c, e) => {
			const parser = new GitStatusParser();

			const onClose = (exitCode: number) => {
				if (exitCode !== 0) {
					const stderr = stderrData.join('');
					return e(new GitError({
						message: 'Failed to execute git',
						stderr,
						exitCode,
						gitErrorCode: getGitErrorCode(stderr),
						gitCommand: 'status',
						gitArgs: args
					}));
				}

				c({ status: parser.status, statusLength: parser.status.length, didHitLimit: false });
			};

			const limit = opts?.limit ?? 10000;
			const onStdoutData = (raw: string) => {
				parser.update(raw);

				if (limit !== 0 && parser.status.length > limit) {
					child.removeListener('close', onClose);
					child.stdout!.removeListener('data', onStdoutData);
					child.kill();

					c({ status: parser.status.slice(0, limit), statusLength: parser.status.length, didHitLimit: true });
				}
			};

			child.stdout!.setEncoding('utf8');
			child.stdout!.on('data', onStdoutData);

			const stderrData: string[] = [];
			child.stderr!.setEncoding('utf8');
			child.stderr!.on('data', raw => stderrData.push(raw as string));

			child.on('error', cpErrorHandler(e));
			child.on('close', onClose);
		});

		if (opts?.cancellationToken) {
			const cancellationPromise = new Promise<{ status: IFileStatus[]; statusLength: number; didHitLimit: boolean }>((_, e) => {
				disposables.push(onceEvent(opts.cancellationToken!.onCancellationRequested)(() => {
					try {
						child.kill();
					} catch (err) {
						// noop
					}

					e(new CancellationError());
				}));
			});

			result = Promise.race([result, cancellationPromise]);
		}

		try {
			const { status, statusLength, didHitLimit } = await result;
			return { status, statusLength, didHitLimit };
		}
		finally {
			dispose(disposables);
		}
	}