Browse Source

Fixes versioned files not working

main
Eric Amodio 6 years ago
parent
commit
64c8bd46c9
4 changed files with 56 additions and 27 deletions
  1. +1
    -1
      src/commands/common.ts
  2. +19
    -6
      src/git/gitUri.ts
  3. +14
    -8
      src/gitService.ts
  4. +22
    -12
      src/trackers/documentTracker.ts

+ 1
- 1
src/commands/common.ts View File

@ -295,7 +295,7 @@ export async function openEditor(uri: Uri, options: TextDocumentShowOptions & {
const { rethrow, ...opts } = options;
try {
if (uri instanceof GitUri) {
uri = uri.fileUri(false);
uri = uri.fileUri({ noSha: true });
}
const document = await workspace.openTextDocument(uri);

+ 19
- 6
src/git/gitUri.ts View File

@ -10,6 +10,7 @@ export interface IGitCommitInfo {
fileName?: string;
repoPath: string;
sha?: string;
versionedPath?: string;
}
// Taken from https://github.com/Microsoft/vscode/blob/master/src/vs/base/common/uri.ts#L331-L337
@ -30,8 +31,10 @@ interface UriEx {
export class GitUri extends ((Uri as any) as UriEx) {
repoPath?: string | undefined;
sha?: string | undefined;
repoPath?: string;
sha?: string;
versionedPath?: string;
constructor(uri?: Uri)
constructor(uri: Uri, commit: IGitCommitInfo);
@ -75,6 +78,7 @@ export class GitUri extends ((Uri as any) as UriEx) {
super({ scheme: uri.scheme, authority: authority, path: fsPath, query: uri.query, fragment: uri.fragment });
this.repoPath = commitOrRepoPath.repoPath;
this.versionedPath = commitOrRepoPath.versionedPath;
if (GitService.isStagedUncommitted(commitOrRepoPath.sha) || !GitService.isUncommitted(commitOrRepoPath.sha)) {
this.sha = commitOrRepoPath.sha;
}
@ -84,8 +88,10 @@ export class GitUri extends ((Uri as any) as UriEx) {
return this.sha && GitService.shortenSha(this.sha);
}
fileUri(useSha: boolean = true) {
return Uri.file(useSha && this.sha ? this.path : this.fsPath);
fileUri(options: { noSha?: boolean, useVersionedPath?: boolean } = {}) {
if (options.useVersionedPath && this.versionedPath !== undefined) return Uri.file(this.versionedPath);
return Uri.file(!options.noSha && this.sha ? this.path : this.fsPath);
}
getFormattedPath(separator: string = Strings.pad(GlyphChars.Dot, 2, 2), relativeTo?: string): string {
@ -190,8 +196,8 @@ export class GitUri extends ((Uri as any) as UriEx) {
} as IGitCommitInfo);
}
const gitUri = await Container.git.getGitUri(uri);
if (gitUri !== undefined) return gitUri;
const versionedUri = await Container.git.getVersionedUri(uri);
if (versionedUri !== undefined) return versionedUri;
return new GitUri(uri, await Container.git.getRepoPath(uri));
}
@ -240,6 +246,13 @@ export class GitUri extends ((Uri as any) as UriEx) {
return Strings.normalizePath(relativePath);
}
static toKey(fileName: string): string;
static toKey(uri: Uri): string;
static toKey(fileNameOrUri: string | Uri): string;
static toKey(fileNameOrUri: string | Uri): string {
return Strings.normalizePath(typeof fileNameOrUri === 'string' ? fileNameOrUri : fileNameOrUri.fsPath).toLowerCase();
}
static toRevisionUri(uri: GitUri): Uri;
static toRevisionUri(sha: string, fileName: string, repoPath: string): Uri;
static toRevisionUri(sha: string, status: IGitStatusFile, repoPath: string): Uri;

+ 14
- 8
src/gitService.ts View File

@ -4,7 +4,7 @@ import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, Range, TextE
import { configuration, IRemotesConfig } from './configuration';
import { CommandContext, DocumentSchemes, setCommandContext } from './constants';
import { Container } from './container';
import { CachedBlame, CachedDiff, CachedLog, DocumentTracker, GitDocumentState, TrackedDocument } from './trackers/documentTracker';
import { CachedBlame, CachedDiff, CachedLog, GitDocumentState, TrackedDocument } from './trackers/documentTracker';
import { RemoteProviderFactory, RemoteProviderMap } from './git/remotes/factory';
import { CommitFormatting, Git, GitAuthor, GitBlame, GitBlameCommit, GitBlameLine, GitBlameLines, GitBlameParser, GitBranch, GitBranchParser, GitCommit, GitCommitType, GitDiff, GitDiffChunkLine, GitDiffParser, GitDiffShortStat, GitLog, GitLogCommit, GitLogParser, GitRemote, GitRemoteParser, GitStash, GitStashParser, GitStatus, GitStatusFile, GitStatusParser, GitTag, GitTagParser, IGit, Repository } from './git/git';
import { GitUri, IGitCommitInfo } from './git/gitUri';
@ -45,12 +45,14 @@ export class GitService extends Disposable {
private _repositoriesLoadingPromise: Promise<void> | undefined;
private _suspended: boolean = false;
private readonly _trackedCache: Map<string, boolean | Promise<boolean>>;
private _versionedUriCache: Map<string, GitUri>;
constructor() {
super(() => this.dispose());
this._repositoryTree = TernarySearchTree.forPaths();
this._trackedCache = new Map();
this._versionedUriCache = new Map();
this._disposable = Disposable.from(
window.onDidChangeWindowState(this.onWindowStateChanged, this),
@ -65,6 +67,7 @@ export class GitService extends Disposable {
dispose() {
this._repositoryTree.forEach(r => r.dispose());
this._trackedCache.clear();
this._versionedUriCache.clear();
this._disposable && this._disposable.dispose();
}
@ -684,11 +687,6 @@ export class GitService extends Disposable {
return await Git.config_get(key, repoPath);
}
async getGitUri(uri: Uri) {
const doc = await Container.tracker.get(uri);
return doc !== undefined ? doc.uri : undefined;
}
async getDiffForFile(uri: GitUri, sha1?: string, sha2?: string): Promise<GitDiff | undefined> {
if (sha1 !== undefined && sha2 === undefined && uri.sha !== undefined) {
sha2 = uri.sha;
@ -1201,6 +1199,10 @@ export class GitService extends Disposable {
}
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 }));
return file;
}
@ -1210,6 +1212,10 @@ export class GitService extends Disposable {
return Git.show(repoPath, fileName, sha, { encoding: GitService.getEncoding(repoPath, fileName) });
}
getVersionedUri(uri: Uri) {
return this._versionedUriCache.get(GitUri.toKey(uri));
}
isTrackable(scheme: string): boolean;
isTrackable(uri: Uri): boolean;
isTrackable(schemeOruri: string | Uri): boolean {
@ -1233,7 +1239,7 @@ export class GitService extends Disposable {
let fileName: string;
if (typeof fileNameOrUri === 'string') {
[fileName, repoPath] = Git.splitPath(fileNameOrUri, repoPath);
cacheKey = DocumentTracker.toStateKey(fileNameOrUri);
cacheKey = GitUri.toKey(fileNameOrUri);
}
else {
if (!this.isTrackable(fileNameOrUri)) return false;
@ -1241,7 +1247,7 @@ export class GitService extends Disposable {
fileName = fileNameOrUri.fsPath;
repoPath = fileNameOrUri.repoPath;
sha = fileNameOrUri.sha;
cacheKey = DocumentTracker.toStateKey(fileName);
cacheKey = GitUri.toKey(fileName);
}
if (sha !== undefined) {

+ 22
- 12
src/trackers/documentTracker.ts View File

@ -1,8 +1,9 @@
'use strict';
import { Functions, IDeferrable, Strings } from './../system';
import { Functions, IDeferrable } from './../system';
import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, window, workspace } from 'vscode';
import { configuration } from './../configuration';
import { CommandContext, DocumentSchemes, isActiveDocument, isTextEditor, setCommandContext } from './../constants';
import { GitUri } from '../gitService';
import { DocumentBlameStateChangeEvent, TrackedDocument } from './trackedDocument';
export { CachedBlame, CachedDiff, CachedLog, GitDocumentState } from './gitDocumentState';
@ -47,6 +48,7 @@ export class DocumentTracker extends Disposable {
this._disposable = Disposable.from(
configuration.onDidChange(this.onConfigurationChanged, this),
window.onDidChangeActiveTextEditor(Functions.debounce(this.onActiveTextEditorChanged, 0), this),
// window.onDidChangeVisibleTextEditors(Functions.debounce(this.onVisibleEditorsChanged, 5000), this),
workspace.onDidChangeTextDocument(Functions.debounce(this.onTextDocumentChanged, 50), this),
workspace.onDidCloseTextDocument(this.onTextDocumentClosed, this),
workspace.onDidSaveTextDocument(this.onTextDocumentSaved, this)
@ -159,6 +161,15 @@ export class DocumentTracker extends Disposable {
}
}
// private onVisibleEditorsChanged(editors: TextEditor[]) {
// if (this._documentMap.size === 0) return;
// // If we have no visible editors, or no "real" visible editors reset our cache
// if (editors.length === 0 || editors.every(e => !isTextEditor(e))) {
// this.clear();
// }
// }
async add(fileName: string): Promise<TrackedDocument<T>>;
async add(document: TextDocument): Promise<TrackedDocument<T>>;
async add(uri: Uri): Promise<TrackedDocument<T>>;
@ -193,7 +204,7 @@ export class DocumentTracker extends Disposable {
has(uri: Uri): boolean;
has(key: string | TextDocument | Uri): boolean {
if (typeof key === 'string' || key instanceof Uri) {
key = DocumentTracker.toStateKey(key);
key = GitUri.toKey(key);
}
return this._documentMap.has(key);
}
@ -202,6 +213,9 @@ export class DocumentTracker extends Disposable {
if (typeof documentOrId === 'string') {
documentOrId = await workspace.openTextDocument(documentOrId);
}
else if (documentOrId instanceof GitUri) {
documentOrId = await workspace.openTextDocument(documentOrId.fileUri({ useVersionedPath: true }));
}
else if (documentOrId instanceof Uri) {
documentOrId = await workspace.openTextDocument(documentOrId);
}
@ -213,8 +227,11 @@ export class DocumentTracker extends Disposable {
}
private async _get(documentOrId: string | TextDocument | Uri) {
if (typeof documentOrId === 'string' || documentOrId instanceof Uri) {
documentOrId = DocumentTracker.toStateKey(documentOrId);
if (documentOrId instanceof GitUri) {
documentOrId = GitUri.toKey(documentOrId.fileUri({ useVersionedPath: true }));
}
else if (typeof documentOrId === 'string' || documentOrId instanceof Uri) {
documentOrId = GitUri.toKey(documentOrId);
}
const doc = this._documentMap.get(documentOrId);
@ -225,7 +242,7 @@ export class DocumentTracker extends Disposable {
}
private addCore(document: TextDocument): TrackedDocument<T> {
const key = DocumentTracker.toStateKey(document.uri);
const key = GitUri.toKey(document.uri);
// Always start out false, so we will fire the event if needed
const doc = new TrackedDocument<T>(document, key, false, {
@ -281,11 +298,4 @@ export class DocumentTracker extends Disposable {
this._dirtyStateChangedDebounced(e);
}
static toStateKey(fileName: string): string;
static toStateKey(uri: Uri): string;
static toStateKey(fileNameOrUri: string | Uri): string;
static toStateKey(fileNameOrUri: string | Uri): string {
return Strings.normalizePath(typeof fileNameOrUri === 'string' ? fileNameOrUri : fileNameOrUri.fsPath).toLowerCase();
}
}

Loading…
Cancel
Save