mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-28 04:23:32 +01:00
Git - logging improvements (#148656)
This commit is contained in:
@@ -3,11 +3,12 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { window, InputBoxOptions, Uri, OutputChannel, Disposable, workspace } from 'vscode';
|
||||
import { IDisposable, EmptyDisposable, toDisposable, logTimestamp } from './util';
|
||||
import { window, InputBoxOptions, Uri, Disposable, workspace } from 'vscode';
|
||||
import { IDisposable, EmptyDisposable, toDisposable } from './util';
|
||||
import * as path from 'path';
|
||||
import { IIPCHandler, IIPCServer, createIPCServer } from './ipc/ipcServer';
|
||||
import { CredentialsProvider, Credentials } from './api/git';
|
||||
import { OutputChannelLogger } from './log';
|
||||
|
||||
export class Askpass implements IIPCHandler {
|
||||
|
||||
@@ -15,11 +16,11 @@ export class Askpass implements IIPCHandler {
|
||||
private cache = new Map<string, Credentials>();
|
||||
private credentialsProviders = new Set<CredentialsProvider>();
|
||||
|
||||
static async create(outputChannel: OutputChannel, context?: string): Promise<Askpass> {
|
||||
static async create(outputChannelLogger: OutputChannelLogger, context?: string): Promise<Askpass> {
|
||||
try {
|
||||
return new Askpass(await createIPCServer(context));
|
||||
} catch (err) {
|
||||
outputChannel.appendLine(`${logTimestamp()} [error] Failed to create git askpass IPC: ${err}`);
|
||||
outputChannelLogger.logError(`Failed to create git askpass IPC: ${err}`);
|
||||
return new Askpass();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { Command, commands, Disposable, LineChange, MessageOptions, OutputChannel, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider } from 'vscode';
|
||||
import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider } from 'vscode';
|
||||
import TelemetryReporter from '@vscode/extension-telemetry';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Branch, ForcePushMode, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourcePublisher } from './api/git';
|
||||
@@ -14,8 +14,8 @@ 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, logTimestamp, pathEquals, relativePath } from './util';
|
||||
import { Log, LogLevel } from './log';
|
||||
import { grep, isDescendant, pathEquals, relativePath } from './util';
|
||||
import { LogLevel, OutputChannelLogger } from './log';
|
||||
import { GitTimelineItem } from './timelineProvider';
|
||||
import { ApiRepository } from './api/api1';
|
||||
import { pickRemoteSource } from './remoteSource';
|
||||
@@ -310,7 +310,7 @@ export class CommandCenter {
|
||||
constructor(
|
||||
private git: Git,
|
||||
private model: Model,
|
||||
private outputChannel: OutputChannel,
|
||||
private outputChannelLogger: OutputChannelLogger,
|
||||
private telemetryReporter: TelemetryReporter
|
||||
) {
|
||||
this.disposables = Commands.map(({ commandId, key, method, options }) => {
|
||||
@@ -328,11 +328,25 @@ export class CommandCenter {
|
||||
|
||||
@command('git.setLogLevel')
|
||||
async setLogLevel(): Promise<void> {
|
||||
const createItem = (logLevel: LogLevel) => ({
|
||||
label: LogLevel[logLevel],
|
||||
logLevel,
|
||||
description: Log.logLevel === logLevel ? localize('current', "Current") : undefined
|
||||
});
|
||||
const createItem = (logLevel: LogLevel) => {
|
||||
let description: string | undefined;
|
||||
const defaultDescription = localize('default', "Default");
|
||||
const currentDescription = localize('current', "Current");
|
||||
|
||||
if (logLevel === this.outputChannelLogger.defaultLogLevel && logLevel === this.outputChannelLogger.currentLogLevel) {
|
||||
description = `${defaultDescription} & ${currentDescription} `;
|
||||
} else if (logLevel === this.outputChannelLogger.defaultLogLevel) {
|
||||
description = defaultDescription;
|
||||
} else if (logLevel === this.outputChannelLogger.currentLogLevel) {
|
||||
description = currentDescription;
|
||||
}
|
||||
|
||||
return {
|
||||
label: LogLevel[logLevel],
|
||||
logLevel,
|
||||
description
|
||||
};
|
||||
};
|
||||
|
||||
const items = [
|
||||
createItem(LogLevel.Trace),
|
||||
@@ -352,8 +366,7 @@ export class CommandCenter {
|
||||
return;
|
||||
}
|
||||
|
||||
Log.logLevel = choice.logLevel;
|
||||
this.outputChannel.appendLine(localize('changed', "{0} Log level changed to: {1}", logTimestamp(), LogLevel[Log.logLevel]));
|
||||
this.outputChannelLogger.setLogLevel(choice.logLevel);
|
||||
}
|
||||
|
||||
@command('git.refresh', { repository: true })
|
||||
@@ -820,14 +833,14 @@ export class CommandCenter {
|
||||
|
||||
@command('git.stage')
|
||||
async stage(...resourceStates: SourceControlResourceState[]): Promise<void> {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} git.stage ${resourceStates.length}`);
|
||||
this.outputChannelLogger.logDebug(`git.stage ${resourceStates.length} `);
|
||||
|
||||
resourceStates = resourceStates.filter(s => !!s);
|
||||
|
||||
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
|
||||
const resource = this.getSCMResource();
|
||||
|
||||
this.outputChannel.appendLine(`${logTimestamp()} git.stage.getSCMResource ${resource ? resource.resourceUri.toString() : null}`);
|
||||
this.outputChannelLogger.logDebug(`git.stage.getSCMResource ${resource ? resource.resourceUri.toString() : null} `);
|
||||
|
||||
if (!resource) {
|
||||
return;
|
||||
@@ -870,7 +883,7 @@ export class CommandCenter {
|
||||
const untracked = selection.filter(s => s.resourceGroupType === ResourceGroupType.Untracked);
|
||||
const scmResources = [...workingTree, ...untracked, ...resolved, ...unresolved];
|
||||
|
||||
this.outputChannel.appendLine(`${logTimestamp()} git.stage.scmResources ${scmResources.length}`);
|
||||
this.outputChannelLogger.logDebug(`git.stage.scmResources ${scmResources.length} `);
|
||||
if (!scmResources.length) {
|
||||
return;
|
||||
}
|
||||
@@ -2809,8 +2822,8 @@ export class CommandCenter {
|
||||
|
||||
const choices = new Map<string, () => void>();
|
||||
const openOutputChannelChoice = localize('open git log', "Open Git Log");
|
||||
const outputChannel = this.outputChannel as OutputChannel;
|
||||
choices.set(openOutputChannelChoice, () => outputChannel.show());
|
||||
const outputChannelLogger = this.outputChannelLogger;
|
||||
choices.set(openOutputChannelChoice, () => outputChannelLogger.showOutputChannel());
|
||||
|
||||
const showCommandOutputChoice = localize('show command output', "Show Command Output");
|
||||
if (err.stderr) {
|
||||
@@ -2913,10 +2926,10 @@ export class CommandCenter {
|
||||
private getSCMResource(uri?: Uri): Resource | undefined {
|
||||
uri = uri ? uri : (window.activeTextEditor && window.activeTextEditor.document.uri);
|
||||
|
||||
this.outputChannel.appendLine(`${logTimestamp()} git.getSCMResource.uri ${uri && uri.toString()}`);
|
||||
this.outputChannelLogger.logDebug(`git.getSCMResource.uri ${uri && uri.toString()}`);
|
||||
|
||||
for (const r of this.model.repositories.map(r => r.root)) {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} repo root ${r}`);
|
||||
this.outputChannelLogger.logDebug(`repo root ${r}`);
|
||||
}
|
||||
|
||||
if (!uri) {
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, EventEmitter } from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { commands, Disposable, Event, EventEmitter, OutputChannel, window, workspace } from 'vscode';
|
||||
import { dispose } from './util';
|
||||
|
||||
/**
|
||||
* The severity level of a log message
|
||||
@@ -18,33 +22,93 @@ export enum LogLevel {
|
||||
Off = 7
|
||||
}
|
||||
|
||||
let _logLevel: LogLevel = LogLevel.Info;
|
||||
const _onDidChangeLogLevel = new EventEmitter<LogLevel>();
|
||||
/**
|
||||
* Output channel logger
|
||||
*/
|
||||
export class OutputChannelLogger {
|
||||
|
||||
export const Log = {
|
||||
/**
|
||||
* Current logging level.
|
||||
*/
|
||||
get logLevel(): LogLevel {
|
||||
return _logLevel;
|
||||
},
|
||||
private _onDidChangeLogLevel = new EventEmitter<LogLevel>();
|
||||
readonly onDidChangeLogLevel: Event<LogLevel> = this._onDidChangeLogLevel.event;
|
||||
|
||||
/**
|
||||
* Current logging level.
|
||||
*/
|
||||
set logLevel(logLevel: LogLevel) {
|
||||
if (_logLevel === logLevel) {
|
||||
private _currentLogLevel: LogLevel;
|
||||
get currentLogLevel(): LogLevel {
|
||||
return this._currentLogLevel;
|
||||
}
|
||||
|
||||
private _defaultLogLevel: LogLevel;
|
||||
get defaultLogLevel(): LogLevel {
|
||||
return this._defaultLogLevel;
|
||||
}
|
||||
|
||||
private _outputChannel: OutputChannel;
|
||||
private _disposables: Disposable[] = [];
|
||||
|
||||
constructor() {
|
||||
// Output channel
|
||||
this._outputChannel = window.createOutputChannel('Git');
|
||||
commands.registerCommand('git.showOutput', () => this.showOutputChannel());
|
||||
this._disposables.push(this._outputChannel);
|
||||
|
||||
// Initialize log level
|
||||
const config = workspace.getConfiguration('git');
|
||||
const logLevel: keyof typeof LogLevel = config.get('logLevel', 'Info');
|
||||
this._currentLogLevel = this._defaultLogLevel = LogLevel[logLevel] ?? LogLevel.Info;
|
||||
|
||||
this.logInfo(localize('gitLogLevel', "Log level: {0}", LogLevel[this._currentLogLevel]));
|
||||
}
|
||||
|
||||
private log(message: string, logLevel: LogLevel): void {
|
||||
if (logLevel < this._currentLogLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
_logLevel = logLevel;
|
||||
_onDidChangeLogLevel.fire(logLevel);
|
||||
},
|
||||
|
||||
/**
|
||||
* An [event](#Event) that fires when the log level has changed.
|
||||
*/
|
||||
get onDidChangeLogLevel(): Event<LogLevel> {
|
||||
return _onDidChangeLogLevel.event;
|
||||
this._outputChannel.appendLine(`[${new Date().toISOString()}] [${LogLevel[logLevel].toLowerCase()}] ${message}`);
|
||||
}
|
||||
};
|
||||
|
||||
logCritical(message: string): void {
|
||||
this.log(message, LogLevel.Critical);
|
||||
}
|
||||
|
||||
logDebug(message: string): void {
|
||||
this.log(message, LogLevel.Debug);
|
||||
}
|
||||
|
||||
logError(message: string): void {
|
||||
this.log(message, LogLevel.Error);
|
||||
}
|
||||
|
||||
logInfo(message: string): void {
|
||||
this.log(message, LogLevel.Info);
|
||||
}
|
||||
|
||||
logTrace(message: string): void {
|
||||
this.log(message, LogLevel.Trace);
|
||||
}
|
||||
|
||||
logWarning(message: string): void {
|
||||
this.log(message, LogLevel.Warning);
|
||||
}
|
||||
|
||||
logGitCommand(command: string): void {
|
||||
this._outputChannel.appendLine(`[${new Date().toISOString()}] ${command}`);
|
||||
}
|
||||
|
||||
setLogLevel(logLevel: LogLevel): void {
|
||||
if (this._currentLogLevel === logLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._currentLogLevel = logLevel;
|
||||
this._onDidChangeLogLevel.fire(logLevel);
|
||||
|
||||
this.logInfo(localize('changed', "Log level changed to: {0}", LogLevel[logLevel]));
|
||||
}
|
||||
|
||||
showOutputChannel(): void {
|
||||
this._outputChannel.show();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables = dispose(this._disposables);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { env, ExtensionContext, workspace, window, Disposable, commands, Uri, OutputChannel, version as vscodeVersion, WorkspaceFolder } from 'vscode';
|
||||
import { env, ExtensionContext, workspace, window, Disposable, commands, Uri, version as vscodeVersion, WorkspaceFolder } from 'vscode';
|
||||
import { findGit, Git, IGit } from './git';
|
||||
import { Model } from './model';
|
||||
import { CommandCenter } from './commands';
|
||||
import { GitFileSystemProvider } from './fileSystemProvider';
|
||||
import { GitDecorations } from './decorationProvider';
|
||||
import { Askpass } from './askpass';
|
||||
import { toDisposable, filterEvent, eventToPromise, logTimestamp } from './util';
|
||||
import { toDisposable, filterEvent, eventToPromise } from './util';
|
||||
import TelemetryReporter from '@vscode/extension-telemetry';
|
||||
import { GitExtension } from './api/git';
|
||||
import { GitProtocolHandler } from './protocolHandler';
|
||||
@@ -24,6 +24,7 @@ import * as os from 'os';
|
||||
import { GitTimelineProvider } from './timelineProvider';
|
||||
import { registerAPICommands } from './api/api1';
|
||||
import { TerminalEnvironmentManager } from './terminal';
|
||||
import { OutputChannelLogger } from './log';
|
||||
|
||||
const deactivateTasks: { (): Promise<any> }[] = [];
|
||||
|
||||
@@ -33,7 +34,7 @@ export async function deactivate(): Promise<any> {
|
||||
}
|
||||
}
|
||||
|
||||
async function createModel(context: ExtensionContext, outputChannel: OutputChannel, telemetryReporter: TelemetryReporter, disposables: Disposable[]): Promise<Model> {
|
||||
async function createModel(context: ExtensionContext, outputChannelLogger: OutputChannelLogger, telemetryReporter: TelemetryReporter, disposables: Disposable[]): Promise<Model> {
|
||||
const pathValue = workspace.getConfiguration('git').get<string | string[]>('path');
|
||||
let pathHints = Array.isArray(pathValue) ? pathValue : pathValue ? [pathValue] : [];
|
||||
|
||||
@@ -46,7 +47,7 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
|
||||
}
|
||||
|
||||
const info = await findGit(pathHints, gitPath => {
|
||||
outputChannel.appendLine(localize('validating', "{0} Validating found git in: {1}", logTimestamp(), gitPath));
|
||||
outputChannelLogger.logInfo(localize('validating', "Validating found git in: {0}", gitPath));
|
||||
if (excludes.length === 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -54,12 +55,12 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
|
||||
const normalized = path.normalize(gitPath).replace(/[\r\n]+$/, '');
|
||||
const skip = excludes.some(e => normalized.startsWith(e));
|
||||
if (skip) {
|
||||
outputChannel.appendLine(localize('skipped', "{0} Skipped found git in: {1}", logTimestamp(), gitPath));
|
||||
outputChannelLogger.logInfo(localize('skipped', "Skipped found git in: {0}", gitPath));
|
||||
}
|
||||
return !skip;
|
||||
});
|
||||
|
||||
const askpass = await Askpass.create(outputChannel, context.storagePath);
|
||||
const askpass = await Askpass.create(outputChannelLogger, context.storagePath);
|
||||
disposables.push(askpass);
|
||||
|
||||
const environment = askpass.getEnv();
|
||||
@@ -73,7 +74,7 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
|
||||
version: info.version,
|
||||
env: environment,
|
||||
});
|
||||
const model = new Model(git, askpass, context.globalState, outputChannel, telemetryReporter);
|
||||
const model = new Model(git, askpass, context.globalState, outputChannelLogger, telemetryReporter);
|
||||
disposables.push(model);
|
||||
|
||||
const onRepository = () => commands.executeCommand('setContext', 'gitOpenRepositoryCount', `${model.repositories.length}`);
|
||||
@@ -81,7 +82,7 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
|
||||
model.onDidCloseRepository(onRepository, null, disposables);
|
||||
onRepository();
|
||||
|
||||
outputChannel.appendLine(localize('using git', "{0} Using git {1} from {2}", logTimestamp(), info.version, info.path));
|
||||
outputChannelLogger.logInfo(localize('using git', "Using git {0} from {1}", info.version, info.path));
|
||||
|
||||
const onOutput = (str: string) => {
|
||||
const lines = str.split(/\r?\n/mg);
|
||||
@@ -90,12 +91,12 @@ async function createModel(context: ExtensionContext, outputChannel: OutputChann
|
||||
lines.pop();
|
||||
}
|
||||
|
||||
outputChannel.appendLine(`${logTimestamp()} ${lines.join('\n')}`);
|
||||
outputChannelLogger.logGitCommand(lines.join('\n'));
|
||||
};
|
||||
git.onOutput.addListener('log', onOutput);
|
||||
disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput)));
|
||||
|
||||
const cc = new CommandCenter(git, model, outputChannel, telemetryReporter);
|
||||
const cc = new CommandCenter(git, model, outputChannelLogger, telemetryReporter);
|
||||
disposables.push(
|
||||
cc,
|
||||
new GitFileSystemProvider(model),
|
||||
@@ -161,9 +162,8 @@ export async function _activate(context: ExtensionContext): Promise<GitExtension
|
||||
const disposables: Disposable[] = [];
|
||||
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
|
||||
|
||||
const outputChannel = window.createOutputChannel('Git');
|
||||
commands.registerCommand('git.showOutput', () => outputChannel.show());
|
||||
disposables.push(outputChannel);
|
||||
const outputChannelLogger = new OutputChannelLogger();
|
||||
disposables.push(outputChannelLogger);
|
||||
|
||||
const { name, version, aiKey } = require('../package.json') as { name: string; version: string; aiKey: string };
|
||||
const telemetryReporter = new TelemetryReporter(name, version, aiKey);
|
||||
@@ -177,12 +177,12 @@ export async function _activate(context: ExtensionContext): Promise<GitExtension
|
||||
const onEnabled = filterEvent(onConfigChange, () => workspace.getConfiguration('git', null).get<boolean>('enabled') === true);
|
||||
const result = new GitExtensionImpl();
|
||||
|
||||
eventToPromise(onEnabled).then(async () => result.model = await createModel(context, outputChannel, telemetryReporter, disposables));
|
||||
eventToPromise(onEnabled).then(async () => result.model = await createModel(context, outputChannelLogger, telemetryReporter, disposables));
|
||||
return result;
|
||||
}
|
||||
|
||||
try {
|
||||
const model = await createModel(context, outputChannel, telemetryReporter, disposables);
|
||||
const model = await createModel(context, outputChannelLogger, telemetryReporter, disposables);
|
||||
return new GitExtensionImpl(model);
|
||||
} catch (err) {
|
||||
if (!/Git installation not found/.test(err.message || '')) {
|
||||
@@ -190,7 +190,7 @@ export async function _activate(context: ExtensionContext): Promise<GitExtension
|
||||
}
|
||||
|
||||
console.warn(err.message);
|
||||
outputChannel.appendLine(`${logTimestamp()} ${err.message}`);
|
||||
outputChannelLogger.logWarning(err.message);
|
||||
|
||||
/* __GDPR__
|
||||
"git.missing" : {}
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, OutputChannel, commands } from 'vscode';
|
||||
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, commands } from 'vscode';
|
||||
import TelemetryReporter from '@vscode/extension-telemetry';
|
||||
import { Repository, RepositoryState } from './repository';
|
||||
import { memoize, sequentialize, debounce } from './decorators';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, pathEquals, toDisposable, eventToPromise, logTimestamp } from './util';
|
||||
import { dispose, anyEvent, filterEvent, isDescendant, pathEquals, toDisposable, eventToPromise } from './util';
|
||||
import { Git } from './git';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
@@ -18,7 +18,7 @@ import { Askpass } from './askpass';
|
||||
import { IPushErrorHandlerRegistry } from './pushError';
|
||||
import { ApiRepository } from './api/api1';
|
||||
import { IRemoteSourcePublisherRegistry } from './remotePublisher';
|
||||
import { Log, LogLevel } from './log';
|
||||
import { OutputChannelLogger } from './log';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -110,7 +110,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(readonly git: Git, private readonly askpass: Askpass, private globalState: Memento, private outputChannel: OutputChannel, private telemetryReporter: TelemetryReporter) {
|
||||
constructor(readonly git: Git, private readonly askpass: Askpass, private globalState: Memento, private outputChannelLogger: OutputChannelLogger, private telemetryReporter: TelemetryReporter) {
|
||||
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
|
||||
window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables);
|
||||
workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables);
|
||||
@@ -145,9 +145,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
const autoRepositoryDetection = config.get<boolean | 'subFolders' | 'openEditors'>('autoRepositoryDetection');
|
||||
|
||||
// Log repository scan settings
|
||||
if (Log.logLevel <= LogLevel.Trace) {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Trace: autoRepositoryDetection="${autoRepositoryDetection}"`);
|
||||
}
|
||||
this.outputChannelLogger.logTrace(`autoRepositoryDetection="${autoRepositoryDetection}"`);
|
||||
|
||||
if (autoRepositoryDetection !== true && autoRepositoryDetection !== 'subFolders') {
|
||||
return;
|
||||
@@ -352,15 +350,13 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
}
|
||||
|
||||
const dotGit = await this.git.getRepositoryDotGit(repositoryRoot);
|
||||
const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this, this.globalState, this.outputChannel, this.telemetryReporter);
|
||||
const repository = new Repository(this.git.open(repositoryRoot, dotGit), this, this, this.globalState, this.outputChannelLogger, this.telemetryReporter);
|
||||
|
||||
this.open(repository);
|
||||
repository.status(); // do not await this, we want SCM to know about the repo asap
|
||||
} catch (ex) {
|
||||
// noop
|
||||
if (Log.logLevel <= LogLevel.Trace) {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Trace: Opening repository for path='${repoPath}' failed; ex=${ex}`);
|
||||
}
|
||||
this.outputChannelLogger.logTrace(`Opening repository for path='${repoPath}' failed; ex=${ex}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +382,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
}
|
||||
|
||||
private open(repository: Repository): void {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Open repository: ${repository.root}`);
|
||||
this.outputChannelLogger.logInfo(`Open repository: ${repository.root}`);
|
||||
|
||||
const onDidDisappearRepository = filterEvent(repository.onDidChangeState, state => state === RepositoryState.Disposed);
|
||||
const disappearListener = onDidDisappearRepository(() => dispose());
|
||||
@@ -443,7 +439,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPushErrorHandlerR
|
||||
return;
|
||||
}
|
||||
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Close repository: ${repository.root}`);
|
||||
this.outputChannelLogger.logInfo(`Close repository: ${repository.root}`);
|
||||
openRepository.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, Tab, TabInputTextDiff, TabInputNotebookDiff, RelativePattern } from 'vscode';
|
||||
import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, Tab, TabInputTextDiff, TabInputNotebookDiff, RelativePattern } from 'vscode';
|
||||
import TelemetryReporter from '@vscode/extension-telemetry';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Branch, Change, ForcePushMode, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status, CommitOptions, BranchQuery, FetchOptions } from './api/git';
|
||||
@@ -14,9 +14,9 @@ import { debounce, memoize, throttle } from './decorators';
|
||||
import { Commit, GitError, Repository as BaseRepository, Stash, Submodule, LogFileOptions } from './git';
|
||||
import { StatusBarCommands } from './statusbar';
|
||||
import { toGitUri } from './uri';
|
||||
import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, logTimestamp, onceEvent, pathEquals, relativePath } from './util';
|
||||
import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, onceEvent, pathEquals, relativePath } from './util';
|
||||
import { IFileWatcher, watch } from './watch';
|
||||
import { Log, LogLevel } from './log';
|
||||
import { LogLevel, OutputChannelLogger } from './log';
|
||||
import { IPushErrorHandlerRegistry } from './pushError';
|
||||
import { ApiRepository } from './api/api1';
|
||||
import { IRemoteSourcePublisherRegistry } from './remotePublisher';
|
||||
@@ -504,10 +504,10 @@ class FileEventLogger {
|
||||
constructor(
|
||||
private onWorkspaceWorkingTreeFileChange: Event<Uri>,
|
||||
private onDotGitFileChange: Event<Uri>,
|
||||
private outputChannel: OutputChannel
|
||||
private outputChannelLogger: OutputChannelLogger
|
||||
) {
|
||||
this.logLevelDisposable = Log.onDidChangeLogLevel(this.onDidChangeLogLevel, this);
|
||||
this.onDidChangeLogLevel(Log.logLevel);
|
||||
this.logLevelDisposable = outputChannelLogger.onDidChangeLogLevel(this.onDidChangeLogLevel, this);
|
||||
this.onDidChangeLogLevel(outputChannelLogger.currentLogLevel);
|
||||
}
|
||||
|
||||
private onDidChangeLogLevel(level: LogLevel): void {
|
||||
@@ -518,8 +518,8 @@ class FileEventLogger {
|
||||
}
|
||||
|
||||
this.eventDisposable = combinedDisposable([
|
||||
this.onWorkspaceWorkingTreeFileChange(uri => this.outputChannel.appendLine(`${logTimestamp()} [debug] [wt] Change: ${uri.fsPath}`)),
|
||||
this.onDotGitFileChange(uri => this.outputChannel.appendLine(`${logTimestamp()} [debug] [.git] Change: ${uri.fsPath}`))
|
||||
this.onWorkspaceWorkingTreeFileChange(uri => this.outputChannelLogger.logDebug(`[wt] Change: ${uri.fsPath}`)),
|
||||
this.onDotGitFileChange(uri => this.outputChannelLogger.logDebug(`[.git] Change: ${uri.fsPath}`))
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@ class DotGitWatcher implements IFileWatcher {
|
||||
|
||||
constructor(
|
||||
private repository: Repository,
|
||||
private outputChannel: OutputChannel
|
||||
private outputChannelLogger: OutputChannelLogger
|
||||
) {
|
||||
const rootWatcher = watch(repository.dotGit.path);
|
||||
this.disposables.push(rootWatcher);
|
||||
@@ -570,9 +570,7 @@ class DotGitWatcher implements IFileWatcher {
|
||||
this.transientDisposables.push(upstreamWatcher);
|
||||
upstreamWatcher.event(this.emitter.fire, this.emitter, this.transientDisposables);
|
||||
} catch (err) {
|
||||
if (Log.logLevel <= LogLevel.Error) {
|
||||
this.outputChannel.appendLine(`${logTimestamp()} Warning: Failed to watch ref '${upstreamPath}', is most likely packed.`);
|
||||
}
|
||||
this.outputChannelLogger.logWarning(`Failed to watch ref '${upstreamPath}', is most likely packed.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,7 +855,7 @@ export class Repository implements Disposable {
|
||||
private pushErrorHandlerRegistry: IPushErrorHandlerRegistry,
|
||||
remoteSourcePublisherRegistry: IRemoteSourcePublisherRegistry,
|
||||
globalState: Memento,
|
||||
outputChannel: OutputChannel,
|
||||
outputChannelLogger: OutputChannelLogger,
|
||||
private telemetryReporter: TelemetryReporter
|
||||
) {
|
||||
const repositoryWatcher = workspace.createFileSystemWatcher(new RelativePattern(Uri.file(repository.root), '**'));
|
||||
@@ -869,13 +867,11 @@ export class Repository implements Disposable {
|
||||
let onRepositoryDotGitFileChange: Event<Uri>;
|
||||
|
||||
try {
|
||||
const dotGitFileWatcher = new DotGitWatcher(this, outputChannel);
|
||||
const dotGitFileWatcher = new DotGitWatcher(this, outputChannelLogger);
|
||||
onRepositoryDotGitFileChange = dotGitFileWatcher.event;
|
||||
this.disposables.push(dotGitFileWatcher);
|
||||
} catch (err) {
|
||||
if (Log.logLevel <= LogLevel.Error) {
|
||||
outputChannel.appendLine(`${logTimestamp()} Failed to watch path:'${this.dotGit.path}' or commonPath:'${this.dotGit.commonPath}', reverting to legacy API file watched. Some events might be lost.\n${err.stack || err}`);
|
||||
}
|
||||
outputChannelLogger.logError(`Failed to watch path:'${this.dotGit.path}' or commonPath:'${this.dotGit.commonPath}', reverting to legacy API file watched. Some events might be lost.\n${err.stack || err}`);
|
||||
|
||||
onRepositoryDotGitFileChange = filterEvent(onRepositoryFileChange, uri => /\.git($|\/)/.test(uri.path));
|
||||
}
|
||||
@@ -889,7 +885,7 @@ export class Repository implements Disposable {
|
||||
// Relevate repository changes should trigger virtual document change events
|
||||
onRepositoryDotGitFileChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables);
|
||||
|
||||
this.disposables.push(new FileEventLogger(onRepositoryWorkingTreeFileChange, onRepositoryDotGitFileChange, outputChannel));
|
||||
this.disposables.push(new FileEventLogger(onRepositoryWorkingTreeFileChange, onRepositoryDotGitFileChange, outputChannelLogger));
|
||||
|
||||
const root = Uri.file(repository.root);
|
||||
this._sourceControl = scm.createSourceControl('git', 'Git', root);
|
||||
|
||||
@@ -16,10 +16,6 @@ export function log(...args: any[]): void {
|
||||
console.log.apply(console, ['git:', ...args]);
|
||||
}
|
||||
|
||||
export function logTimestamp(): string {
|
||||
return `[${new Date().toISOString()}]`;
|
||||
}
|
||||
|
||||
export interface IDisposable {
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user