mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-30 01:25:38 -05:00
Merge from vscode bead496a613e475819f89f08e9e882b841bc1fe8 (#14883)
* Merge from vscode bead496a613e475819f89f08e9e882b841bc1fe8 * Bump distro * Upgrade GCC to 4.9 due to yarn install errors * Update build image * Fix bootstrap base url * Bump distro * Fix build errors * Update source map file * Disable checkbox for blocking migration issues (#15131) * disable checkbox for blocking issues * wip * disable checkbox fixes * fix strings * Remove duplicate tsec command * Default to off for tab color if settings not present * re-skip failing tests * Fix mocha error * Bump sqlite version & fix notebooks search view * Turn off esbuild warnings * Update esbuild log level * Fix overflowactionbar tests * Fix ts-ignore in dropdown tests * cleanup/fixes * Fix hygiene * Bundle in entire zone.js module * Remove extra constructor param * bump distro for web compile break * bump distro for web compile break v2 * Undo log level change * New distro * Fix integration test scripts * remove the "no yarn.lock changes" workflow * fix scripts v2 * Update unit test scripts * Ensure ads-kerberos2 updates in .vscodeignore * Try fix unit tests * Upload crash reports * remove nogpu * always upload crashes * Use bash script * Consolidate data/ext dir names * Create in tmp directory Co-authored-by: chlafreniere <hichise@gmail.com> Co-authored-by: Christopher Suh <chsuh@microsoft.com> Co-authored-by: chgagnon <chgagnon@microsoft.com>
This commit is contained in:
@@ -14,7 +14,7 @@ import * as filetype from 'file-type';
|
||||
import { assign, groupBy, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent, splitInChunks, Limiter } from './util';
|
||||
import { CancellationToken, Progress, Uri } from 'vscode';
|
||||
import { detectEncoding } from './encoding';
|
||||
import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status, CommitOptions, BranchQuery } from './api/git';
|
||||
import { Ref, RefType, Branch, Remote, ForcePushMode, GitErrorCodes, LogOptions, Change, Status, CommitOptions, BranchQuery } from './api/git';
|
||||
import * as byline from 'byline';
|
||||
import { StringDecoder } from 'string_decoder';
|
||||
|
||||
@@ -311,6 +311,7 @@ export class GitError {
|
||||
|
||||
export interface IGitOptions {
|
||||
gitPath: string;
|
||||
userAgent: string;
|
||||
version: string;
|
||||
env?: any;
|
||||
}
|
||||
@@ -362,6 +363,8 @@ export interface ICloneOptions {
|
||||
export class Git {
|
||||
|
||||
readonly path: string;
|
||||
readonly userAgent: string;
|
||||
readonly version: string;
|
||||
private env: any;
|
||||
|
||||
private _onOutput = new EventEmitter();
|
||||
@@ -369,6 +372,8 @@ export class Git {
|
||||
|
||||
constructor(options: IGitOptions) {
|
||||
this.path = options.gitPath;
|
||||
this.version = options.version;
|
||||
this.userAgent = options.userAgent;
|
||||
this.env = options.env || {};
|
||||
}
|
||||
|
||||
@@ -427,7 +432,11 @@ export class Git {
|
||||
if (options.recursive) {
|
||||
command.push('--recursive');
|
||||
}
|
||||
await this.exec(options.parentPath, command, { cancellationToken, onSpawn });
|
||||
await this.exec(options.parentPath, command, {
|
||||
cancellationToken,
|
||||
env: { 'GIT_HTTP_USER_AGENT': this.userAgent },
|
||||
onSpawn,
|
||||
});
|
||||
} catch (err) {
|
||||
if (err.stderr) {
|
||||
err.stderr = err.stderr.replace(/^Cloning.+$/m, '').trim();
|
||||
@@ -458,7 +467,7 @@ export class Git {
|
||||
|
||||
try {
|
||||
const networkPath = await new Promise<string | undefined>(resolve =>
|
||||
realpath.native(`${letter}:`, { encoding: 'utf8' }, (err, resolvedPath) =>
|
||||
realpath.native(`${letter}:\\`, { encoding: 'utf8' }, (err, resolvedPath) =>
|
||||
resolve(err !== null ? undefined : resolvedPath),
|
||||
),
|
||||
);
|
||||
@@ -798,11 +807,6 @@ export interface PullOptions {
|
||||
readonly cancellationToken?: CancellationToken;
|
||||
}
|
||||
|
||||
export enum ForcePushMode {
|
||||
Force,
|
||||
ForceWithLease
|
||||
}
|
||||
|
||||
export class Repository {
|
||||
|
||||
constructor(
|
||||
@@ -819,8 +823,7 @@ export class Repository {
|
||||
return this.repositoryRoot;
|
||||
}
|
||||
|
||||
// TODO@Joao: rename to exec
|
||||
async run(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
|
||||
async exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
|
||||
return await this.git.exec(this.repositoryRoot, args, options);
|
||||
}
|
||||
|
||||
@@ -845,7 +848,7 @@ export class Repository {
|
||||
args.push(value);
|
||||
}
|
||||
|
||||
const result = await this.run(args, options);
|
||||
const result = await this.exec(args, options);
|
||||
return result.stdout.trim();
|
||||
}
|
||||
|
||||
@@ -858,7 +861,7 @@ export class Repository {
|
||||
|
||||
args.push('-l');
|
||||
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
const lines = result.stdout.trim().split(/\r|\r\n|\n/);
|
||||
|
||||
return lines.map(entry => {
|
||||
@@ -874,7 +877,7 @@ export class Repository {
|
||||
args.push(options.path);
|
||||
}
|
||||
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
if (result.exitCode) {
|
||||
// An empty repo
|
||||
return [];
|
||||
@@ -905,7 +908,7 @@ export class Repository {
|
||||
|
||||
args.push('--', uri.fsPath);
|
||||
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
if (result.exitCode) {
|
||||
// No file history, e.g. a new file or untracked
|
||||
return [];
|
||||
@@ -960,7 +963,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
const { mode, object } = elements[0];
|
||||
const catFile = await this.run(['cat-file', '-s', object]);
|
||||
const catFile = await this.exec(['cat-file', '-s', object]);
|
||||
const size = parseInt(catFile.stdout);
|
||||
|
||||
return { mode, object, size };
|
||||
@@ -977,12 +980,12 @@ export class Repository {
|
||||
}
|
||||
|
||||
async lstree(treeish: string, path: string): Promise<LsTreeElement[]> {
|
||||
const { stdout } = await this.run(['ls-tree', '-l', treeish, '--', sanitizePath(path)]);
|
||||
const { stdout } = await this.exec(['ls-tree', '-l', treeish, '--', sanitizePath(path)]);
|
||||
return parseLsTree(stdout);
|
||||
}
|
||||
|
||||
async lsfiles(path: string): Promise<LsFilesElement[]> {
|
||||
const { stdout } = await this.run(['ls-files', '--stage', '--', sanitizePath(path)]);
|
||||
const { stdout } = await this.exec(['ls-files', '--stage', '--', sanitizePath(path)]);
|
||||
return parseLsFiles(stdout);
|
||||
}
|
||||
|
||||
@@ -1047,7 +1050,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
} catch (err) {
|
||||
if (/patch does not apply/.test(err.stderr)) {
|
||||
err.gitErrorCode = GitErrorCodes.PatchDoesNotApply;
|
||||
@@ -1064,7 +1067,7 @@ export class Repository {
|
||||
args.push('--cached');
|
||||
}
|
||||
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
@@ -1077,7 +1080,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
const args = ['diff', '--', sanitizePath(path)];
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
@@ -1090,7 +1093,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
const args = ['diff', ref, '--', sanitizePath(path)];
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
@@ -1103,7 +1106,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
const args = ['diff', '--cached', '--', sanitizePath(path)];
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
@@ -1116,13 +1119,13 @@ export class Repository {
|
||||
}
|
||||
|
||||
const args = ['diff', '--cached', ref, '--', sanitizePath(path)];
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
async diffBlobs(object1: string, object2: string): Promise<string> {
|
||||
const args = ['diff', object1, object2];
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
return result.stdout;
|
||||
}
|
||||
|
||||
@@ -1136,7 +1139,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
const args = ['diff', range, '--', sanitizePath(path)];
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
|
||||
return result.stdout.trim();
|
||||
}
|
||||
@@ -1151,7 +1154,7 @@ export class Repository {
|
||||
args.push(ref);
|
||||
}
|
||||
|
||||
const gitResult = await this.run(args);
|
||||
const gitResult = await this.exec(args);
|
||||
if (gitResult.exitCode) {
|
||||
return [];
|
||||
}
|
||||
@@ -1224,14 +1227,14 @@ export class Repository {
|
||||
|
||||
async getMergeBase(ref1: string, ref2: string): Promise<string> {
|
||||
const args = ['merge-base', ref1, ref2];
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
|
||||
return result.stdout.trim();
|
||||
}
|
||||
|
||||
async hashObject(data: string): Promise<string> {
|
||||
const args = ['hash-object', '-w', '--stdin'];
|
||||
const result = await this.run(args, { input: data });
|
||||
const result = await this.exec(args, { input: data });
|
||||
|
||||
return result.stdout.trim();
|
||||
}
|
||||
@@ -1247,10 +1250,10 @@ export class Repository {
|
||||
|
||||
if (paths && paths.length) {
|
||||
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
|
||||
await this.run([...args, '--', ...chunk]);
|
||||
await this.exec([...args, '--', ...chunk]);
|
||||
}
|
||||
} else {
|
||||
await this.run([...args, '--', '.']);
|
||||
await this.exec([...args, '--', '.']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1263,7 +1266,7 @@ export class Repository {
|
||||
|
||||
args.push(...paths.map(sanitizePath));
|
||||
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async stage(path: string, data: string): Promise<void> {
|
||||
@@ -1296,7 +1299,7 @@ export class Repository {
|
||||
add = '--add';
|
||||
}
|
||||
|
||||
await this.run(['update-index', add, '--cacheinfo', mode, hash, path]);
|
||||
await this.exec(['update-index', add, '--cacheinfo', mode, hash, path]);
|
||||
}
|
||||
|
||||
async checkout(treeish: string, paths: string[], opts: { track?: boolean, detached?: boolean } = Object.create(null)): Promise<void> {
|
||||
@@ -1317,10 +1320,10 @@ export class Repository {
|
||||
try {
|
||||
if (paths && paths.length > 0) {
|
||||
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
|
||||
await this.run([...args, '--', ...chunk]);
|
||||
await this.exec([...args, '--', ...chunk]);
|
||||
}
|
||||
} else {
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
} catch (err) {
|
||||
if (/Please,? commit your changes or stash them/.test(err.stderr || '')) {
|
||||
@@ -1365,25 +1368,27 @@ export class Repository {
|
||||
args.push('--no-verify');
|
||||
}
|
||||
|
||||
// Stops git from guessing at user/email
|
||||
args.splice(0, 0, '-c', 'user.useConfigOnly=true');
|
||||
if (opts.requireUserConfig ?? true) {
|
||||
// Stops git from guessing at user/email
|
||||
args.splice(0, 0, '-c', 'user.useConfigOnly=true');
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(args, !opts.amend || message ? { input: message || '' } : {});
|
||||
await this.exec(args, !opts.amend || message ? { input: message || '' } : {});
|
||||
} catch (commitErr) {
|
||||
await this.handleCommitError(commitErr);
|
||||
}
|
||||
}
|
||||
|
||||
async rebaseAbort(): Promise<void> {
|
||||
await this.run(['rebase', '--abort']);
|
||||
await this.exec(['rebase', '--abort']);
|
||||
}
|
||||
|
||||
async rebaseContinue(): Promise<void> {
|
||||
const args = ['rebase', '--continue'];
|
||||
|
||||
try {
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
} catch (commitErr) {
|
||||
await this.handleCommitError(commitErr);
|
||||
}
|
||||
@@ -1396,14 +1401,14 @@ export class Repository {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(['config', '--get-all', 'user.name']);
|
||||
await this.exec(['config', '--get-all', 'user.name']);
|
||||
} catch (err) {
|
||||
err.gitErrorCode = GitErrorCodes.NoUserNameConfigured;
|
||||
throw err;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(['config', '--get-all', 'user.email']);
|
||||
await this.exec(['config', '--get-all', 'user.email']);
|
||||
} catch (err) {
|
||||
err.gitErrorCode = GitErrorCodes.NoUserEmailConfigured;
|
||||
throw err;
|
||||
@@ -1419,39 +1424,39 @@ export class Repository {
|
||||
args.push(ref);
|
||||
}
|
||||
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async deleteBranch(name: string, force?: boolean): Promise<void> {
|
||||
const args = ['branch', force ? '-D' : '-d', name];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async renameBranch(name: string): Promise<void> {
|
||||
const args = ['branch', '-m', name];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async move(from: string, to: string): Promise<void> {
|
||||
const args = ['mv', from, to];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async setBranchUpstream(name: string, upstream: string): Promise<void> {
|
||||
const args = ['branch', '--set-upstream-to', upstream, name];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async deleteRef(ref: string): Promise<void> {
|
||||
const args = ['update-ref', '-d', ref];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async merge(ref: string): Promise<void> {
|
||||
const args = ['merge', ref];
|
||||
|
||||
try {
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
} catch (err) {
|
||||
if (/^CONFLICT /m.test(err.stdout || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.Conflict;
|
||||
@@ -1470,12 +1475,12 @@ export class Repository {
|
||||
args = [...args, name];
|
||||
}
|
||||
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async deleteTag(name: string): Promise<void> {
|
||||
let args = ['tag', '-d', name];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async clean(paths: string[]): Promise<void> {
|
||||
@@ -1488,7 +1493,7 @@ export class Repository {
|
||||
|
||||
for (const paths of groups) {
|
||||
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
|
||||
promises.push(limiter.queue(() => this.run([...args, '--', ...chunk])));
|
||||
promises.push(limiter.queue(() => this.exec([...args, '--', ...chunk])));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1496,10 +1501,10 @@ export class Repository {
|
||||
}
|
||||
|
||||
async undo(): Promise<void> {
|
||||
await this.run(['clean', '-fd']);
|
||||
await this.exec(['clean', '-fd']);
|
||||
|
||||
try {
|
||||
await this.run(['checkout', '--', '.']);
|
||||
await this.exec(['checkout', '--', '.']);
|
||||
} catch (err) {
|
||||
if (/did not match any file\(s\) known to git\./.test(err.stderr || '')) {
|
||||
return;
|
||||
@@ -1511,11 +1516,11 @@ export class Repository {
|
||||
|
||||
async reset(treeish: string, hard: boolean = false): Promise<void> {
|
||||
const args = ['reset', hard ? '--hard' : '--soft', treeish];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async revert(treeish: string, paths: string[]): Promise<void> {
|
||||
const result = await this.run(['branch']);
|
||||
const result = await this.exec(['branch']);
|
||||
let args: string[];
|
||||
|
||||
// In case there are no branches, we must use rm --cached
|
||||
@@ -1528,10 +1533,10 @@ export class Repository {
|
||||
try {
|
||||
if (paths && paths.length > 0) {
|
||||
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
|
||||
await this.run([...args, '--', ...chunk]);
|
||||
await this.exec([...args, '--', ...chunk]);
|
||||
}
|
||||
} else {
|
||||
await this.run([...args, '--', '.']);
|
||||
await this.exec([...args, '--', '.']);
|
||||
}
|
||||
} catch (err) {
|
||||
// In case there are merge conflicts to be resolved, git reset will output
|
||||
@@ -1546,23 +1551,24 @@ export class Repository {
|
||||
|
||||
async addRemote(name: string, url: string): Promise<void> {
|
||||
const args = ['remote', 'add', name, url];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async removeRemote(name: string): Promise<void> {
|
||||
const args = ['remote', 'remove', name];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async renameRemote(name: string, newName: string): Promise<void> {
|
||||
const args = ['remote', 'rename', name, newName];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async fetch(options: { remote?: string, ref?: string, all?: boolean, prune?: boolean, depth?: number, silent?: boolean, readonly cancellationToken?: CancellationToken } = {}): Promise<void> {
|
||||
const args = ['fetch'];
|
||||
const spawnOptions: SpawnOptions = {
|
||||
cancellationToken: options.cancellationToken,
|
||||
env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent }
|
||||
};
|
||||
|
||||
if (options.remote) {
|
||||
@@ -1584,11 +1590,11 @@ export class Repository {
|
||||
}
|
||||
|
||||
if (options.silent) {
|
||||
spawnOptions.env = { 'VSCODE_GIT_FETCH_SILENT': 'true' };
|
||||
spawnOptions.env!['VSCODE_GIT_FETCH_SILENT'] = 'true';
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(args, spawnOptions);
|
||||
await this.exec(args, spawnOptions);
|
||||
} catch (err) {
|
||||
if (/No remote repository specified\./.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.NoRemoteRepositorySpecified;
|
||||
@@ -1621,7 +1627,10 @@ export class Repository {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(args, options);
|
||||
await this.exec(args, {
|
||||
cancellationToken: options.cancellationToken,
|
||||
env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent }
|
||||
});
|
||||
} catch (err) {
|
||||
if (/^CONFLICT \([^)]+\): \b/m.test(err.stdout || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.Conflict;
|
||||
@@ -1648,7 +1657,7 @@ export class Repository {
|
||||
args.push(branch);
|
||||
|
||||
try {
|
||||
await this.run(args, options);
|
||||
await this.exec(args, options);
|
||||
} catch (err) {
|
||||
if (/^CONFLICT \([^)]+\): \b/m.test(err.stdout || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.Conflict;
|
||||
@@ -1690,7 +1699,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(args);
|
||||
await this.exec(args, { env: { 'GIT_HTTP_USER_AGENT': this.git.userAgent } });
|
||||
} catch (err) {
|
||||
if (/^error: failed to push some refs to\b/m.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.PushRejected;
|
||||
@@ -1708,13 +1717,13 @@ export class Repository {
|
||||
|
||||
async cherryPick(commitHash: string): Promise<void> {
|
||||
const args = ['cherry-pick', commitHash];
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
}
|
||||
|
||||
async blame(path: string): Promise<string> {
|
||||
try {
|
||||
const args = ['blame', sanitizePath(path)];
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
return result.stdout.trim();
|
||||
} catch (err) {
|
||||
if (/^fatal: no such path/.test(err.stderr || '')) {
|
||||
@@ -1737,7 +1746,7 @@ export class Repository {
|
||||
args.push('-m', message);
|
||||
}
|
||||
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
} catch (err) {
|
||||
if (/No local changes to save/.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.NoLocalChanges;
|
||||
@@ -1763,7 +1772,7 @@ export class Repository {
|
||||
args.push(`stash@{${index}}`);
|
||||
}
|
||||
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
} catch (err) {
|
||||
if (/No stash found/.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.NoStashFound;
|
||||
@@ -1785,7 +1794,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
try {
|
||||
await this.run(args);
|
||||
await this.exec(args);
|
||||
} catch (err) {
|
||||
if (/No stash found/.test(err.stderr || '')) {
|
||||
err.gitErrorCode = GitErrorCodes.NoStashFound;
|
||||
@@ -1850,7 +1859,7 @@ export class Repository {
|
||||
|
||||
async getHEAD(): Promise<Ref> {
|
||||
try {
|
||||
const result = await this.run(['symbolic-ref', '--short', 'HEAD']);
|
||||
const result = await this.exec(['symbolic-ref', '--short', 'HEAD']);
|
||||
|
||||
if (!result.stdout) {
|
||||
throw new Error('Not in a branch');
|
||||
@@ -1858,7 +1867,7 @@ export class Repository {
|
||||
|
||||
return { name: result.stdout.trim(), commit: undefined, type: RefType.Head };
|
||||
} catch (err) {
|
||||
const result = await this.run(['rev-parse', 'HEAD']);
|
||||
const result = await this.exec(['rev-parse', 'HEAD']);
|
||||
|
||||
if (!result.stdout) {
|
||||
throw new Error('Error parsing HEAD');
|
||||
@@ -1869,7 +1878,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
async findTrackingBranches(upstreamBranch: string): Promise<Branch[]> {
|
||||
const result = await this.run(['for-each-ref', '--format', '%(refname:short)%00%(upstream:short)', 'refs/heads']);
|
||||
const result = await this.exec(['for-each-ref', '--format', '%(refname:short)%00%(upstream:short)', 'refs/heads']);
|
||||
return result.stdout.trim().split('\n')
|
||||
.map(line => line.trim().split('\0'))
|
||||
.filter(([_, upstream]) => upstream === upstreamBranch)
|
||||
@@ -1897,7 +1906,7 @@ export class Repository {
|
||||
args.push('--contains', opts.contains);
|
||||
}
|
||||
|
||||
const result = await this.run(args);
|
||||
const result = await this.exec(args);
|
||||
|
||||
const fn = (line: string): Ref | null => {
|
||||
let match: RegExpExecArray | null;
|
||||
@@ -1913,14 +1922,14 @@ export class Repository {
|
||||
return null;
|
||||
};
|
||||
|
||||
return result.stdout.trim().split('\n')
|
||||
return result.stdout.split('\n')
|
||||
.filter(line => !!line)
|
||||
.map(fn)
|
||||
.filter(ref => !!ref) as Ref[];
|
||||
}
|
||||
|
||||
async getStashes(): Promise<Stash[]> {
|
||||
const result = await this.run(['stash', 'list']);
|
||||
const result = await this.exec(['stash', 'list']);
|
||||
const regex = /^stash@{(\d+)}:(.+)$/;
|
||||
const rawStashes = result.stdout.trim().split('\n')
|
||||
.filter(b => !!b)
|
||||
@@ -1932,7 +1941,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
async getRemotes(): Promise<Remote[]> {
|
||||
const result = await this.run(['remote', '--verbose']);
|
||||
const result = await this.exec(['remote', '--verbose']);
|
||||
const lines = result.stdout.trim().split('\n').filter(l => !!l);
|
||||
const remotes: MutableRemote[] = [];
|
||||
|
||||
@@ -1968,50 +1977,59 @@ export class Repository {
|
||||
return this.getHEAD();
|
||||
}
|
||||
|
||||
let result = await this.run(['rev-parse', name]);
|
||||
|
||||
if (!result.stdout && /^@/.test(name)) {
|
||||
const symbolicFullNameResult = await this.run(['rev-parse', '--symbolic-full-name', name]);
|
||||
name = symbolicFullNameResult.stdout.trim();
|
||||
|
||||
result = await this.run(['rev-parse', name]);
|
||||
const args = ['for-each-ref', '--format=%(refname)%00%(upstream:short)%00%(upstream:track)%00%(objectname)'];
|
||||
if (/^refs\/(head|remotes)\//i.test(name)) {
|
||||
args.push(name);
|
||||
} else {
|
||||
args.push(`refs/heads/${name}`, `refs/remotes/${name}`);
|
||||
}
|
||||
|
||||
if (!result.stdout) {
|
||||
return Promise.reject<Branch>(new Error('No such branch'));
|
||||
}
|
||||
const result = await this.exec(args);
|
||||
const branches: Branch[] = result.stdout.trim().split('\n').map<Branch | undefined>(line => {
|
||||
let [branchName, upstream, status, ref] = line.trim().split('\0');
|
||||
|
||||
const commit = result.stdout.trim();
|
||||
if (branchName.startsWith('refs/heads/')) {
|
||||
branchName = branchName.substring(11);
|
||||
const index = upstream.indexOf('/');
|
||||
|
||||
try {
|
||||
const res2 = await this.run(['rev-parse', '--symbolic-full-name', name + '@{u}']);
|
||||
const fullUpstream = res2.stdout.trim();
|
||||
const match = /^refs\/remotes\/([^/]+)\/(.+)$/.exec(fullUpstream);
|
||||
|
||||
if (!match) {
|
||||
throw new Error(`Could not parse upstream branch: ${fullUpstream}`);
|
||||
}
|
||||
|
||||
const upstream = { remote: match[1], name: match[2] };
|
||||
const res3 = await this.run(['rev-list', '--left-right', name + '...' + fullUpstream]);
|
||||
|
||||
let ahead = 0, behind = 0;
|
||||
let i = 0;
|
||||
|
||||
while (i < res3.stdout.length) {
|
||||
switch (res3.stdout.charAt(i)) {
|
||||
case '<': ahead++; break;
|
||||
case '>': behind++; break;
|
||||
default: i++; break;
|
||||
let ahead;
|
||||
let behind;
|
||||
const match = /\[(?:ahead ([0-9]+))?[,\s]*(?:behind ([0-9]+))?]|\[gone]/.exec(status);
|
||||
if (match) {
|
||||
[, ahead, behind] = match;
|
||||
}
|
||||
|
||||
while (res3.stdout.charAt(i++) !== '\n') { /* no-op */ }
|
||||
}
|
||||
return {
|
||||
type: RefType.Head,
|
||||
name: branchName,
|
||||
upstream: upstream ? {
|
||||
name: upstream.substring(index + 1),
|
||||
remote: upstream.substring(0, index)
|
||||
} : undefined,
|
||||
commit: ref || undefined,
|
||||
ahead: Number(ahead) || 0,
|
||||
behind: Number(behind) || 0,
|
||||
};
|
||||
} else if (branchName.startsWith('refs/remotes/')) {
|
||||
branchName = branchName.substring(13);
|
||||
const index = branchName.indexOf('/');
|
||||
|
||||
return { name, type: RefType.Head, commit, upstream, ahead, behind };
|
||||
} catch (err) {
|
||||
return { name, type: RefType.Head, commit };
|
||||
return {
|
||||
type: RefType.RemoteHead,
|
||||
name: branchName.substring(index + 1),
|
||||
remote: branchName.substring(0, index),
|
||||
commit: ref,
|
||||
};
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}).filter((b?: Branch): b is Branch => !!b);
|
||||
|
||||
if (branches.length) {
|
||||
return branches[0];
|
||||
}
|
||||
|
||||
return Promise.reject<Branch>(new Error('No such branch'));
|
||||
}
|
||||
|
||||
async getBranches(query: BranchQuery): Promise<Ref[]> {
|
||||
@@ -2048,7 +2066,7 @@ export class Repository {
|
||||
|
||||
async getCommitTemplate(): Promise<string> {
|
||||
try {
|
||||
const result = await this.run(['config', '--get', 'commit.template']);
|
||||
const result = await this.exec(['config', '--get', 'commit.template']);
|
||||
|
||||
if (!result.stdout) {
|
||||
return '';
|
||||
@@ -2071,7 +2089,7 @@ export class Repository {
|
||||
}
|
||||
|
||||
async getCommit(ref: string): Promise<Commit> {
|
||||
const result = await this.run(['show', '-s', `--format=${COMMIT_FORMAT}`, '-z', ref]);
|
||||
const result = await this.exec(['show', '-s', `--format=${COMMIT_FORMAT}`, '-z', ref]);
|
||||
const commits = parseGitCommits(result.stdout);
|
||||
if (commits.length === 0) {
|
||||
return Promise.reject<Commit>('bad commit format');
|
||||
@@ -2083,7 +2101,7 @@ export class Repository {
|
||||
const args = ['submodule', 'update'];
|
||||
|
||||
for (const chunk of splitInChunks(paths.map(sanitizePath), MAX_CLI_LENGTH)) {
|
||||
await this.run([...args, '--', ...chunk]);
|
||||
await this.exec([...args, '--', ...chunk]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user