Browse Source

Fixes #430 - Use content provider instead of tmp files (for text docs)

main
Eric Amodio 6 years ago
parent
commit
0f2f79fca7
12 changed files with 57 additions and 139 deletions
  1. +1
    -0
      CHANGELOG.md
  2. +2
    -2
      src/codelens/gitCodeLensProvider.ts
  3. +0
    -91
      src/codelens/gitRevisionCodeLensProvider.ts
  4. +8
    -11
      src/commands/common.ts
  5. +2
    -2
      src/commands/diffWithWorking.ts
  6. +11
    -1
      src/constants.ts
  7. +0
    -4
      src/container.ts
  8. +7
    -8
      src/git/gitUri.ts
  9. +6
    -6
      src/git/models/repository.ts
  10. +5
    -3
      src/gitContentProvider.ts
  11. +12
    -8
      src/gitService.ts
  12. +3
    -3
      src/trackers/documentTracker.ts

+ 1
- 0
CHANGELOG.md View File

@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
### Fixed ### Fixed
- Fixes [#405](https://github.com/eamodio/vscode-gitlens/issues/405) - Secondary, blank repository appears repeatedly in gitExplorer view - Fixes [#405](https://github.com/eamodio/vscode-gitlens/issues/405) - Secondary, blank repository appears repeatedly in gitExplorer view
- Fixes [#430](https://github.com/eamodio/vscode-gitlens/issues/430) - File revisions can end up being parsed by language servers (causing errors and warnings, etc)
- Fixes issues with git log caching - Fixes issues with git log caching
### Removed ### Removed

+ 2
- 2
src/codelens/gitCodeLensProvider.ts View File

@ -222,7 +222,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
gitUri.getFilename(), gitUri.getFilename(),
SymbolKind.File, SymbolKind.File,
'', '',
new Location(gitUri.fileUri(), new Range(0, 0, 0, blameRange.start.character))
new Location(gitUri.documentUri(), new Range(0, 0, 0, blameRange.start.character))
); );
lenses.push( lenses.push(
new GitRecentChangeCodeLens( new GitRecentChangeCodeLens(
@ -249,7 +249,7 @@ export class GitCodeLensProvider implements CodeLensProvider {
gitUri.getFilename(), gitUri.getFilename(),
SymbolKind.File, SymbolKind.File,
'', '',
new Location(gitUri.fileUri(), new Range(0, 1, 0, blameRange.start.character))
new Location(gitUri.documentUri(), new Range(0, 1, 0, blameRange.start.character))
); );
lenses.push( lenses.push(
new GitAuthorsCodeLens( new GitAuthorsCodeLens(

+ 0
- 91
src/codelens/gitRevisionCodeLensProvider.ts View File

@ -1,91 +0,0 @@
'use strict';
import { CancellationToken, CodeLens, CodeLensProvider, DocumentSelector, Range, TextDocument, Uri } from 'vscode';
import { Commands, DiffWithPreviousCommandArgs, DiffWithWorkingCommandArgs } from '../commands';
import { DocumentSchemes } from '../constants';
import { Container } from '../container';
import { GitCommit, GitUri } from '../gitService';
export class GitDiffWithWorkingCodeLens extends CodeLens {
constructor(
public readonly fileName: string,
public readonly commit: GitCommit,
range: Range
) {
super(range);
}
}
export class GitDiffWithPreviousCodeLens extends CodeLens {
constructor(
public readonly fileName: string,
public readonly commit: GitCommit,
range: Range
) {
super(range);
}
}
export class GitRevisionCodeLensProvider implements CodeLensProvider {
static selector: DocumentSelector = { scheme: DocumentSchemes.GitLensGit };
async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise<CodeLens[]> {
const gitUri = GitUri.fromRevisionUri(document.uri);
const lenses: CodeLens[] = [];
const commit = await Container.git.getLogCommitForFile(gitUri.repoPath, gitUri.fsPath, {
ref: gitUri.sha,
firstIfNotFound: true
});
if (commit === undefined) return lenses;
if (commit.previousSha) {
lenses.push(new GitDiffWithPreviousCodeLens(commit.previousUri.fsPath, commit, new Range(0, 0, 0, 1)));
}
lenses.push(new GitDiffWithWorkingCodeLens(commit.uri.fsPath, commit, new Range(0, 1, 0, 2)));
return lenses;
}
resolveCodeLens(lens: CodeLens, token: CancellationToken): Thenable<CodeLens> {
if (lens instanceof GitDiffWithWorkingCodeLens) return this._resolveDiffWithWorkingTreeCodeLens(lens, token);
if (lens instanceof GitDiffWithPreviousCodeLens) return this._resolveGitDiffWithPreviousCodeLens(lens, token);
return Promise.reject<CodeLens>(undefined);
}
_resolveDiffWithWorkingTreeCodeLens(
lens: GitDiffWithWorkingCodeLens,
token: CancellationToken
): Thenable<CodeLens> {
lens.command = {
title: `Compare Revision (${lens.commit.shortSha}) with Working`,
command: Commands.DiffWithWorking,
arguments: [
Uri.file(lens.fileName),
{
commit: lens.commit,
line: lens.range.start.line
} as DiffWithWorkingCommandArgs
]
};
return Promise.resolve(lens);
}
_resolveGitDiffWithPreviousCodeLens(
lens: GitDiffWithPreviousCodeLens,
token: CancellationToken
): Thenable<CodeLens> {
lens.command = {
title: `Compare Revision (${lens.commit.shortSha}) with Previous (${lens.commit.previousShortSha})`,
command: Commands.DiffWithPrevious,
arguments: [
Uri.file(lens.fileName),
{
commit: lens.commit,
line: lens.range.start.line
} as DiffWithPreviousCommandArgs
]
};
return Promise.resolve(lens);
}
}

+ 8
- 11
src/commands/common.ts View File

@ -13,7 +13,7 @@ import {
window, window,
workspace workspace
} from 'vscode'; } from 'vscode';
import { BuiltInCommands, DocumentSchemes, ImageExtensions } from '../constants';
import { BuiltInCommands, DocumentSchemes, ImageMimetypes } from '../constants';
import { Container } from '../container'; import { Container } from '../container';
import { GitBranch, GitCommit, GitRemote, GitUri } from '../gitService'; import { GitBranch, GitCommit, GitRemote, GitUri } from '../gitService';
import { Logger } from '../logger'; import { Logger } from '../logger';
@ -394,21 +394,18 @@ export async function openEditor(
const { rethrow, ...opts } = options; const { rethrow, ...opts } = options;
try { try {
if (uri instanceof GitUri) { if (uri instanceof GitUri) {
uri = uri.fileUri({ noSha: true });
uri = uri.documentUri({ noSha: true });
} }
// TODO: revist this
// This is a bit of an ugly hack, but I added it because there a bunch of call sites and toRevisionUri can't be easily made async because of its use in ctors // This is a bit of an ugly hack, but I added it because there a bunch of call sites and toRevisionUri can't be easily made async because of its use in ctors
if (uri.scheme === DocumentSchemes.GitLensGit) {
if (uri.scheme === DocumentSchemes.GitLensGit && ImageMimetypes[path.extname(uri.fsPath)]) {
const gitUri = GitUri.fromRevisionUri(uri); const gitUri = GitUri.fromRevisionUri(uri);
if (ImageExtensions.includes(path.extname(gitUri.fsPath))) {
const uri = await Container.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha);
if (uri !== undefined) {
await commands.executeCommand(BuiltInCommands.Open, uri);
return undefined;
}
const imageUri = await Container.git.getVersionedFile(gitUri.repoPath, gitUri.fsPath, gitUri.sha);
if (imageUri !== undefined) {
await commands.executeCommand(BuiltInCommands.Open, imageUri);
} }
return undefined;
} }
const document = await workspace.openTextDocument(uri); const document = await workspace.openTextDocument(uri);

+ 2
- 2
src/commands/diffWithWorking.ts View File

@ -44,11 +44,11 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
repoPath: gitUri.repoPath, repoPath: gitUri.repoPath,
lhs: { lhs: {
sha: GitService.stagedUncommittedSha, sha: GitService.stagedUncommittedSha,
uri: gitUri.fileUri()
uri: gitUri.documentUri()
}, },
rhs: { rhs: {
sha: '', sha: '',
uri: gitUri.fileUri()
uri: gitUri.documentUri()
}, },
line: args.line, line: args.line,
showOptions: args.showOptions showOptions: args.showOptions

+ 11
- 1
src/constants.ts View File

@ -109,7 +109,17 @@ export enum GlobalState {
GitLensVersion = 'gitlensVersion' GitLensVersion = 'gitlensVersion'
} }
export const ImageExtensions = ['.png', '.gif', '.jpg', '.jpeg', '.webp', '.tif', '.tiff', '.bmp'];
export const ImageMimetypes: { [key: string]: string } = {
'.png': 'image/png',
'.gif': 'image/gif',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.jpe': 'image/jpeg',
'.webp': 'image/webp',
'.tif': 'image/tiff',
'.tiff': 'image/tiff',
'.bmp': 'image/bmp'
};
export enum WorkspaceState { export enum WorkspaceState {
GitExplorerAutoRefresh = 'gitlens:gitExplorer:autoRefresh', GitExplorerAutoRefresh = 'gitlens:gitExplorer:autoRefresh',

+ 0
- 4
src/container.ts View File

@ -3,7 +3,6 @@ import { Disposable, ExtensionContext, languages, workspace } from 'vscode';
import { FileAnnotationController } from './annotations/fileAnnotationController'; import { FileAnnotationController } from './annotations/fileAnnotationController';
import { LineAnnotationController } from './annotations/lineAnnotationController'; import { LineAnnotationController } from './annotations/lineAnnotationController';
import { CodeLensController } from './codelens/codeLensController'; import { CodeLensController } from './codelens/codeLensController';
import { GitRevisionCodeLensProvider } from './codelens/gitRevisionCodeLensProvider';
import { configuration, IConfig } from './configuration'; import { configuration, IConfig } from './configuration';
import { GitContentProvider } from './gitContentProvider'; import { GitContentProvider } from './gitContentProvider';
import { GitService } from './gitService'; import { GitService } from './gitService';
@ -69,9 +68,6 @@ export class Container {
context.subscriptions.push( context.subscriptions.push(
workspace.registerTextDocumentContentProvider(GitContentProvider.scheme, new GitContentProvider()) workspace.registerTextDocumentContentProvider(GitContentProvider.scheme, new GitContentProvider())
); );
context.subscriptions.push(
languages.registerCodeLensProvider(GitRevisionCodeLensProvider.selector, new GitRevisionCodeLensProvider())
);
} }
private static _codeLensController: CodeLensController; private static _codeLensController: CodeLensController;

+ 7
- 8
src/git/gitUri.ts View File

@ -33,7 +33,6 @@ interface UriEx {
export class GitUri extends ((Uri as any) as UriEx) { export class GitUri extends ((Uri as any) as UriEx) {
repoPath?: string; repoPath?: string;
sha?: string; sha?: string;
versionedPath?: string; versionedPath?: string;
constructor(uri?: Uri); constructor(uri?: Uri);
@ -94,16 +93,16 @@ export class GitUri extends ((Uri as any) as UriEx) {
return this.sha && GitService.shortenSha(this.sha); return this.sha && GitService.shortenSha(this.sha);
} }
equals(uri: Uri | undefined) {
if (!UriComparer.equals(this, uri)) return false;
documentUri(options: { noSha?: boolean; useVersionedPath?: boolean } = {}) {
if (options.useVersionedPath && this.versionedPath !== undefined) return Uri.file(this.versionedPath);
return this.sha === (uri instanceof GitUri ? uri.sha : undefined);
return this.scheme === 'file' ? Uri.file(!options.noSha && this.sha ? this.path : this.fsPath) : this;
} }
fileUri(options: { noSha?: boolean; useVersionedPath?: boolean } = {}) {
if (options.useVersionedPath && this.versionedPath !== undefined) return Uri.file(this.versionedPath);
equals(uri: Uri | undefined) {
if (!UriComparer.equals(this, uri)) return false;
return Uri.file(!options.noSha && this.sha ? this.path : this.fsPath);
return this.sha === (uri instanceof GitUri ? uri.sha : undefined);
} }
getDirectory(relativeTo?: string): string { getDirectory(relativeTo?: string): string {
@ -314,7 +313,7 @@ export class GitUri extends ((Uri as any) as UriEx) {
const parsed = path.parse(fileName); const parsed = path.parse(fileName);
return Uri.parse( return Uri.parse(
`${DocumentSchemes.GitLensGit}:${path.join(parsed.dir, parsed.name)}:${shortSha}${
`${DocumentSchemes.GitLensGit}:${path.join(parsed.dir, parsed.name)} (${shortSha})${
parsed.ext parsed.ext
}?${JSON.stringify(data)}` }?${JSON.stringify(data)}`
); );

+ 6
- 6
src/git/models/repository.ts View File

@ -218,13 +218,13 @@ export class Repository implements Disposable {
} }
} }
containsUri(uri: Uri) {
if (uri instanceof GitUri) {
uri = uri.repoPath !== undefined ? Uri.file(uri.repoPath) : uri.fileUri();
}
// containsUri(uri: Uri) {
// if (uri instanceof GitUri) {
// uri = uri.repoPath !== undefined ? Uri.file(uri.repoPath) : uri.documentUri();
// }
return this.folder === workspace.getWorkspaceFolder(uri);
}
// return this.folder === workspace.getWorkspaceFolder(uri);
// }
getBranch(): Promise<GitBranch | undefined> { getBranch(): Promise<GitBranch | undefined> {
if (this._branch === undefined) { if (this._branch === undefined) {

+ 5
- 3
src/gitContentProvider.ts View File

@ -1,8 +1,7 @@
'use strict'; 'use strict';
import * as path from 'path'; import * as path from 'path';
import { CancellationToken, TextDocumentContentProvider, Uri, window } from 'vscode';
import { CancellationToken, TextDocumentContentProvider, Uri, window, workspace } from 'vscode';
import { DocumentSchemes } from './constants'; import { DocumentSchemes } from './constants';
import { Container } from './container';
import { GitService, GitUri } from './gitService'; import { GitService, GitUri } from './gitService';
import { Logger } from './logger'; import { Logger } from './logger';
@ -14,7 +13,10 @@ export class GitContentProvider implements TextDocumentContentProvider {
if (!gitUri.repoPath || gitUri.sha === GitService.deletedSha) return ''; if (!gitUri.repoPath || gitUri.sha === GitService.deletedSha) return '';
try { try {
return await Container.git.getVersionedFileText(gitUri.repoPath, gitUri.fsPath, gitUri.sha || 'HEAD');
const document = await workspace.openTextDocument(
Uri.parse(`git:/${gitUri.fsPath}?${JSON.stringify({ path: gitUri.fsPath, ref: gitUri.sha || 'HEAD' })}`)
);
return document.getText();
} }
catch (ex) { catch (ex) {
Logger.error(ex, 'GitContentProvider', 'getVersionedFileText'); Logger.error(ex, 'GitContentProvider', 'getVersionedFileText');

+ 12
- 8
src/gitService.ts View File

@ -18,7 +18,7 @@ import {
} from 'vscode'; } from 'vscode';
import { GitExtension } from './@types/git'; import { GitExtension } from './@types/git';
import { configuration, IRemotesConfig } from './configuration'; import { configuration, IRemotesConfig } from './configuration';
import { CommandContext, DocumentSchemes, GlyphChars, setCommandContext } from './constants';
import { CommandContext, DocumentSchemes, GlyphChars, ImageMimetypes, setCommandContext } from './constants';
import { Container } from './container'; import { Container } from './container';
import { import {
CommitFormatting, CommitFormatting,
@ -1652,15 +1652,19 @@ export class GitService implements Disposable {
return undefined; return undefined;
} }
const file = await Git.getVersionedFile(repoPath, fileName, sha);
if (file === undefined) return undefined;
if (ImageMimetypes[path.extname(fileName)]) {
const file = await Git.getVersionedFile(repoPath, fileName, sha);
if (file === undefined) return undefined;
this._versionedUriCache.set(
GitUri.toKey(file),
new GitUri(Uri.file(fileName), { sha: sha, repoPath: repoPath!, versionedPath: file })
);
this._versionedUriCache.set(
GitUri.toKey(file),
new GitUri(Uri.file(fileName), { sha: sha, repoPath: repoPath!, versionedPath: file })
);
return Uri.file(file);
}
return Uri.file(file);
return GitUri.toRevisionUri(sha, fileName, repoPath!);
} }
getVersionedFileText(repoPath: string, fileName: string, sha: string) { getVersionedFileText(repoPath: string, fileName: string, sha: string) {

+ 3
- 3
src/trackers/documentTracker.ts View File

@ -238,7 +238,7 @@ export class DocumentTracker implements Disposable {
private async _add(documentOrId: TextDocument | Uri): Promise<TrackedDocument<T>> { private async _add(documentOrId: TextDocument | Uri): Promise<TrackedDocument<T>> {
if (documentOrId instanceof GitUri) { if (documentOrId instanceof GitUri) {
try { try {
documentOrId = await workspace.openTextDocument(documentOrId.fileUri({ useVersionedPath: true }));
documentOrId = await workspace.openTextDocument(documentOrId.documentUri({ useVersionedPath: true }));
} }
catch (ex) { catch (ex) {
const msg = ex.toString(); const msg = ex.toString();
@ -271,7 +271,7 @@ export class DocumentTracker implements Disposable {
private async _get(documentOrId: string | TextDocument | Uri) { private async _get(documentOrId: string | TextDocument | Uri) {
if (documentOrId instanceof GitUri) { if (documentOrId instanceof GitUri) {
documentOrId = GitUri.toKey(documentOrId.fileUri({ useVersionedPath: true }));
documentOrId = GitUri.toKey(documentOrId.documentUri({ useVersionedPath: true }));
} }
else if (typeof documentOrId === 'string' || documentOrId instanceof Uri) { else if (typeof documentOrId === 'string' || documentOrId instanceof Uri) {
documentOrId = GitUri.toKey(documentOrId); documentOrId = GitUri.toKey(documentOrId);
@ -366,7 +366,7 @@ class EmptyTextDocument implements TextDocument {
constructor( constructor(
public readonly gitUri: GitUri public readonly gitUri: GitUri
) { ) {
this.uri = gitUri.fileUri({ useVersionedPath: true });
this.uri = gitUri.documentUri({ useVersionedPath: true });
this.eol = EndOfLine.LF; this.eol = EndOfLine.LF;
this.fileName = this.uri.fsPath; this.fileName = this.uri.fsPath;

Loading…
Cancel
Save