diff --git a/extensions/git/package.json b/extensions/git/package.json index 2ba6515e963..42025387d61 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -26,6 +26,11 @@ }, "contributes": { "commands": [ + { + "command": "git.setLogLevel", + "title": "%command.setLogLevel%", + "category": "Git" + }, { "command": "git.clone", "title": "%command.clone%", diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 5c357b40eb0..f3d75519653 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -1,6 +1,7 @@ { "displayName": "Git", "description": "Git SCM Integration", + "command.setLogLevel": "Set Log Level...", "command.clone": "Clone", "command.init": "Initialize Repository", "command.openRepository": "Open Repository", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index bbc4c555b19..2414b16634f 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -16,6 +16,7 @@ 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'; +import { Log, LogLevel } from './log'; const localize = nls.loadMessageBundle(); @@ -252,6 +253,36 @@ export class CommandCenter { }); } + @command('git.setLogLevel') + async setLogLevel(): Promise { + const createItem = (logLevel: LogLevel) => ({ + label: LogLevel[logLevel], + logLevel, + description: Log.logLevel === logLevel ? localize('current', "Current") : undefined + }); + + const items = [ + createItem(LogLevel.Trace), + createItem(LogLevel.Debug), + createItem(LogLevel.Info), + createItem(LogLevel.Warning), + createItem(LogLevel.Error), + createItem(LogLevel.Critical), + createItem(LogLevel.Off) + ]; + + const choice = await window.showQuickPick(items, { + placeHolder: localize('select log level', "Select log level") + }); + + if (!choice) { + return; + } + + Log.logLevel = choice.logLevel; + this.outputChannel.appendLine(localize('changed', "Log level changed to: {0}", LogLevel[Log.logLevel])); + } + @command('git.refresh', { repository: true }) async refresh(repository: Repository): Promise { await repository.status(); diff --git a/extensions/git/src/log.ts b/extensions/git/src/log.ts new file mode 100644 index 00000000000..487228e57a7 --- /dev/null +++ b/extensions/git/src/log.ts @@ -0,0 +1,50 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Event, EventEmitter } from 'vscode'; + +/** + * The severity level of a log message + */ +export enum LogLevel { + Trace = 1, + Debug = 2, + Info = 3, + Warning = 4, + Error = 5, + Critical = 6, + Off = 7 +} + +let _logLevel: LogLevel = LogLevel.Info; +const _onDidChangeLogLevel = new EventEmitter(); + +export const Log = { + /** + * Current logging level. + */ + get logLevel(): LogLevel { + return _logLevel; + }, + + /** + * Current logging level. + */ + set logLevel(logLevel: LogLevel) { + if (_logLevel === logLevel) { + return; + } + + _logLevel = logLevel; + _onDidChangeLogLevel.fire(logLevel); + }, + + /** + * An [event](#Event) that fires when the log level has changed. + */ + get onDidChangeLogLevel(): Event { + return _onDidChangeLogLevel.event; + } +}; diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 47832f9e0f0..dd00637a502 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -5,7 +5,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import { CancellationToken, Command, Disposable, env, Event, EventEmitter, LogLevel, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, Decoration } from 'vscode'; +import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, Decoration } from 'vscode'; import * as nls from 'vscode-nls'; import { Branch, Change, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status } from './api/git'; import { AutoFetcher } from './autofetch'; @@ -15,6 +15,7 @@ import { StatusBarCommands } from './statusbar'; import { toGitUri } from './uri'; import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, onceEvent } from './util'; import { IFileWatcher, watch } from './watch'; +import { Log, LogLevel } from './log'; const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); @@ -457,8 +458,8 @@ class FileEventLogger { private onDotGitFileChange: Event, private outputChannel: OutputChannel ) { - this.logLevelDisposable = env.onDidChangeLogLevel(this.onDidChangeLogLevel, this); - this.onDidChangeLogLevel(env.logLevel); + this.logLevelDisposable = Log.onDidChangeLogLevel(this.onDidChangeLogLevel, this); + this.onDidChangeLogLevel(Log.logLevel); } private onDidChangeLogLevel(level: LogLevel): void { @@ -519,7 +520,7 @@ class DotGitWatcher implements IFileWatcher { this.transientDisposables.push(upstreamWatcher); upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables); } catch (err) { - if (env.logLevel <= LogLevel.Error) { + if (Log.logLevel <= LogLevel.Error) { this.outputChannel.appendLine(`Failed to watch ref '${upstreamPath}', is most likely packed.\n${err.stack || err}`); } } @@ -682,7 +683,7 @@ export class Repository implements Disposable { onDotGitFileChange = dotGitFileWatcher.event; this.disposables.push(dotGitFileWatcher); } catch (err) { - if (env.logLevel <= LogLevel.Error) { + if (Log.logLevel <= LogLevel.Error) { outputChannel.appendLine(`Failed to watch '${this.dotGit}', reverting to legacy API file watched. Some events might be lost.\n${err.stack || err}`); }