mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-25 01:25:36 -05:00
Merge from vscode 2e5312cd61ff99c570299ecc122c52584265eda2
This commit is contained in:
committed by
Anthony Dresser
parent
3603f55d97
commit
7f1d8fc32f
@@ -5,8 +5,8 @@
|
||||
|
||||
import { Model } from '../model';
|
||||
import { Repository as BaseRepository, Resource } from '../repository';
|
||||
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions } from './git';
|
||||
import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode';
|
||||
import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions, APIState, CommitOptions, GitExtension, RefType, RemoteSourceProvider } from './git';
|
||||
import { Event, SourceControlInputBox, Uri, SourceControl, Disposable, commands } from 'vscode';
|
||||
import { mapEvent } from '../util';
|
||||
import { toGitUri } from '../uri';
|
||||
|
||||
@@ -248,5 +248,82 @@ export class ApiImpl implements API {
|
||||
return result ? new ApiRepository(result) : null;
|
||||
}
|
||||
|
||||
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable {
|
||||
return this._model.registerRemoteSourceProvider(provider);
|
||||
}
|
||||
|
||||
constructor(private _model: Model) { }
|
||||
}
|
||||
|
||||
function getRefType(type: RefType): string {
|
||||
switch (type) {
|
||||
case RefType.Head: return 'Head';
|
||||
case RefType.RemoteHead: return 'RemoteHead';
|
||||
case RefType.Tag: return 'Tag';
|
||||
}
|
||||
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
function getStatus(status: Status): string {
|
||||
switch (status) {
|
||||
case Status.INDEX_MODIFIED: return 'INDEX_MODIFIED';
|
||||
case Status.INDEX_ADDED: return 'INDEX_ADDED';
|
||||
case Status.INDEX_DELETED: return 'INDEX_DELETED';
|
||||
case Status.INDEX_RENAMED: return 'INDEX_RENAMED';
|
||||
case Status.INDEX_COPIED: return 'INDEX_COPIED';
|
||||
case Status.MODIFIED: return 'MODIFIED';
|
||||
case Status.DELETED: return 'DELETED';
|
||||
case Status.UNTRACKED: return 'UNTRACKED';
|
||||
case Status.IGNORED: return 'IGNORED';
|
||||
case Status.INTENT_TO_ADD: return 'INTENT_TO_ADD';
|
||||
case Status.ADDED_BY_US: return 'ADDED_BY_US';
|
||||
case Status.ADDED_BY_THEM: return 'ADDED_BY_THEM';
|
||||
case Status.DELETED_BY_US: return 'DELETED_BY_US';
|
||||
case Status.DELETED_BY_THEM: return 'DELETED_BY_THEM';
|
||||
case Status.BOTH_ADDED: return 'BOTH_ADDED';
|
||||
case Status.BOTH_DELETED: return 'BOTH_DELETED';
|
||||
case Status.BOTH_MODIFIED: return 'BOTH_MODIFIED';
|
||||
}
|
||||
|
||||
return 'UNKNOWN';
|
||||
}
|
||||
|
||||
export function registerAPICommands(extension: GitExtension): Disposable {
|
||||
return Disposable.from(
|
||||
commands.registerCommand('git.api.getRepositories', () => {
|
||||
const api = extension.getAPI(1);
|
||||
return api.repositories.map(r => r.rootUri.toString());
|
||||
}),
|
||||
|
||||
commands.registerCommand('git.api.getRepositoryState', (uri: string) => {
|
||||
const api = extension.getAPI(1);
|
||||
const repository = api.getRepository(Uri.parse(uri));
|
||||
|
||||
if (!repository) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const state = repository.state;
|
||||
|
||||
const ref = (ref: Ref | undefined) => (ref && { ...ref, type: getRefType(ref.type) });
|
||||
const change = (change: Change) => ({
|
||||
uri: change.uri.toString(),
|
||||
originalUri: change.originalUri.toString(),
|
||||
renameUri: change.renameUri?.toString(),
|
||||
status: getStatus(change.status)
|
||||
});
|
||||
|
||||
return {
|
||||
HEAD: ref(state.HEAD),
|
||||
refs: state.refs.map(ref),
|
||||
remotes: state.remotes,
|
||||
submodules: state.submodules,
|
||||
rebaseCommit: state.rebaseCommit,
|
||||
mergeChanges: state.mergeChanges.map(change),
|
||||
indexChanges: state.indexChanges.map(change),
|
||||
workingTreeChanges: state.workingTreeChanges.map(change)
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
17
extensions/git/src/api/git.d.ts
vendored
17
extensions/git/src/api/git.d.ts
vendored
@@ -3,7 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri, SourceControlInputBox, Event, CancellationToken } from 'vscode';
|
||||
import { Uri, Event, Disposable, ProviderResult } from 'vscode';
|
||||
export { ProviderResult } from 'vscode';
|
||||
|
||||
export interface Git {
|
||||
readonly path: string;
|
||||
@@ -189,6 +190,19 @@ export interface Repository {
|
||||
commit(message: string, opts?: CommitOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export interface RemoteSource {
|
||||
readonly name: string;
|
||||
readonly description?: string;
|
||||
readonly url: string | string[];
|
||||
}
|
||||
|
||||
export interface RemoteSourceProvider {
|
||||
readonly name: string;
|
||||
readonly icon?: string; // codicon name
|
||||
readonly supportsQuery?: boolean;
|
||||
getRemoteSources(query?: string): ProviderResult<RemoteSource[]>;
|
||||
}
|
||||
|
||||
export type APIState = 'uninitialized' | 'initialized';
|
||||
|
||||
export interface API {
|
||||
@@ -201,6 +215,7 @@ export interface API {
|
||||
|
||||
toGitUri(uri: Uri, ref: string): Uri;
|
||||
getRepository(uri: Uri): Repository | null;
|
||||
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable;
|
||||
}
|
||||
|
||||
export interface GitExtension {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
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, TimelineItem, env } from 'vscode';
|
||||
import { commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, QuickPick } from 'vscode';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions } from './api/git';
|
||||
import { Branch, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourceProvider, RemoteSource } from './api/git';
|
||||
import { ForcePushMode, Git, Stash } from './git';
|
||||
import { Model } from './model';
|
||||
import { Repository, Resource, ResourceGroupType } from './repository';
|
||||
@@ -18,6 +18,7 @@ import { fromGitUri, toGitUri, isGitUri } from './uri';
|
||||
import { grep, isDescendant, pathEquals } from './util';
|
||||
import { Log, LogLevel } from './log';
|
||||
import { GitTimelineItem } from './timelineProvider';
|
||||
import { throttle, debounce } from './decorators';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -233,6 +234,71 @@ interface PushOptions {
|
||||
silent?: boolean;
|
||||
}
|
||||
|
||||
async function getQuickPickResult<T extends QuickPickItem>(quickpick: QuickPick<T>): Promise<T | undefined> {
|
||||
const result = await new Promise<T | undefined>(c => {
|
||||
quickpick.onDidAccept(() => c(quickpick.selectedItems[0]));
|
||||
quickpick.onDidHide(() => c(undefined));
|
||||
quickpick.show();
|
||||
});
|
||||
|
||||
quickpick.hide();
|
||||
return result;
|
||||
}
|
||||
|
||||
class RemoteSourceProviderQuickPick {
|
||||
|
||||
private quickpick: QuickPick<QuickPickItem & { remoteSource?: RemoteSource }>;
|
||||
|
||||
constructor(private provider: RemoteSourceProvider) {
|
||||
this.quickpick = window.createQuickPick();
|
||||
this.quickpick.ignoreFocusOut = true;
|
||||
|
||||
if (provider.supportsQuery) {
|
||||
this.quickpick.placeholder = localize('type to search', "Repository name (type to search)");
|
||||
this.quickpick.onDidChangeValue(this.onDidChangeValue, this);
|
||||
} else {
|
||||
this.quickpick.placeholder = localize('type to filter', "Repository name");
|
||||
}
|
||||
}
|
||||
|
||||
@debounce(300)
|
||||
onDidChangeValue(): void {
|
||||
this.query();
|
||||
}
|
||||
|
||||
@throttle
|
||||
async query(): Promise<void> {
|
||||
this.quickpick.busy = true;
|
||||
|
||||
try {
|
||||
const remoteSources = await this.provider.getRemoteSources(this.quickpick.value) || [];
|
||||
|
||||
if (remoteSources.length === 0) {
|
||||
this.quickpick.items = [{
|
||||
label: localize('none found', "No remote repositories found."),
|
||||
alwaysShow: true
|
||||
}];
|
||||
} else {
|
||||
this.quickpick.items = remoteSources.map(remoteSource => ({
|
||||
label: remoteSource.name,
|
||||
description: remoteSource.description || (typeof remoteSource.url === 'string' ? remoteSource.url : remoteSource.url[0]),
|
||||
remoteSource
|
||||
}));
|
||||
}
|
||||
} catch (err) {
|
||||
this.quickpick.items = [{ label: localize('error', "$(error) Error: {0}", err.message), alwaysShow: true }];
|
||||
} finally {
|
||||
this.quickpick.busy = false;
|
||||
}
|
||||
}
|
||||
|
||||
async pick(): Promise<RemoteSource | undefined> {
|
||||
this.query();
|
||||
const result = await getQuickPickResult(this.quickpick);
|
||||
return result?.remoteSource;
|
||||
}
|
||||
}
|
||||
|
||||
export class CommandCenter {
|
||||
|
||||
private disposables: Disposable[];
|
||||
@@ -290,7 +356,7 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
@command('git.openResource')
|
||||
async openResource(resource: Resource): Promise<void> {
|
||||
async openResource(resource: Resource, preserveFocus: boolean): Promise<void> {
|
||||
const repository = this.model.getRepository(resource.resourceUri);
|
||||
|
||||
if (!repository) {
|
||||
@@ -301,7 +367,7 @@ export class CommandCenter {
|
||||
const openDiffOnClick = config.get<boolean>('openDiffOnClick');
|
||||
|
||||
if (openDiffOnClick) {
|
||||
await this._openResource(resource, undefined, true, false);
|
||||
await this._openResource(resource, undefined, preserveFocus, false);
|
||||
} else {
|
||||
await this.openFile(resource);
|
||||
}
|
||||
@@ -454,10 +520,51 @@ export class CommandCenter {
|
||||
@command('git.clone')
|
||||
async clone(url?: string, parentPath?: string): Promise<void> {
|
||||
if (!url) {
|
||||
url = await window.showInputBox({
|
||||
prompt: localize('repourl', "Repository URL"),
|
||||
ignoreFocusOut: true
|
||||
});
|
||||
const quickpick = window.createQuickPick<(QuickPickItem & { provider?: RemoteSourceProvider, url?: string })>();
|
||||
quickpick.ignoreFocusOut = true;
|
||||
|
||||
const providers = this.model.getRemoteProviders()
|
||||
.map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + localize('clonefrom', "Clone from {1}", provider.name), alwaysShow: true, provider }));
|
||||
|
||||
quickpick.placeholder = providers.length === 0
|
||||
? localize('provide url', "Provide repository URL.")
|
||||
: localize('provide url or pick', "Provide repository URL or pick a repository source.");
|
||||
|
||||
const updatePicks = (value?: string) => {
|
||||
if (value) {
|
||||
quickpick.items = [{
|
||||
label: localize('repourl', "Clone from URL"),
|
||||
description: value,
|
||||
alwaysShow: true,
|
||||
url: value
|
||||
},
|
||||
...providers];
|
||||
} else {
|
||||
quickpick.items = providers;
|
||||
}
|
||||
};
|
||||
|
||||
quickpick.onDidChangeValue(updatePicks);
|
||||
updatePicks();
|
||||
|
||||
const result = await getQuickPickResult(quickpick);
|
||||
|
||||
if (result) {
|
||||
if (result.url) {
|
||||
url = result.url;
|
||||
} else if (result.provider) {
|
||||
const quickpick = new RemoteSourceProviderQuickPick(result.provider);
|
||||
const remote = await quickpick.pick();
|
||||
|
||||
if (remote) {
|
||||
if (typeof remote.url === 'string') {
|
||||
url = remote.url;
|
||||
} else if (remote.url.length > 0) {
|
||||
url = await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: localize('pick url', "Choose a URL to clone from.") });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!url) {
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { workspace, Uri, Disposable, Event, EventEmitter, window } from 'vscode';
|
||||
import { debounce, throttle } from './decorators';
|
||||
import { fromGitUri, toGitUri } from './uri';
|
||||
import { Model, ModelChangeEvent, OriginalResourceChangeEvent } from './model';
|
||||
import { filterEvent, eventToPromise, isDescendant, pathEquals } from './util';
|
||||
|
||||
interface CacheRow {
|
||||
uri: Uri;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
interface Cache {
|
||||
[uri: string]: CacheRow;
|
||||
}
|
||||
|
||||
const THREE_MINUTES = 1000 * 60 * 3;
|
||||
const FIVE_MINUTES = 1000 * 60 * 5;
|
||||
|
||||
export class GitContentProvider {
|
||||
|
||||
private _onDidChange = new EventEmitter<Uri>();
|
||||
get onDidChange(): Event<Uri> { return this._onDidChange.event; }
|
||||
|
||||
private changedRepositoryRoots = new Set<string>();
|
||||
private cache: Cache = Object.create(null);
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(private model: Model) {
|
||||
this.disposables.push(
|
||||
model.onDidChangeRepository(this.onDidChangeRepository, this),
|
||||
model.onDidChangeOriginalResource(this.onDidChangeOriginalResource, this),
|
||||
workspace.registerTextDocumentContentProvider('git', this)
|
||||
);
|
||||
|
||||
setInterval(() => this.cleanup(), FIVE_MINUTES);
|
||||
}
|
||||
|
||||
private onDidChangeRepository({ repository }: ModelChangeEvent): void {
|
||||
this.changedRepositoryRoots.add(repository.root);
|
||||
this.eventuallyFireChangeEvents();
|
||||
}
|
||||
|
||||
private onDidChangeOriginalResource({ uri }: OriginalResourceChangeEvent): void {
|
||||
if (uri.scheme !== 'file') {
|
||||
return;
|
||||
}
|
||||
|
||||
this._onDidChange.fire(toGitUri(uri, '', { replaceFileExtension: true }));
|
||||
}
|
||||
|
||||
@debounce(1100)
|
||||
private eventuallyFireChangeEvents(): void {
|
||||
this.fireChangeEvents();
|
||||
}
|
||||
|
||||
@throttle
|
||||
private async fireChangeEvents(): Promise<void> {
|
||||
if (!window.state.focused) {
|
||||
const onDidFocusWindow = filterEvent(window.onDidChangeWindowState, e => e.focused);
|
||||
await eventToPromise(onDidFocusWindow);
|
||||
}
|
||||
|
||||
Object.keys(this.cache).forEach(key => {
|
||||
const uri = this.cache[key].uri;
|
||||
const fsPath = uri.fsPath;
|
||||
|
||||
for (const root of this.changedRepositoryRoots) {
|
||||
if (isDescendant(root, fsPath)) {
|
||||
this._onDidChange.fire(uri);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.changedRepositoryRoots.clear();
|
||||
}
|
||||
|
||||
async provideTextDocumentContent(uri: Uri): Promise<string> {
|
||||
let { path, ref, submoduleOf } = fromGitUri(uri);
|
||||
|
||||
if (submoduleOf) {
|
||||
const repository = this.model.getRepository(submoduleOf);
|
||||
|
||||
if (!repository) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (ref === 'index') {
|
||||
return await repository.diffIndexWithHEAD(path);
|
||||
} else {
|
||||
return await repository.diffWithHEAD(path);
|
||||
}
|
||||
}
|
||||
|
||||
const repository = this.model.getRepository(uri);
|
||||
|
||||
if (!repository) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const cacheKey = uri.toString();
|
||||
const timestamp = new Date().getTime();
|
||||
const cacheValue: CacheRow = { uri, timestamp };
|
||||
|
||||
this.cache[cacheKey] = cacheValue;
|
||||
|
||||
if (ref === '~') {
|
||||
const fileUri = Uri.file(path);
|
||||
const uriString = fileUri.toString();
|
||||
const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString);
|
||||
ref = indexStatus ? '' : 'HEAD';
|
||||
} else if (/^~\d$/.test(ref)) {
|
||||
ref = `:${ref[1]}`;
|
||||
}
|
||||
|
||||
try {
|
||||
return await repository.show(ref, path);
|
||||
} catch (err) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
private cleanup(): void {
|
||||
const now = new Date().getTime();
|
||||
const cache = Object.create(null);
|
||||
|
||||
Object.keys(this.cache).forEach(key => {
|
||||
const row = this.cache[key];
|
||||
const { path } = fromGitUri(row.uri);
|
||||
const isOpen = workspace.textDocuments
|
||||
.filter(d => d.uri.scheme === 'file')
|
||||
.some(d => pathEquals(d.uri.fsPath, path));
|
||||
|
||||
if (isOpen || now - row.timestamp < THREE_MINUTES) {
|
||||
cache[row.uri.toString()] = row;
|
||||
}
|
||||
});
|
||||
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.disposables.forEach(d => d.dispose());
|
||||
}
|
||||
}
|
||||
@@ -443,7 +443,10 @@ export class Git {
|
||||
);
|
||||
if (networkPath !== undefined) {
|
||||
return path.normalize(
|
||||
repoUri.fsPath.replace(networkPath, `${letter.toLowerCase()}:`),
|
||||
repoUri.fsPath.replace(
|
||||
networkPath,
|
||||
`${letter.toLowerCase()}:${networkPath.endsWith('\\') ? '\\' : ''}`
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch { }
|
||||
@@ -537,7 +540,8 @@ export class Git {
|
||||
options.env = assign({}, process.env, this.env, options.env || {}, {
|
||||
VSCODE_GIT_COMMAND: args[0],
|
||||
LC_ALL: 'en_US.UTF-8',
|
||||
LANG: 'en_US.UTF-8'
|
||||
LANG: 'en_US.UTF-8',
|
||||
GIT_PAGER: 'cat'
|
||||
});
|
||||
|
||||
if (options.cwd) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import { ExtensionContext, workspace, window, Disposable, commands, OutputChanne
|
||||
import { findGit, Git, IGit } from './git';
|
||||
import { Model } from './model';
|
||||
import { CommandCenter } from './commands';
|
||||
import { GitContentProvider } from './contentProvider';
|
||||
import { GitFileSystemProvider } from './fileSystemProvider';
|
||||
import { GitDecorations } from './decorationProvider';
|
||||
import { Askpass } from './askpass';
|
||||
@@ -23,6 +22,7 @@ import { GitExtensionImpl } from './api/extension';
|
||||
// import * as fs from 'fs';
|
||||
import { createIPCServer, IIPCServer } from './ipc/ipcServer';
|
||||
import { GitTimelineProvider } from './timelineProvider';
|
||||
import { registerAPICommands } from './api/api1';
|
||||
|
||||
const deactivateTasks: { (): Promise<any>; }[] = [];
|
||||
|
||||
@@ -80,7 +80,6 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
|
||||
|
||||
disposables.push(
|
||||
new CommandCenter(git, model, outputChannel, telemetryReporter),
|
||||
new GitContentProvider(model),
|
||||
new GitFileSystemProvider(model),
|
||||
new GitDecorations(model),
|
||||
new GitProtocolHandler(),
|
||||
@@ -141,7 +140,7 @@ async function warnAboutMissingGit(): Promise<void> {
|
||||
}
|
||||
}*/
|
||||
|
||||
export async function activate(context: ExtensionContext): Promise<GitExtension> {
|
||||
export async function _activate(context: ExtensionContext): Promise<GitExtension> {
|
||||
const disposables: Disposable[] = [];
|
||||
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
|
||||
|
||||
@@ -183,10 +182,19 @@ export async function activate(context: ExtensionContext): Promise<GitExtension>
|
||||
}
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}} - Rename info to _info to prevent error due to unused variable
|
||||
async function checkGitVersion(_info: IGit): Promise<void> {
|
||||
export async function activate(context: ExtensionContext): Promise<GitExtension> {
|
||||
const result = await _activate(context);
|
||||
context.subscriptions.push(registerAPICommands(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
async function checkGitVersion(_info: IGit): Promise<void> { // {{SQL CARBON EDIT}} - Rename info to _info to prevent error due to unused variable
|
||||
return; /* {{SQL CARBON EDIT}} return immediately
|
||||
|
||||
/*const config = workspace.getConfiguration('git');
|
||||
const shouldIgnore = config.get<boolean>('ignoreLegacyWarning') === true;
|
||||
|
||||
|
||||
const config = workspace.getConfiguration('git');
|
||||
const shouldIgnore = config.get<boolean>('ignoreLegacyWarning') === true;
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel } from 'vscode';
|
||||
import { Repository, RepositoryState } from './repository';
|
||||
import { memoize, sequentialize, debounce } from './decorators';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, firstIndex, pathEquals } from './util';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, firstIndex, pathEquals, toDisposable } from './util';
|
||||
import { Git } from './git';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { fromGitUri } from './uri';
|
||||
import { GitErrorCodes, APIState as State } from './api/git';
|
||||
import { GitErrorCodes, APIState as State, RemoteSourceProvider } from './api/git';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -74,6 +74,8 @@ export class Model {
|
||||
this._onDidChangeState.fire(state);
|
||||
}
|
||||
|
||||
private remoteProviders = new Set<RemoteSourceProvider>();
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(readonly git: Git, private globalState: Memento, private outputChannel: OutputChannel) {
|
||||
@@ -447,6 +449,15 @@ export class Model {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
registerRemoteSourceProvider(provider: RemoteSourceProvider): Disposable {
|
||||
this.remoteProviders.add(provider);
|
||||
return toDisposable(() => this.remoteProviders.delete(provider));
|
||||
}
|
||||
|
||||
getRemoteProviders(): RemoteSourceProvider[] {
|
||||
return [...this.remoteProviders.values()];
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
const openRepositories = [...this.openRepositories];
|
||||
openRepositories.forEach(r => r.dispose());
|
||||
|
||||
@@ -743,6 +743,15 @@ export class Repository implements Disposable {
|
||||
const onConfigListenerForUntracked = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.untrackedChanges', root));
|
||||
onConfigListenerForUntracked(this.updateModelState, this, this.disposables);
|
||||
|
||||
const updateInputBoxVisibility = () => {
|
||||
const config = workspace.getConfiguration('git', root);
|
||||
this._sourceControl.inputBox.visible = config.get<boolean>('showCommitInput', true);
|
||||
};
|
||||
|
||||
const onConfigListenerForInputBoxVisibility = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.showCommitInput', root));
|
||||
onConfigListenerForInputBoxVisibility(updateInputBoxVisibility, this, this.disposables);
|
||||
updateInputBoxVisibility();
|
||||
|
||||
this.mergeGroup.hideWhenEmpty = true;
|
||||
this.untrackedGroup.hideWhenEmpty = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user