Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)

* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c

* remove files we don't want

* fix hygiene

* update distro

* update distro

* fix hygiene

* fix strict nulls

* distro

* distro

* fix tests

* fix tests

* add another edit

* fix viewlet icon

* fix azure dialog

* fix some padding

* fix more padding issues
This commit is contained in:
Anthony Dresser
2019-12-04 19:28:22 -08:00
committed by GitHub
parent a8818ab0df
commit f5ce7fb2a5
1507 changed files with 42813 additions and 27370 deletions

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as fs from 'fs';
import { promises as fs, exists } from 'fs';
import * as path from 'path';
import * as os from 'os';
import * as cp from 'child_process';
@@ -11,7 +11,7 @@ import * as which from 'which';
import { EventEmitter } from 'events';
import iconv = require('iconv-lite');
import * as filetype from 'file-type';
import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util';
import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util';
import { CancellationToken, Progress } from 'vscode';
import { URI } from 'vscode-uri';
import { detectEncoding } from './encoding';
@@ -22,8 +22,6 @@ import { StringDecoder } from 'string_decoder';
// https://github.com/microsoft/vscode/issues/65693
const MAX_CLI_LENGTH = 30000;
const readfile = denodeify<string, string | null, string>(fs.readFile);
export interface IGit {
path: string;
version: string;
@@ -196,13 +194,13 @@ async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToke
}),
new Promise<Buffer>(c => {
const buffers: Buffer[] = [];
on(child.stdout, 'data', (b: Buffer) => buffers.push(b));
once(child.stdout, 'close', () => c(Buffer.concat(buffers)));
on(child.stdout!, 'data', (b: Buffer) => buffers.push(b));
once(child.stdout!, 'close', () => c(Buffer.concat(buffers)));
}),
new Promise<string>(c => {
const buffers: Buffer[] = [];
on(child.stderr, 'data', (b: Buffer) => buffers.push(b));
once(child.stderr, 'close', () => c(Buffer.concat(buffers).toString('utf8')));
on(child.stderr!, 'data', (b: Buffer) => buffers.push(b));
once(child.stderr!, 'close', () => c(Buffer.concat(buffers).toString('utf8')));
})
]) as Promise<[number, Buffer, string]>;
@@ -350,7 +348,7 @@ export class Git {
let folderPath = path.join(parentPath, folderName);
let count = 1;
while (count < 20 && await new Promise(c => fs.exists(folderPath, c))) {
while (count < 20 && await new Promise(c => exists(folderPath, c))) {
folderName = `${baseFolderName}-${count++}`;
folderPath = path.join(parentPath, folderName);
}
@@ -360,7 +358,7 @@ export class Git {
const onSpawn = (child: cp.ChildProcess) => {
const decoder = new StringDecoder('utf8');
const lineStream = new byline.LineStream({ encoding: 'utf8' });
child.stderr.on('data', (buffer: Buffer) => lineStream.write(decoder.write(buffer)));
child.stderr!.on('data', (buffer: Buffer) => lineStream.write(decoder.write(buffer)));
let totalProgress = 0;
let previousProgress = 0;
@@ -438,7 +436,7 @@ export class Git {
}
if (options.input) {
child.stdin.end(options.input, 'utf8');
child.stdin!.end(options.input, 'utf8');
}
const bufferResult = await exec(child, options.cancellationToken);
@@ -763,9 +761,10 @@ export class Repository {
async log(options?: LogOptions): Promise<Commit[]> {
const maxEntries = options && typeof options.maxEntries === 'number' && options.maxEntries > 0 ? options.maxEntries : 32;
const args = ['log', '-' + maxEntries, `--pretty=format:${COMMIT_FORMAT}%x00%x00`];
const gitResult = await this.run(args);
if (gitResult.exitCode) {
// An empty repo.
// An empty repo
return [];
}
@@ -882,7 +881,7 @@ export class Repository {
async detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
const child = await this.stream(['show', object]);
const buffer = await readBytes(child.stdout, 4100);
const buffer = await readBytes(child.stdout!, 4100);
try {
child.kill();
@@ -1151,7 +1150,7 @@ export class Repository {
async stage(path: string, data: string): Promise<void> {
const child = this.stream(['hash-object', '--stdin', '-w', '--path', path], { stdio: [null, null, null] });
child.stdin.end(data, 'utf8');
child.stdin!.end(data, 'utf8');
const { exitCode, stdout } = await exec(child);
const hash = stdout.toString('utf8');
@@ -1163,11 +1162,12 @@ export class Repository {
});
}
const treeish = await this.getCommit('HEAD').then(() => 'HEAD', () => '');
let mode: string;
let add: string = '';
try {
const details = await this.getObjectDetails('HEAD', path);
const details = await this.getObjectDetails(treeish, path);
mode = details.mode;
} catch (err) {
if (err.gitErrorCode !== GitErrorCodes.UnknownPath) {
@@ -1327,6 +1327,11 @@ export class Repository {
await this.run(args);
}
async deleteTag(name: string): Promise<void> {
let args = ['tag', '-d', name];
await this.run(args);
}
async clean(paths: string[]): Promise<void> {
const pathsByGroup = groupBy(paths, p => path.dirname(p));
const groups = Object.keys(pathsByGroup).map(k => pathsByGroup[k]);
@@ -1592,6 +1597,24 @@ export class Repository {
}
}
async dropStash(index?: number): Promise<void> {
const args = ['stash', 'drop'];
if (typeof index === 'number') {
args.push(`stash@{${index}}`);
}
try {
await this.run(args);
} catch (err) {
if (/No stash found/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoStashFound;
}
throw err;
}
}
getStatus(limit = 5000): Promise<{ status: IFileStatus[]; didHitLimit: boolean; }> {
return new Promise<{ status: IFileStatus[]; didHitLimit: boolean; }>((c, e) => {
const parser = new GitStatusParser();
@@ -1618,19 +1641,19 @@ export class Repository {
if (parser.status.length > limit) {
child.removeListener('exit', onExit);
child.stdout.removeListener('data', onStdoutData);
child.stdout!.removeListener('data', onStdoutData);
child.kill();
c({ status: parser.status.slice(0, limit), didHitLimit: true });
}
};
child.stdout.setEncoding('utf8');
child.stdout.on('data', onStdoutData);
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.stderr!.setEncoding('utf8');
child.stderr!.on('data', raw => stderrData.push(raw as string));
child.on('error', cpErrorHandler(e));
child.on('exit', onExit);
@@ -1789,18 +1812,17 @@ export class Repository {
}
}
cleanupCommitEditMessage(message: string): string {
//TODO: Support core.commentChar
// TODO: Support core.commentChar
stripCommitMessageComments(message: string): string {
return message.replace(/^\s*#.*$\n?/gm, '').trim();
}
async getMergeMessage(): Promise<string | undefined> {
const mergeMsgPath = path.join(this.repositoryRoot, '.git', 'MERGE_MSG');
try {
const raw = await readfile(mergeMsgPath, 'utf8');
return raw.trim();
const raw = await fs.readFile(mergeMsgPath, 'utf8');
return this.stripCommitMessageComments(raw);
} catch {
return undefined;
}
@@ -1823,9 +1845,8 @@ export class Repository {
templatePath = path.join(this.repositoryRoot, templatePath);
}
const raw = await readfile(templatePath, 'utf8');
return raw.trim();
const raw = await fs.readFile(templatePath, 'utf8');
return this.stripCommitMessageComments(raw);
} catch (err) {
return '';
}
@@ -1848,7 +1869,7 @@ export class Repository {
const gitmodulesPath = path.join(this.root, '.gitmodules');
try {
const gitmodulesRaw = await readfile(gitmodulesPath, 'utf8');
const gitmodulesRaw = await fs.readFile(gitmodulesPath, 'utf8');
return parseGitmodules(gitmodulesRaw);
} catch (err) {
if (/ENOENT/.test(err.message)) {