diff --git a/extensions/git/src/contentProvider.ts b/extensions/git/src/contentProvider.ts index a0dfec226bf..2e6614936fc 100644 --- a/extensions/git/src/contentProvider.ts +++ b/extensions/git/src/contentProvider.ts @@ -6,8 +6,7 @@ 'use strict'; import { workspace, Uri, Disposable, Event, EventEmitter } from 'vscode'; -import * as path from 'path'; -import { Git } from './git'; +import { Model } from './model'; export class GitContentProvider { @@ -18,7 +17,7 @@ export class GitContentProvider { private uris = new Set(); - constructor(private git: Git, private rootPath: string, onGitChange: Event) { + constructor(private model: Model, onGitChange: Event) { this.disposables.push( onGitChange(this.fireChangeEvents, this), workspace.registerTextDocumentContentProvider('git', this) @@ -32,19 +31,10 @@ export class GitContentProvider { } async provideTextDocumentContent(uri: Uri): Promise { - const treeish = uri.query; - const relativePath = path.relative(this.rootPath, uri.fsPath).replace(/\\/g, '/'); - try { - const result = await this.git.exec(this.rootPath, ['show', `${treeish}:${relativePath}`]); - - if (result.exitCode !== 0) { - this.uris.delete(uri); - return ''; - } - + const result = await this.model.show(uri.query, uri); this.uris.add(uri); - return result.stdout; + return result; } catch (err) { this.uris.delete(uri); return ''; diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index 058f8130e2c..8078e3c098f 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -50,7 +50,7 @@ async function init(disposables: Disposable[]): Promise { const commitHandler = new CommitController(); const commandCenter = new CommandCenter(model, outputChannel); const provider = new GitSCMProvider(model, commandCenter); - const contentProvider = new GitContentProvider(git, rootPath, onGitChange); + const contentProvider = new GitContentProvider(model, onGitChange); const checkoutStatusBar = new CheckoutStatusBar(model); const syncStatusBar = new SyncStatusBar(model); const autoFetcher = new AutoFetcher(model); diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index fc8d4be84de..06ec7f21ac8 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -6,7 +6,7 @@ 'use strict'; import { Uri, EventEmitter, Event, SCMResource, SCMResourceDecorations, SCMResourceGroup, Disposable, window, workspace } from 'vscode'; -import { Repository, Ref, Branch, Remote, PushOptions, Commit, GitErrorCodes } from './git'; +import { Repository, Ref, Branch, Remote, PushOptions, Commit, GitErrorCodes, GitError } from './git'; import { anyEvent, eventToPromise, filterEvent, mapEvent, EmptyDisposable, combinedDisposable } from './util'; import { memoize, throttle, debounce } from './decorators'; import { watch } from './watch'; @@ -182,7 +182,7 @@ export enum Operation { Push = 1 << 10, Sync = 1 << 11, Init = 1 << 12, - UpdateModel = 1 << 13 + Show = 1 << 13 } export interface Operations { @@ -421,22 +421,40 @@ export class Model implements Disposable { await this.run(Operation.Sync, () => this.repository.sync()); } - private async run(operation: Operation, runOperation: () => Promise = () => Promise.resolve()): Promise { + @throttle + async show(ref: string, uri: Uri): Promise { + return await this.run(Operation.Show, async () => { + const relativePath = path.relative(this.repositoryRoot, uri.fsPath).replace(/\\/g, '/'); + const result = await this.repository.git.exec(this.repositoryRoot, ['show', `${ref}:${relativePath}`]); + + if (result.exitCode !== 0) { + throw new GitError({ + message: localize('cantshow', "Could not show object"), + exitCode: result.exitCode + }); + } + + return result.stdout; + }); + } + + private async run(operation: Operation, runOperation: () => Promise = () => Promise.resolve(null)): Promise { return window.withScmProgress(async () => { this._operations = this._operations.start(operation); this._onRunOperation.fire(operation); try { await this.assertIdleState(); - await runOperation(); + const result = await runOperation(); await this.update(); + return result; } catch (err) { if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) { this.repositoryDisposable.dispose(); this.state = State.NotAGitRepository; - } else { - throw err; } + + throw err; } finally { this._operations = this._operations.end(operation); this._onDidRunOperation.fire(operation);