Merge from vscode 52dcb723a39ae75bee1bd56b3312d7fcdc87aeed (#6719)

This commit is contained in:
Anthony Dresser
2019-08-12 21:31:51 -07:00
committed by GitHub
parent 00250839fc
commit 7eba8c4c03
616 changed files with 9472 additions and 7087 deletions

View File

@@ -353,9 +353,11 @@ export class CommandCenter {
switch (resource.type) {
case Status.INDEX_MODIFIED:
case Status.INDEX_RENAMED:
case Status.INDEX_ADDED:
return this.getURI(resource.original, 'HEAD');
case Status.MODIFIED:
case Status.UNTRACKED:
return this.getURI(resource.resourceUri, '~');
case Status.DELETED_BY_THEM:
@@ -414,6 +416,7 @@ export class CommandCenter {
switch (resource.type) {
case Status.INDEX_MODIFIED:
case Status.INDEX_RENAMED:
case Status.INDEX_ADDED:
return `${basename} (Index)`;
case Status.MODIFIED:
@@ -426,6 +429,10 @@ export class CommandCenter {
case Status.DELETED_BY_THEM:
return `${basename} (Ours)`;
case Status.UNTRACKED:
return `${basename} (Untracked)`;
}
return '';
@@ -450,6 +457,8 @@ export class CommandCenter {
return;
}
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());
@@ -698,7 +707,13 @@ export class CommandCenter {
viewColumn: ViewColumn.Active
};
const document = await workspace.openTextDocument(uri);
let document;
try {
document = await workspace.openTextDocument(uri);
} catch (error) {
await commands.executeCommand<void>('vscode.open', uri, opts);
continue;
}
// Check if active text editor has same path as other editor. we cannot compare via
// URI.toString() here because the schemas can be different. Instead we just go by path.
@@ -1225,23 +1240,35 @@ export class CommandCenter {
opts?: CommitOptions
): Promise<boolean> {
const config = workspace.getConfiguration('git', Uri.file(repository.root));
const promptToSaveFilesBeforeCommit = config.get<boolean>('promptToSaveFilesBeforeCommit') === true;
let promptToSaveFilesBeforeCommit = config.get<'always' | 'staged' | 'never'>('promptToSaveFilesBeforeCommit');
if (promptToSaveFilesBeforeCommit) {
const unsavedTextDocuments = workspace.textDocuments
// migration
if (promptToSaveFilesBeforeCommit as any === true) {
promptToSaveFilesBeforeCommit = 'always';
} else if (promptToSaveFilesBeforeCommit as any === false) {
promptToSaveFilesBeforeCommit = 'never';
}
if (promptToSaveFilesBeforeCommit !== 'never') {
let documents = workspace.textDocuments
.filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath));
if (unsavedTextDocuments.length > 0) {
const message = unsavedTextDocuments.length === 1
? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before committing?", path.basename(unsavedTextDocuments[0].uri.fsPath))
: localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", unsavedTextDocuments.length);
if (promptToSaveFilesBeforeCommit === 'staged') {
documents = documents
.filter(d => repository.indexGroup.resourceStates.some(s => s.resourceUri.path === d.uri.fsPath));
}
if (documents.length > 0) {
const message = documents.length === 1
? localize('unsaved files single', "The following file is unsaved and will not be included in the commit if you proceed: {0}.\n\nWould you like to save it before committing?", path.basename(documents[0].uri.fsPath))
: localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", documents.length);
const saveAndCommit = localize('save and commit', "Save All & Commit");
const commit = localize('commit', "Commit Anyway");
const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit);
if (pick === saveAndCommit) {
await Promise.all(unsavedTextDocuments.map(d => d.save()));
await repository.status();
await Promise.all(documents.map(d => d.save()));
await repository.add(documents.map(d => d.uri));
} else if (pick !== commit) {
return false; // do not commit on cancel
}
@@ -1255,15 +1282,24 @@ export class CommandCenter {
// no changes, and the user has not configured to commit all in this case
if (!noUnstagedChanges && noStagedChanges && !enableSmartCommit) {
const suggestSmartCommit = config.get<boolean>('suggestSmartCommit') === true;
if (!suggestSmartCommit) {
return false;
}
// prompt the user if we want to commit all or not
const message = localize('no staged changes', "There are no staged changes to commit.\n\nWould you like to automatically stage all your changes and commit them directly?");
const yes = localize('yes', "Yes");
const always = localize('always', "Always");
const pick = await window.showWarningMessage(message, { modal: true }, yes, always);
const never = localize('never', "Never");
const pick = await window.showWarningMessage(message, { modal: true }, yes, always, never);
if (pick === always) {
config.update('enableSmartCommit', true, true);
} else if (pick === never) {
config.update('suggestSmartCommit', false, true);
return false;
} else if (pick !== yes) {
return false; // do not commit on cancel
}
@@ -1301,6 +1337,10 @@ export class CommandCenter {
return false;
}
if (opts.all && config.get<'all' | 'tracked'>('smartCommitChanges') === 'tracked') {
opts.all = 'tracked';
}
await repository.commit(message, opts);
const postCommitCommand = config.get<'none' | 'push' | 'sync'>('postCommitCommand');
@@ -1350,19 +1390,6 @@ export class CommandCenter {
await this.commitWithAnyInput(repository);
}
@command('git.commitWithInput', { repository: true })
async commitWithInput(repository: Repository): Promise<void> {
if (!repository.inputBox.value) {
return;
}
const didCommit = await this.smartCommit(repository, async () => repository.inputBox.value);
if (didCommit) {
repository.inputBox.value = await repository.getCommitTemplate();
}
}
@command('git.commitStaged', { repository: true })
async commitStaged(repository: Repository): Promise<void> {
await this.commitWithAnyInput(repository, { all: false });
@@ -1487,12 +1514,12 @@ export class CommandCenter {
await this._branch(repository, undefined, true);
}
private async _branch(repository: Repository, defaultName?: string, from = false): Promise<void> {
private async promptForBranchName(defaultName?: string): Promise<string> {
const config = workspace.getConfiguration('git');
const branchWhitespaceChar = config.get<string>('branchWhitespaceChar')!;
const branchValidationRegex = config.get<string>('branchValidationRegex')!;
const sanitize = (name: string) => name ?
name.trim().replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, branchWhitespaceChar)
name.trim().replace(/^-+/, '').replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$|\[|\]$/g, branchWhitespaceChar)
: name;
const rawBranchName = defaultName || await window.showInputBox({
@@ -1509,7 +1536,11 @@ export class CommandCenter {
}
});
const branchName = sanitize(rawBranchName || '');
return sanitize(rawBranchName || '');
}
private async _branch(repository: Repository, defaultName?: string, from = false): Promise<void> {
const branchName = await this.promptForBranchName(defaultName);
if (!branchName) {
return;
@@ -1571,25 +1602,21 @@ export class CommandCenter {
@command('git.renameBranch', { repository: true })
async renameBranch(repository: Repository): Promise<void> {
const name = await window.showInputBox({
placeHolder: localize('branch name', "Branch name"),
prompt: localize('provide branch name', "Please provide a branch name"),
value: repository.HEAD && repository.HEAD.name
});
const branchName = await this.promptForBranchName();
if (!name || name.trim().length === 0) {
if (!branchName) {
return;
}
try {
await repository.renameBranch(name);
await repository.renameBranch(branchName);
} 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));
window.showErrorMessage(localize('branch already exists', "A branch named '{0}' already exists", branchName));
return;
default:
throw err;
@@ -1913,7 +1940,17 @@ export class CommandCenter {
private async _sync(repository: Repository, rebase: boolean): Promise<void> {
const HEAD = repository.HEAD;
if (!HEAD || !HEAD.upstream) {
if (!HEAD) {
return;
} else if (!HEAD.upstream) {
const branchName = HEAD.name;
const message = localize('confirm publish branch', "The branch '{0}' has no upstream branch. Would you like to publish this branch?", branchName);
const yes = localize('ok', "OK");
const pick = await window.showWarningMessage(message, { modal: true }, yes);
if (pick === yes) {
await this.publish(repository);
}
return;
}
@@ -1945,8 +1982,16 @@ export class CommandCenter {
}
@command('git.sync', { repository: true })
sync(repository: Repository): Promise<void> {
return this._sync(repository, false);
async sync(repository: Repository): Promise<void> {
try {
await this._sync(repository, false);
} catch (err) {
if (/Cancelled/i.test(err && (err.message || err.stderr || ''))) {
return;
}
throw err;
}
}
@command('git._syncAll')
@@ -1963,8 +2008,16 @@ export class CommandCenter {
}
@command('git.syncRebase', { repository: true })
syncRebase(repository: Repository): Promise<void> {
return this._sync(repository, true);
async syncRebase(repository: Repository): Promise<void> {
try {
await this._sync(repository, true);
} catch (err) {
if (/Cancelled/i.test(err && (err.message || err.stderr || ''))) {
return;
}
throw err;
}
}
@command('git.publish', { repository: true })