mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-30 17:23:29 -05:00
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:
@@ -3,19 +3,19 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, MessageOptions, WorkspaceFolder } from 'vscode';
|
||||
import { Git, CommitOptions, Stash, ForcePushMode } from './git';
|
||||
import { Repository, Resource, ResourceGroupType } from './repository';
|
||||
import { Model } from './model';
|
||||
import { toGitUri, fromGitUri } from './uri';
|
||||
import { grep, isDescendant, pathEquals } from './util';
|
||||
import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange, getModifiedRange } from './staging';
|
||||
import * as path from 'path';
|
||||
import { lstat, Stats } from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder } from 'vscode';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Ref, RefType, Branch, GitErrorCodes, Status } from './api/git';
|
||||
import { Branch, GitErrorCodes, Ref, RefType, Status } from './api/git';
|
||||
import { CommitOptions, ForcePushMode, Git, Stash } from './git';
|
||||
import { Model } from './model';
|
||||
import { Repository, Resource, ResourceGroupType } from './repository';
|
||||
import { applyLineChanges, getModifiedRange, intersectDiffWithRange, invertLineChange, toLineRanges } from './staging';
|
||||
import { fromGitUri, toGitUri, isGitUri } from './uri';
|
||||
import { grep, isDescendant, pathEquals } from './util';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -99,7 +99,7 @@ class CreateBranchItem implements QuickPickItem {
|
||||
|
||||
constructor(private cc: CommandCenter) { }
|
||||
|
||||
get label(): string { return localize('create branch', '$(plus) Create new branch...'); }
|
||||
get label(): string { return '$(plus) ' + localize('create branch', 'Create new branch...'); }
|
||||
get description(): string { return ''; }
|
||||
|
||||
get alwaysShow(): boolean { return true; }
|
||||
@@ -113,7 +113,7 @@ class CreateBranchFromItem implements QuickPickItem {
|
||||
|
||||
constructor(private cc: CommandCenter) { }
|
||||
|
||||
get label(): string { return localize('create branch from', '$(plus) Create new branch from...'); }
|
||||
get label(): string { return '$(plus) ' + localize('create branch from', 'Create new branch from...'); }
|
||||
get description(): string { return ''; }
|
||||
|
||||
get alwaysShow(): boolean { return true; }
|
||||
@@ -136,7 +136,7 @@ class AddRemoteItem implements QuickPickItem {
|
||||
|
||||
constructor(private cc: CommandCenter) { }
|
||||
|
||||
get label(): string { return localize('add remote', '$(plus) Add a new remote...'); }
|
||||
get label(): string { return '$(plus) ' + localize('add remote', 'Add a new remote...'); }
|
||||
get description(): string { return ''; }
|
||||
|
||||
get alwaysShow(): boolean { return true; }
|
||||
@@ -170,14 +170,14 @@ function command(commandId: string, options: CommandOptions = {}): Function {
|
||||
};
|
||||
}
|
||||
|
||||
const ImageMimetypes = [
|
||||
'image/png',
|
||||
'image/gif',
|
||||
'image/jpeg',
|
||||
'image/webp',
|
||||
'image/tiff',
|
||||
'image/bmp'
|
||||
];
|
||||
// const ImageMimetypes = [
|
||||
// 'image/png',
|
||||
// 'image/gif',
|
||||
// 'image/jpeg',
|
||||
// 'image/webp',
|
||||
// 'image/tiff',
|
||||
// 'image/bmp'
|
||||
// ];
|
||||
|
||||
async function categorizeResourceByResolution(resources: Resource[]): Promise<{ merge: Resource[], resolved: Resource[], unresolved: Resource[], deletionConflicts: Resource[] }> {
|
||||
const selection = resources.filter(s => s instanceof Resource) as Resource[];
|
||||
@@ -213,6 +213,12 @@ function createCheckoutItems(repository: Repository): CheckoutItem[] {
|
||||
return [...heads, ...tags, ...remoteHeads];
|
||||
}
|
||||
|
||||
class TagItem implements QuickPickItem {
|
||||
get label(): string { return this.ref.name ?? ''; }
|
||||
get description(): string { return this.ref.commit?.substr(0, 8) ?? ''; }
|
||||
constructor(readonly ref: Ref) { }
|
||||
}
|
||||
|
||||
enum PushType {
|
||||
Push,
|
||||
PushTo,
|
||||
@@ -289,10 +295,10 @@ export class CommandCenter {
|
||||
}
|
||||
} else {
|
||||
if (resource.type !== Status.DELETED_BY_THEM) {
|
||||
left = await this.getLeftResource(resource);
|
||||
left = this.getLeftResource(resource);
|
||||
}
|
||||
|
||||
right = await this.getRightResource(resource);
|
||||
right = this.getRightResource(resource);
|
||||
}
|
||||
|
||||
const title = this.getTitle(resource);
|
||||
@@ -324,79 +330,40 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
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.getObjectDetails(gitRef, uri.fsPath);
|
||||
const { mimetype } = 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> {
|
||||
private getLeftResource(resource: Resource): Uri | undefined {
|
||||
switch (resource.type) {
|
||||
case Status.INDEX_MODIFIED:
|
||||
case Status.INDEX_RENAMED:
|
||||
case Status.INDEX_ADDED:
|
||||
return this.getURI(resource.original, 'HEAD');
|
||||
return toGitUri(resource.original, 'HEAD');
|
||||
|
||||
case Status.MODIFIED:
|
||||
case Status.UNTRACKED:
|
||||
return this.getURI(resource.resourceUri, '~');
|
||||
return toGitUri(resource.resourceUri, '~');
|
||||
|
||||
case Status.DELETED_BY_THEM:
|
||||
return this.getURI(resource.resourceUri, '');
|
||||
return toGitUri(resource.resourceUri, '');
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private async getRightResource(resource: Resource): Promise<Uri | undefined> {
|
||||
private getRightResource(resource: Resource): Uri | undefined {
|
||||
switch (resource.type) {
|
||||
case Status.INDEX_MODIFIED:
|
||||
case Status.INDEX_ADDED:
|
||||
case Status.INDEX_COPIED:
|
||||
case Status.INDEX_RENAMED:
|
||||
return this.getURI(resource.resourceUri, '');
|
||||
return toGitUri(resource.resourceUri, '');
|
||||
|
||||
case Status.INDEX_DELETED:
|
||||
case Status.DELETED:
|
||||
return this.getURI(resource.resourceUri, 'HEAD');
|
||||
return toGitUri(resource.resourceUri, 'HEAD');
|
||||
|
||||
case Status.DELETED_BY_US:
|
||||
return this.getURI(resource.resourceUri, '~3');
|
||||
return toGitUri(resource.resourceUri, '~3');
|
||||
|
||||
case Status.DELETED_BY_THEM:
|
||||
return this.getURI(resource.resourceUri, '~2');
|
||||
return toGitUri(resource.resourceUri, '~2');
|
||||
|
||||
case Status.MODIFIED:
|
||||
case Status.UNTRACKED:
|
||||
@@ -453,7 +420,7 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
@command('git.clone')
|
||||
async clone(url?: string): Promise<void> {
|
||||
async clone(url?: string, parentPath?: string): Promise<void> {
|
||||
if (!url) {
|
||||
url = await window.showInputBox({
|
||||
prompt: localize('repourl', "Repository URL"),
|
||||
@@ -473,31 +440,33 @@ export class CommandCenter {
|
||||
|
||||
url = url.trim().replace(/^git\s+clone\s+/, '');
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
let defaultCloneDirectory = config.get<string>('defaultCloneDirectory') || os.homedir();
|
||||
defaultCloneDirectory = defaultCloneDirectory.replace(/^~/, os.homedir());
|
||||
if (!parentPath) {
|
||||
const config = workspace.getConfiguration('git');
|
||||
let defaultCloneDirectory = config.get<string>('defaultCloneDirectory') || os.homedir();
|
||||
defaultCloneDirectory = defaultCloneDirectory.replace(/^~/, os.homedir());
|
||||
|
||||
const uris = await window.showOpenDialog({
|
||||
canSelectFiles: false,
|
||||
canSelectFolders: true,
|
||||
canSelectMany: false,
|
||||
defaultUri: Uri.file(defaultCloneDirectory),
|
||||
openLabel: localize('selectFolder', "Select Repository Location")
|
||||
});
|
||||
const uris = await window.showOpenDialog({
|
||||
canSelectFiles: false,
|
||||
canSelectFolders: true,
|
||||
canSelectMany: false,
|
||||
defaultUri: Uri.file(defaultCloneDirectory),
|
||||
openLabel: localize('selectFolder', "Select Repository Location")
|
||||
});
|
||||
|
||||
if (!uris || uris.length === 0) {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_directory' });
|
||||
return;
|
||||
if (!uris || uris.length === 0) {
|
||||
/* __GDPR__
|
||||
"clone" : {
|
||||
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'no_directory' });
|
||||
return;
|
||||
}
|
||||
|
||||
const uri = uris[0];
|
||||
parentPath = uri.fsPath;
|
||||
}
|
||||
|
||||
const uri = uris[0];
|
||||
const parentPath = uri.fsPath;
|
||||
|
||||
try {
|
||||
const opts = {
|
||||
location: ProgressLocation.Notification,
|
||||
@@ -507,7 +476,7 @@ export class CommandCenter {
|
||||
|
||||
const repositoryPath = await window.withProgress(
|
||||
opts,
|
||||
(progress, token) => this.git.clone(url!, parentPath, progress, token)
|
||||
(progress, token) => this.git.clone(url!, parentPath!, progress, token)
|
||||
);
|
||||
|
||||
let message = localize('proposeopen', "Would you like to open the cloned repository?");
|
||||
@@ -686,7 +655,7 @@ export class CommandCenter {
|
||||
let uris: Uri[] | undefined;
|
||||
|
||||
if (arg instanceof Uri) {
|
||||
if (arg.scheme === 'git') {
|
||||
if (isGitUri(arg)) {
|
||||
uris = [Uri.file(fromGitUri(arg).path)];
|
||||
} else if (arg.scheme === 'file') {
|
||||
uris = [arg];
|
||||
@@ -765,7 +734,7 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
const HEAD = await this.getLeftResource(resource);
|
||||
const HEAD = this.getLeftResource(resource);
|
||||
const basename = path.basename(resource.resourceUri.fsPath);
|
||||
const title = `${basename} (HEAD)`;
|
||||
|
||||
@@ -866,7 +835,8 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
const workingTree = selection.filter(s => s.resourceGroupType === ResourceGroupType.WorkingTree);
|
||||
const scmResources = [...workingTree, ...resolved, ...unresolved];
|
||||
const untracked = selection.filter(s => s.resourceGroupType === ResourceGroupType.Untracked);
|
||||
const scmResources = [...workingTree, ...untracked, ...resolved, ...unresolved];
|
||||
|
||||
this.outputChannel.appendLine(`git.stage.scmResources ${scmResources.length}`);
|
||||
if (!scmResources.length) {
|
||||
@@ -907,7 +877,9 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
await repository.add([]);
|
||||
const config = workspace.getConfiguration('git', Uri.file(repository.root));
|
||||
const untrackedChanges = config.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges');
|
||||
await repository.add([], untrackedChanges === 'mixed' ? undefined : { update: true });
|
||||
}
|
||||
|
||||
private async _stageDeletionConflict(repository: Repository, uri: Uri): Promise<void> {
|
||||
@@ -945,6 +917,24 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.stageAllTracked', { repository: true })
|
||||
async stageAllTracked(repository: Repository): Promise<void> {
|
||||
const resources = repository.workingTreeGroup.resourceStates
|
||||
.filter(r => r.type !== Status.UNTRACKED && r.type !== Status.IGNORED);
|
||||
const uris = resources.map(r => r.resourceUri);
|
||||
|
||||
await repository.add(uris);
|
||||
}
|
||||
|
||||
@command('git.stageAllUntracked', { repository: true })
|
||||
async stageAllUntracked(repository: Repository): Promise<void> {
|
||||
const resources = [...repository.workingTreeGroup.resourceStates, ...repository.untrackedGroup.resourceStates]
|
||||
.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED);
|
||||
const uris = resources.map(r => r.resourceUri);
|
||||
|
||||
await repository.add(uris);
|
||||
}
|
||||
|
||||
@command('git.stageChange')
|
||||
async stageChange(uri: Uri, changes: LineChange[], index: number): Promise<void> {
|
||||
const textEditor = window.visibleTextEditors.filter(e => e.document.uri.toString() === uri.toString())[0];
|
||||
@@ -1090,7 +1080,7 @@ export class CommandCenter {
|
||||
const modifiedDocument = textEditor.document;
|
||||
const modifiedUri = modifiedDocument.uri;
|
||||
|
||||
if (modifiedUri.scheme !== 'git') {
|
||||
if (!isGitUri(modifiedUri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1131,8 +1121,8 @@ export class CommandCenter {
|
||||
resourceStates = [resource];
|
||||
}
|
||||
|
||||
const scmResources = resourceStates
|
||||
.filter(s => s instanceof Resource && s.resourceGroupType === ResourceGroupType.WorkingTree) as Resource[];
|
||||
const scmResources = resourceStates.filter(s => s instanceof Resource
|
||||
&& (s.resourceGroupType === ResourceGroupType.WorkingTree || s.resourceGroupType === ResourceGroupType.Untracked)) as Resource[];
|
||||
|
||||
if (!scmResources.length) {
|
||||
return;
|
||||
@@ -1189,41 +1179,11 @@ export class CommandCenter {
|
||||
const untrackedResources = resources.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED);
|
||||
|
||||
if (untrackedResources.length === 0) {
|
||||
const message = resources.length === 1
|
||||
? localize('confirm discard all single', "Are you sure you want to discard changes in {0}?", path.basename(resources[0].resourceUri.fsPath))
|
||||
: localize('confirm discard all', "Are you sure you want to discard ALL changes in {0} files?\nThis is IRREVERSIBLE!\nYour current working set will be FOREVER LOST.", resources.length);
|
||||
const yes = resources.length === 1
|
||||
? localize('discardAll multiple', "Discard 1 File")
|
||||
: localize('discardAll', "Discard All {0} Files", resources.length);
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
return;
|
||||
await this._cleanTrackedChanges(repository, resources);
|
||||
} else if (resources.length === 1) {
|
||||
const message = localize('confirm delete', "Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST.", path.basename(resources[0].resourceUri.fsPath));
|
||||
const yes = localize('delete file', "Delete file");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
await this._cleanUntrackedChange(repository, resources[0]);
|
||||
} else if (trackedResources.length === 0) {
|
||||
const message = localize('confirm delete multiple', "Are you sure you want to DELETE {0} files?", resources.length);
|
||||
const yes = localize('delete files', "Delete Files");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
|
||||
await this._cleanUntrackedChanges(repository, resources);
|
||||
} else { // resources.length > 1 && untrackedResources.length > 0 && trackedResources.length > 0
|
||||
const untrackedMessage = untrackedResources.length === 1
|
||||
? localize('there are untracked files single', "The following untracked file will be DELETED FROM DISK if discarded: {0}.", path.basename(untrackedResources[0].resourceUri.fsPath))
|
||||
@@ -1248,6 +1208,74 @@ export class CommandCenter {
|
||||
}
|
||||
}
|
||||
|
||||
@command('git.cleanAllTracked', { repository: true })
|
||||
async cleanAllTracked(repository: Repository): Promise<void> {
|
||||
const resources = repository.workingTreeGroup.resourceStates
|
||||
.filter(r => r.type !== Status.UNTRACKED && r.type !== Status.IGNORED);
|
||||
|
||||
if (resources.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this._cleanTrackedChanges(repository, resources);
|
||||
}
|
||||
|
||||
@command('git.cleanAllUntracked', { repository: true })
|
||||
async cleanAllUntracked(repository: Repository): Promise<void> {
|
||||
const resources = [...repository.workingTreeGroup.resourceStates, ...repository.untrackedGroup.resourceStates]
|
||||
.filter(r => r.type === Status.UNTRACKED || r.type === Status.IGNORED);
|
||||
|
||||
if (resources.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (resources.length === 1) {
|
||||
await this._cleanUntrackedChange(repository, resources[0]);
|
||||
} else {
|
||||
await this._cleanUntrackedChanges(repository, resources);
|
||||
}
|
||||
}
|
||||
|
||||
private async _cleanTrackedChanges(repository: Repository, resources: Resource[]): Promise<void> {
|
||||
const message = resources.length === 1
|
||||
? localize('confirm discard all single', "Are you sure you want to discard changes in {0}?", path.basename(resources[0].resourceUri.fsPath))
|
||||
: localize('confirm discard all', "Are you sure you want to discard ALL changes in {0} files?\nThis is IRREVERSIBLE!\nYour current working set will be FOREVER LOST.", resources.length);
|
||||
const yes = resources.length === 1
|
||||
? localize('discardAll multiple', "Discard 1 File")
|
||||
: localize('discardAll', "Discard All {0} Files", resources.length);
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
}
|
||||
|
||||
private async _cleanUntrackedChange(repository: Repository, resource: Resource): Promise<void> {
|
||||
const message = localize('confirm delete', "Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST.", path.basename(resource.resourceUri.fsPath));
|
||||
const yes = localize('delete file', "Delete file");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean([resource.resourceUri]);
|
||||
}
|
||||
|
||||
private async _cleanUntrackedChanges(repository: Repository, resources: Resource[]): Promise<void> {
|
||||
const message = localize('confirm delete multiple', "Are you sure you want to DELETE {0} files?", resources.length);
|
||||
const yes = localize('delete files', "Delete Files");
|
||||
const pick = await window.showWarningMessage(message, { modal: true }, yes);
|
||||
|
||||
if (pick !== yes) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.clean(resources.map(r => r.resourceUri));
|
||||
}
|
||||
|
||||
private async smartCommit(
|
||||
repository: Repository,
|
||||
getCommitMessage: () => Promise<string | undefined>,
|
||||
@@ -1271,7 +1299,7 @@ export class CommandCenter {
|
||||
|
||||
if (promptToSaveFilesBeforeCommit === 'staged' || repository.indexGroup.resourceStates.length > 0) {
|
||||
documents = documents
|
||||
.filter(d => repository.indexGroup.resourceStates.some(s => s.resourceUri.path === d.uri.fsPath));
|
||||
.filter(d => repository.indexGroup.resourceStates.some(s => pathEquals(s.resourceUri.fsPath, d.uri.fsPath)));
|
||||
}
|
||||
|
||||
if (documents.length > 0) {
|
||||
@@ -1356,6 +1384,10 @@ export class CommandCenter {
|
||||
opts.all = 'tracked';
|
||||
}
|
||||
|
||||
if (opts.all && config.get<'mixed' | 'separate' | 'hidden'>('untrackedChanges') !== 'mixed') {
|
||||
opts.all = 'tracked';
|
||||
}
|
||||
|
||||
await repository.commit(message, opts);
|
||||
|
||||
const postCommitCommand = config.get<'none' | 'push' | 'sync'>('postCommitCommand');
|
||||
@@ -1376,6 +1408,7 @@ export class CommandCenter {
|
||||
const message = repository.inputBox.value;
|
||||
const getCommitMessage = async () => {
|
||||
let _message: string | undefined = message;
|
||||
|
||||
if (!_message) {
|
||||
let value: string | undefined = undefined;
|
||||
|
||||
@@ -1400,7 +1433,7 @@ export class CommandCenter {
|
||||
});
|
||||
}
|
||||
|
||||
return _message ? repository.cleanUpCommitEditMessage(_message) : _message;
|
||||
return _message;
|
||||
};
|
||||
|
||||
const didCommit = await this.smartCommit(repository, getCommitMessage, opts);
|
||||
@@ -1485,7 +1518,7 @@ export class CommandCenter {
|
||||
|
||||
if (commit.parents.length > 1) {
|
||||
const yes = localize('undo commit', "Undo merge commit");
|
||||
const result = await window.showWarningMessage(localize('merge commit', "The last commit was a merge commit. Are you sure you want to undo it?"), yes);
|
||||
const result = await window.showWarningMessage(localize('merge commit', "The last commit was a merge commit. Are you sure you want to undo it?"), { modal: true }, yes);
|
||||
|
||||
if (result !== yes) {
|
||||
return;
|
||||
@@ -1705,6 +1738,26 @@ export class CommandCenter {
|
||||
await repository.tag(name, message);
|
||||
}
|
||||
|
||||
@command('git.deleteTag', { repository: true })
|
||||
async deleteTag(repository: Repository): Promise<void> {
|
||||
const picks = repository.refs.filter(ref => ref.type === RefType.Tag)
|
||||
.map(ref => new TagItem(ref));
|
||||
|
||||
if (picks.length === 0) {
|
||||
window.showWarningMessage(localize('no tags', "This repository has no tags."));
|
||||
return;
|
||||
}
|
||||
|
||||
const placeHolder = localize('select a tag to delete', 'Select a tag to delete');
|
||||
const choice = await window.showQuickPick(picks, { placeHolder });
|
||||
|
||||
if (!choice) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.deleteTag(choice.label);
|
||||
}
|
||||
|
||||
@command('git.fetch', { repository: true })
|
||||
async fetch(repository: Repository): Promise<void> {
|
||||
if (repository.remotes.length === 0) {
|
||||
@@ -2073,9 +2126,14 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
const branchName = repository.HEAD && repository.HEAD.name || '';
|
||||
|
||||
if (remotes.length === 1) {
|
||||
return await repository.pushTo(remotes[0].name, branchName, true);
|
||||
}
|
||||
|
||||
const addRemote = new AddRemoteItem(this);
|
||||
const picks = [...repository.remotes.map(r => ({ label: r.name, description: r.pushUrl })), addRemote];
|
||||
const branchName = repository.HEAD && repository.HEAD.name || '';
|
||||
const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName);
|
||||
const choice = await window.showQuickPick(picks, { placeHolder });
|
||||
|
||||
@@ -2133,7 +2191,8 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
private async _stash(repository: Repository, includeUntracked = false): Promise<void> {
|
||||
const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0;
|
||||
const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0
|
||||
&& (!includeUntracked || repository.untrackedGroup.resourceStates.length === 0);
|
||||
const noStagedChanges = repository.indexGroup.resourceStates.length === 0;
|
||||
|
||||
if (noUnstagedChanges && noStagedChanges) {
|
||||
@@ -2215,6 +2274,18 @@ export class CommandCenter {
|
||||
await repository.applyStash();
|
||||
}
|
||||
|
||||
@command('git.stashDrop', { repository: true })
|
||||
async stashDrop(repository: Repository): Promise<void> {
|
||||
const placeHolder = localize('pick stash to drop', "Pick a stash to drop");
|
||||
const stash = await this.pickStash(repository, placeHolder);
|
||||
|
||||
if (!stash) {
|
||||
return;
|
||||
}
|
||||
|
||||
await repository.dropStash(stash.index);
|
||||
}
|
||||
|
||||
private async pickStash(repository: Repository, placeHolder: string): Promise<Stash | undefined> {
|
||||
const stashes = await repository.getStashes();
|
||||
|
||||
@@ -2352,7 +2423,7 @@ export class CommandCenter {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (uri.scheme === 'git') {
|
||||
if (isGitUri(uri)) {
|
||||
const { path } = fromGitUri(uri);
|
||||
uri = Uri.file(path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user