mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-14 03:58:33 -05:00
Initial VS Code 1.19 source merge (#571)
* Initial 1.19 xcopy * Fix yarn build * Fix numerous build breaks * Next batch of build break fixes * More build break fixes * Runtime breaks * Additional post merge fixes * Fix windows setup file * Fix test failures. * Update license header blocks to refer to source eula
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor } from 'vscode';
|
||||
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, CancellationTokenSource, StatusBarAlignment } from 'vscode';
|
||||
import { Ref, RefType, Git, GitErrorCodes, Branch } from './git';
|
||||
import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository';
|
||||
import { Model } from './model';
|
||||
@@ -127,6 +127,15 @@ function command(commandId: string, options: CommandOptions = {}): Function {
|
||||
};
|
||||
}
|
||||
|
||||
const ImageMimetypes = [
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/jpeg',
|
||||
'image/webp',
|
||||
'image/tiff',
|
||||
'image/bmp'
|
||||
];
|
||||
|
||||
export class CommandCenter {
|
||||
|
||||
private disposables: Disposable[];
|
||||
@@ -159,8 +168,8 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
private async _openResource(resource: Resource, preview?: boolean, preserveFocus?: boolean, preserveSelection?: boolean): Promise<void> {
|
||||
const left = this.getLeftResource(resource);
|
||||
const right = this.getRightResource(resource);
|
||||
const left = await this.getLeftResource(resource);
|
||||
const right = await this.getRightResource(resource);
|
||||
const title = this.getTitle(resource);
|
||||
|
||||
if (!right) {
|
||||
@@ -184,40 +193,77 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
if (!left) {
|
||||
const document = await workspace.openTextDocument(right);
|
||||
await window.showTextDocument(document, opts);
|
||||
return;
|
||||
await commands.executeCommand<void>('vscode.open', right, opts);
|
||||
} else {
|
||||
await commands.executeCommand<void>('vscode.diff', left, right, title, opts);
|
||||
}
|
||||
|
||||
return await commands.executeCommand<void>('vscode.diff', left, right, title, opts);
|
||||
}
|
||||
|
||||
private getLeftResource(resource: Resource): Uri | undefined {
|
||||
private async getURI(uri: Uri, ref: string): Promise<Uri | undefined> {
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
return toGitUri(uri, ref);
|
||||
}
|
||||
|
||||
try {
|
||||
let gitRef = ref;
|
||||
|
||||
if (gitRef === '~') {
|
||||
const uriString = uri.toString();
|
||||
const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString);
|
||||
gitRef = indexStatus ? '' : 'HEAD';
|
||||
}
|
||||
|
||||
const { size, object } = await repository.lstree(gitRef, uri.fsPath);
|
||||
const { mimetype, encoding } = await repository.detectObjectType(object);
|
||||
|
||||
if (mimetype === 'text/plain') {
|
||||
return toGitUri(uri, ref);
|
||||
}
|
||||
|
||||
if (size > 1000000) { // 1 MB
|
||||
return Uri.parse(`data:;label:${path.basename(uri.fsPath)};description:${gitRef},`);
|
||||
}
|
||||
|
||||
if (ImageMimetypes.indexOf(mimetype) > -1) {
|
||||
const contents = await repository.buffer(gitRef, uri.fsPath);
|
||||
return Uri.parse(`data:${mimetype};label:${path.basename(uri.fsPath)};description:${gitRef};size:${size};base64,${contents.toString('base64')}`);
|
||||
}
|
||||
|
||||
return Uri.parse(`data:;label:${path.basename(uri.fsPath)};description:${gitRef},`);
|
||||
|
||||
} catch (err) {
|
||||
return toGitUri(uri, ref);
|
||||
}
|
||||
}
|
||||
|
||||
private async getLeftResource(resource: Resource): Promise<Uri | undefined> {
|
||||
switch (resource.type) {
|
||||
case Status.INDEX_MODIFIED:
|
||||
case Status.INDEX_RENAMED:
|
||||
return toGitUri(resource.original, 'HEAD');
|
||||
return this.getURI(resource.original, 'HEAD');
|
||||
|
||||
case Status.MODIFIED:
|
||||
return toGitUri(resource.resourceUri, '~');
|
||||
return this.getURI(resource.resourceUri, '~');
|
||||
|
||||
case Status.DELETED_BY_THEM:
|
||||
return toGitUri(resource.resourceUri, '');
|
||||
return this.getURI(resource.resourceUri, '');
|
||||
}
|
||||
}
|
||||
|
||||
private getRightResource(resource: Resource): Uri | undefined {
|
||||
private async getRightResource(resource: Resource): Promise<Uri | undefined> {
|
||||
switch (resource.type) {
|
||||
case Status.INDEX_MODIFIED:
|
||||
case Status.INDEX_ADDED:
|
||||
case Status.INDEX_COPIED:
|
||||
case Status.INDEX_RENAMED:
|
||||
return toGitUri(resource.resourceUri, '');
|
||||
return this.getURI(resource.resourceUri, '');
|
||||
|
||||
case Status.INDEX_DELETED:
|
||||
case Status.DELETED_BY_THEM:
|
||||
case Status.DELETED:
|
||||
return toGitUri(resource.resourceUri, 'HEAD');
|
||||
return this.getURI(resource.resourceUri, 'HEAD');
|
||||
|
||||
case Status.MODIFIED:
|
||||
case Status.UNTRACKED:
|
||||
@@ -261,6 +307,8 @@ export class CommandCenter {
|
||||
return '';
|
||||
}
|
||||
|
||||
private static cloneId = 0;
|
||||
|
||||
@command('git.clone')
|
||||
async clone(url?: string): Promise<void> {
|
||||
if (!url) {
|
||||
@@ -281,7 +329,8 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
const value = config.get<string>('defaultCloneDirectory') || os.homedir();
|
||||
let value = config.get<string>('defaultCloneDirectory') || os.homedir();
|
||||
value = value.replace(/^~/, os.homedir());
|
||||
|
||||
const parentPath = await window.showInputBox({
|
||||
prompt: localize('parent', "Parent Directory"),
|
||||
@@ -299,12 +348,21 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
const clonePromise = this.git.clone(url, parentPath);
|
||||
const tokenSource = new CancellationTokenSource();
|
||||
const cancelCommandId = `cancelClone${CommandCenter.cloneId++}`;
|
||||
const commandDisposable = commands.registerCommand(cancelCommandId, () => tokenSource.cancel());
|
||||
|
||||
const statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
|
||||
statusBarItem.text = localize('cancel', "$(sync~spin) Cloning repository... Click to cancel");
|
||||
statusBarItem.tooltip = localize('cancel tooltip', "Cancel clone");
|
||||
statusBarItem.command = cancelCommandId;
|
||||
statusBarItem.show();
|
||||
|
||||
const clonePromise = this.git.clone(url, parentPath, tokenSource.token);
|
||||
|
||||
try {
|
||||
window.withProgress({ location: ProgressLocation.SourceControl, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
|
||||
window.withProgress({ location: ProgressLocation.Window, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
|
||||
// window.withProgress({ location: ProgressLocation.Window, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
|
||||
|
||||
const repositoryPath = await clonePromise;
|
||||
|
||||
@@ -330,6 +388,8 @@ export class CommandCenter {
|
||||
}
|
||||
*/
|
||||
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'directory_not_empty' });
|
||||
} else if (/Cancelled/i.test(err && (err.message || err.stderr || ''))) {
|
||||
return;
|
||||
} else {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
@@ -338,41 +398,62 @@ export class CommandCenter {
|
||||
*/
|
||||
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'error' });
|
||||
}
|
||||
|
||||
throw err;
|
||||
} finally {
|
||||
commandDisposable.dispose();
|
||||
statusBarItem.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.init')
|
||||
async init(): Promise<void> {
|
||||
const homeUri = Uri.file(os.homedir());
|
||||
const defaultUri = workspace.workspaceFolders && workspace.workspaceFolders.length > 0
|
||||
? Uri.file(workspace.workspaceFolders[0].uri.fsPath)
|
||||
: homeUri;
|
||||
let path: string | undefined;
|
||||
|
||||
const result = await window.showOpenDialog({
|
||||
canSelectFiles: false,
|
||||
canSelectFolders: true,
|
||||
canSelectMany: false,
|
||||
defaultUri,
|
||||
openLabel: localize('init repo', "Initialize Repository")
|
||||
});
|
||||
if (workspace.workspaceFolders && workspace.workspaceFolders.length > 1) {
|
||||
const placeHolder = localize('init', "Pick workspace folder to initialize git repo in");
|
||||
const items = workspace.workspaceFolders.map(folder => ({ label: folder.name, description: folder.uri.fsPath, folder }));
|
||||
const item = await window.showQuickPick(items, { placeHolder, ignoreFocusOut: true });
|
||||
|
||||
if (!result || result.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uri = result[0];
|
||||
|
||||
if (homeUri.toString().startsWith(uri.toString())) {
|
||||
const yes = localize('create repo', "Initialize Repository");
|
||||
const answer = await window.showWarningMessage(localize('are you sure', "This will create a Git repository in '{0}'. Are you sure you want to continue?", uri.fsPath), yes);
|
||||
|
||||
if (answer !== yes) {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
path = item.folder.uri.fsPath;
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
const homeUri = Uri.file(os.homedir());
|
||||
const defaultUri = workspace.workspaceFolders && workspace.workspaceFolders.length > 0
|
||||
? Uri.file(workspace.workspaceFolders[0].uri.fsPath)
|
||||
: homeUri;
|
||||
|
||||
const result = await window.showOpenDialog({
|
||||
canSelectFiles: false,
|
||||
canSelectFolders: true,
|
||||
canSelectMany: false,
|
||||
defaultUri,
|
||||
openLabel: localize('init repo', "Initialize Repository")
|
||||
});
|
||||
|
||||
if (!result || result.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const uri = result[0];
|
||||
|
||||
if (homeUri.toString().startsWith(uri.toString())) {
|
||||
const yes = localize('create repo', "Initialize Repository");
|
||||
const answer = await window.showWarningMessage(localize('are you sure', "This will create a Git repository in '{0}'. Are you sure you want to continue?", uri.fsPath), yes);
|
||||
|
||||
if (answer !== yes) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
path = uri.fsPath;
|
||||
}
|
||||
|
||||
const path = uri.fsPath;
|
||||
await this.git.init(path);
|
||||
await this.model.tryOpenRepository(path);
|
||||
}
|
||||
@@ -426,8 +507,7 @@ export class CommandCenter {
|
||||
opts.selection = activeTextEditor.selection;
|
||||
}
|
||||
|
||||
const document = await workspace.openTextDocument(uri);
|
||||
await window.showTextDocument(document, opts);
|
||||
await commands.executeCommand<void>('vscode.open', uri, opts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,7 +527,7 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
const HEAD = this.getLeftResource(resource);
|
||||
const HEAD = await this.getLeftResource(resource);
|
||||
|
||||
if (!HEAD) {
|
||||
window.showWarningMessage(localize('HEAD not available', "HEAD version of '{0}' is not available.", path.basename(resource.resourceUri.fsPath)));
|
||||
@@ -494,7 +574,7 @@ export class CommandCenter {
|
||||
|
||||
@command('git.stage')
|
||||
async stage(...resourceStates: SourceControlResourceState[]): Promise<void> {
|
||||
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
|
||||
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
|
||||
const resource = this.getSCMResource();
|
||||
|
||||
if (!resource) {
|
||||
@@ -671,7 +751,7 @@ export class CommandCenter {
|
||||
|
||||
@command('git.unstage')
|
||||
async unstage(...resourceStates: SourceControlResourceState[]): Promise<void> {
|
||||
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
|
||||
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
|
||||
const resource = this.getSCMResource();
|
||||
|
||||
if (!resource) {
|
||||
@@ -737,7 +817,7 @@ export class CommandCenter {
|
||||
|
||||
@command('git.clean')
|
||||
async clean(...resourceStates: SourceControlResourceState[]): Promise<void> {
|
||||
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
|
||||
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
|
||||
const resource = this.getSCMResource();
|
||||
|
||||
if (!resource) {
|
||||
@@ -917,6 +997,7 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
return await window.showInputBox({
|
||||
value: opts && opts.defaultMsg,
|
||||
placeHolder: localize('commit message', "Commit message"),
|
||||
prompt: localize('provide commit message', "Please provide a commit message"),
|
||||
ignoreFocusOut: true
|
||||
@@ -960,7 +1041,15 @@ export class CommandCenter {
|
||||
|
||||
@command('git.commitStagedAmend', { repository: true })
|
||||
async commitStagedAmend(repository: Repository): Promise<void> {
|
||||
await this.commitWithAnyInput(repository, { all: false, amend: true });
|
||||
let msg;
|
||||
if (repository.HEAD) {
|
||||
if (repository.HEAD.commit) {
|
||||
let id = repository.HEAD.commit;
|
||||
let commit = await repository.getCommit(id);
|
||||
msg = commit.message;
|
||||
}
|
||||
}
|
||||
await this.commitWithAnyInput(repository, { all: false, amend: true, defaultMsg: msg });
|
||||
}
|
||||
|
||||
@command('git.commitAll', { repository: true })
|
||||
@@ -1077,6 +1166,31 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.renameBranch', { repository: true })
|
||||
async renameBranch(repository: Repository): Promise<void> {
|
||||
const placeHolder = localize('provide branch name', "Please provide a branch name");
|
||||
const name = await window.showInputBox({ placeHolder });
|
||||
|
||||
if (!name || name.trim().length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await repository.renameBranch(name);
|
||||
} catch (err) {
|
||||
switch (err.gitErrorCode) {
|
||||
case GitErrorCodes.InvalidBranchName:
|
||||
window.showErrorMessage(localize('invalid branch name', 'Invalid branch name'));
|
||||
return;
|
||||
case GitErrorCodes.BranchAlreadyExists:
|
||||
window.showErrorMessage(localize('branch already exists', "A branch named '{0}' already exists", name));
|
||||
return;
|
||||
default:
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.merge', { repository: true })
|
||||
async merge(repository: Repository): Promise<void> {
|
||||
const config = workspace.getConfiguration('git');
|
||||
@@ -1134,6 +1248,16 @@ export class CommandCenter {
|
||||
await repository.tag(name, message);
|
||||
}
|
||||
|
||||
@command('git.fetch', { repository: true })
|
||||
async fetch(repository: Repository): Promise<void> {
|
||||
if (repository.remotes.length === 0) {
|
||||
window.showWarningMessage(localize('no remotes to fetch', "This repository has no remotes configured to fetch from."));
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.fetch();
|
||||
}
|
||||
|
||||
@command('git.pullFrom', { repository: true })
|
||||
async pullFrom(repository: Repository): Promise<void> {
|
||||
const remotes = repository.remotes;
|
||||
@@ -1240,8 +1364,7 @@ export class CommandCenter {
|
||||
repository.pushTo(pick.label, branchName);
|
||||
}
|
||||
|
||||
@command('git.sync', { repository: true })
|
||||
async sync(repository: Repository): Promise<void> {
|
||||
private async _sync(repository: Repository, rebase: boolean): Promise<void> {
|
||||
const HEAD = repository.HEAD;
|
||||
|
||||
if (!HEAD || !HEAD.upstream) {
|
||||
@@ -1264,7 +1387,16 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
await repository.sync();
|
||||
if (rebase) {
|
||||
await repository.syncRebase();
|
||||
} else {
|
||||
await repository.sync();
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.sync', { repository: true })
|
||||
sync(repository: Repository): Promise<void> {
|
||||
return this._sync(repository, false);
|
||||
}
|
||||
|
||||
@command('git._syncAll')
|
||||
@@ -1280,6 +1412,11 @@ export class CommandCenter {
|
||||
}));
|
||||
}
|
||||
|
||||
@command('git.syncRebase', { repository: true })
|
||||
syncRebase(repository: Repository): Promise<void> {
|
||||
return this._sync(repository, true);
|
||||
}
|
||||
|
||||
@command('git.publish', { repository: true })
|
||||
async publish(repository: Repository): Promise<void> {
|
||||
const remotes = repository.remotes;
|
||||
@@ -1304,14 +1441,9 @@ export class CommandCenter {
|
||||
await repository.pushTo(choice, branchName, true);
|
||||
}
|
||||
|
||||
@command('git.showOutput')
|
||||
showOutput(): void {
|
||||
this.outputChannel.show();
|
||||
}
|
||||
|
||||
@command('git.ignore')
|
||||
async ignore(...resourceStates: SourceControlResourceState[]): Promise<void> {
|
||||
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
|
||||
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
|
||||
const resource = this.getSCMResource();
|
||||
|
||||
if (!resource) {
|
||||
@@ -1332,23 +1464,36 @@ export class CommandCenter {
|
||||
await this.runByRepository(resources, async (repository, resources) => repository.ignore(resources));
|
||||
}
|
||||
|
||||
@command('git.stash', { repository: true })
|
||||
async stash(repository: Repository): Promise<void> {
|
||||
private async _stash(repository: Repository, includeUntracked = false): Promise<void> {
|
||||
if (repository.workingTreeGroup.resourceStates.length === 0) {
|
||||
window.showInformationMessage(localize('no changes stash', "There are no changes to stash."));
|
||||
return;
|
||||
}
|
||||
|
||||
const message = await window.showInputBox({
|
||||
prompt: localize('provide stash message', "Optionally provide a stash message"),
|
||||
placeHolder: localize('stash message', "Stash message")
|
||||
});
|
||||
const message = await this.getStashMessage();
|
||||
|
||||
if (typeof message === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.createStash(message);
|
||||
await repository.createStash(message, includeUntracked);
|
||||
}
|
||||
|
||||
private async getStashMessage(): Promise<string | undefined> {
|
||||
return await window.showInputBox({
|
||||
prompt: localize('provide stash message', "Optionally provide a stash message"),
|
||||
placeHolder: localize('stash message', "Stash message")
|
||||
});
|
||||
}
|
||||
|
||||
@command('git.stash', { repository: true })
|
||||
stash(repository: Repository): Promise<void> {
|
||||
return this._stash(repository);
|
||||
}
|
||||
|
||||
@command('git.stashIncludeUntracked', { repository: true })
|
||||
stashIncludeUntracked(repository: Repository): Promise<void> {
|
||||
return this._stash(repository, true);
|
||||
}
|
||||
|
||||
@command('git.stashPop', { repository: true })
|
||||
@@ -1384,7 +1529,7 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any {
|
||||
const result = (...args) => {
|
||||
const result = (...args: any[]) => {
|
||||
let result: Promise<any>;
|
||||
|
||||
if (!options.repository) {
|
||||
@@ -1426,14 +1571,14 @@ export class CommandCenter {
|
||||
message = localize('clean repo', "Please clean your repository working tree before checkout.");
|
||||
break;
|
||||
case GitErrorCodes.PushRejected:
|
||||
message = localize('cant push', "Can't push refs to remote. Run 'Pull' first to integrate your changes.");
|
||||
message = localize('cant push', "Can't push refs to remote. Try running 'Pull' first to integrate your changes.");
|
||||
break;
|
||||
default:
|
||||
const hint = (err.stderr || err.message || String(err))
|
||||
.replace(/^error: /mi, '')
|
||||
.replace(/^> husky.*$/mi, '')
|
||||
.split(/[\r\n]/)
|
||||
.filter(line => !!line)
|
||||
.filter((line: string) => !!line)
|
||||
[0];
|
||||
|
||||
message = hint
|
||||
@@ -1459,7 +1604,7 @@ export class CommandCenter {
|
||||
};
|
||||
|
||||
// patch this object, so people can call methods directly
|
||||
this[key] = result;
|
||||
(this as any)[key] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1523,4 +1668,4 @@ export class CommandCenter {
|
||||
dispose(): void {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user