mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-24 09:35:37 -05:00
Merge from vscode 2cd495805cf99b31b6926f08ff4348124b2cf73d
This commit is contained in:
committed by
AzureDataStudio
parent
a8a7559229
commit
1388493cc1
@@ -8,15 +8,15 @@ import * as path from 'path';
|
||||
import { Repository, GitResourceGroup } from './repository';
|
||||
import { Model } from './model';
|
||||
import { debounce } from './decorators';
|
||||
import { filterEvent, dispose, anyEvent, fireEvent } from './util';
|
||||
import { filterEvent, dispose, anyEvent, fireEvent, PromiseSource } from './util';
|
||||
import { GitErrorCodes, Status } from './api/git';
|
||||
|
||||
type Callback = { resolve: (status: boolean) => void, reject: (err: any) => void };
|
||||
|
||||
class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
|
||||
private static Decoration: Decoration = { priority: 3, color: new ThemeColor('gitDecoration.ignoredResourceForeground') };
|
||||
|
||||
readonly onDidChangeDecorations: Event<Uri[]>;
|
||||
private queue = new Map<string, { repository: Repository; queue: Map<string, Callback>; }>();
|
||||
private queue = new Map<string, { repository: Repository; queue: Map<string, PromiseSource<Decoration | undefined>>; }>();
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(private model: Model) {
|
||||
@@ -29,32 +29,29 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
this.disposables.push(window.registerDecorationProvider(this));
|
||||
}
|
||||
|
||||
provideDecoration(uri: Uri): Promise<Decoration | undefined> {
|
||||
async provideDecoration(uri: Uri): Promise<Decoration | undefined> {
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
return Promise.resolve(undefined);
|
||||
return;
|
||||
}
|
||||
|
||||
let queueItem = this.queue.get(repository.root);
|
||||
|
||||
if (!queueItem) {
|
||||
queueItem = { repository, queue: new Map<string, Callback>() };
|
||||
queueItem = { repository, queue: new Map<string, PromiseSource<Decoration | undefined>>() };
|
||||
this.queue.set(repository.root, queueItem);
|
||||
}
|
||||
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
queueItem!.queue.set(uri.fsPath, { resolve, reject });
|
||||
let promiseSource = queueItem.queue.get(uri.fsPath);
|
||||
|
||||
if (!promiseSource) {
|
||||
promiseSource = new PromiseSource();
|
||||
queueItem!.queue.set(uri.fsPath, promiseSource);
|
||||
this.checkIgnoreSoon();
|
||||
}).then(ignored => {
|
||||
if (ignored) {
|
||||
return <Decoration>{
|
||||
priority: 3,
|
||||
color: new ThemeColor('gitDecoration.ignoredResourceForeground')
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
return await promiseSource.promise;
|
||||
}
|
||||
|
||||
@debounce(500)
|
||||
@@ -66,16 +63,16 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
|
||||
const paths = [...item.queue.keys()];
|
||||
|
||||
item.repository.checkIgnore(paths).then(ignoreSet => {
|
||||
for (const [key, value] of item.queue.entries()) {
|
||||
value.resolve(ignoreSet.has(key));
|
||||
for (const [path, promiseSource] of item.queue.entries()) {
|
||||
promiseSource.resolve(ignoreSet.has(path) ? GitIgnoreDecorationProvider.Decoration : undefined);
|
||||
}
|
||||
}, err => {
|
||||
if (err.gitErrorCode !== GitErrorCodes.IsInSubmodule) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
for (const [, value] of item.queue.entries()) {
|
||||
value.reject(err);
|
||||
for (const [, promiseSource] of item.queue.entries()) {
|
||||
promiseSource.reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import * as os from 'os';
|
||||
import * as cp from 'child_process';
|
||||
import * as which from 'which';
|
||||
import { EventEmitter } from 'events';
|
||||
import iconv = require('iconv-lite');
|
||||
import * as iconv from 'iconv-lite-umd';
|
||||
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';
|
||||
@@ -1939,6 +1939,17 @@ export class Repository {
|
||||
return message.replace(/^\s*#.*$\n?/gm, '').trim();
|
||||
}
|
||||
|
||||
async getSquashMessage(): Promise<string | undefined> {
|
||||
const squashMsgPath = path.join(this.repositoryRoot, '.git', 'SQUASH_MSG');
|
||||
|
||||
try {
|
||||
const raw = await fs.readFile(squashMsgPath, 'utf8');
|
||||
return this.stripCommitMessageComments(raw);
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async getMergeMessage(): Promise<string | undefined> {
|
||||
const mergeMsgPath = path.join(this.repositoryRoot, '.git', 'MERGE_MSG');
|
||||
|
||||
|
||||
@@ -537,7 +537,7 @@ class DotGitWatcher implements IFileWatcher {
|
||||
upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables);
|
||||
} catch (err) {
|
||||
if (Log.logLevel <= LogLevel.Error) {
|
||||
this.outputChannel.appendLine(`Failed to watch ref '${upstreamPath}', is most likely packed.\n${err.stack || err}`);
|
||||
this.outputChannel.appendLine(`Warning: Failed to watch ref '${upstreamPath}', is most likely packed.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -729,10 +729,10 @@ export class Repository implements Disposable {
|
||||
this.updateInputBoxPlaceholder();
|
||||
this.disposables.push(this.onDidRunGitStatus(() => this.updateInputBoxPlaceholder()));
|
||||
|
||||
this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "MERGE CHANGES"));
|
||||
this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "STAGED CHANGES"));
|
||||
this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "CHANGES"));
|
||||
this._untrackedGroup = this._sourceControl.createResourceGroup('untracked', localize('untracked changes', "UNTRACKED CHANGES"));
|
||||
this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes"));
|
||||
this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "Staged Changes"));
|
||||
this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "Changes"));
|
||||
this._untrackedGroup = this._sourceControl.createResourceGroup('untracked', localize('untracked changes', "Untracked Changes"));
|
||||
|
||||
const updateIndexGroupVisibility = () => {
|
||||
const config = workspace.getConfiguration('git', root);
|
||||
@@ -865,10 +865,10 @@ export class Repository implements Disposable {
|
||||
}
|
||||
|
||||
async getInputTemplate(): Promise<string> {
|
||||
const mergeMessage = await this.repository.getMergeMessage();
|
||||
const commitMessage = (await Promise.all([this.repository.getMergeMessage(), this.repository.getSquashMessage()])).find(msg => msg !== undefined);
|
||||
|
||||
if (mergeMessage) {
|
||||
return mergeMessage;
|
||||
if (commitMessage) {
|
||||
return commitMessage;
|
||||
}
|
||||
|
||||
return await this.repository.getCommitTemplate();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, Disposable } from 'vscode';
|
||||
import { Event, Disposable, EventEmitter } from 'vscode';
|
||||
import { dirname, sep } from 'path';
|
||||
import { Readable } from 'stream';
|
||||
import { promises as fs, createReadStream } from 'fs';
|
||||
@@ -400,3 +400,39 @@ export class Limiter<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Completion<T> = { success: true, value: T } | { success: false, err: any };
|
||||
|
||||
export class PromiseSource<T> {
|
||||
|
||||
private _onDidComplete = new EventEmitter<Completion<T>>();
|
||||
|
||||
private _promise: Promise<T> | undefined;
|
||||
get promise(): Promise<T> {
|
||||
if (this._promise) {
|
||||
return this._promise;
|
||||
}
|
||||
|
||||
return eventToPromise(this._onDidComplete.event).then(completion => {
|
||||
if (completion.success) {
|
||||
return completion.value;
|
||||
} else {
|
||||
throw completion.err;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
resolve(value: T): void {
|
||||
if (!this._promise) {
|
||||
this._promise = Promise.resolve(value);
|
||||
this._onDidComplete.fire({ success: true, value });
|
||||
}
|
||||
}
|
||||
|
||||
reject(err: any): void {
|
||||
if (!this._promise) {
|
||||
this._promise = Promise.reject(err);
|
||||
this._onDidComplete.fire({ success: false, err });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user