Browse Source

Fixes errors with renamed/deleted files

Adds a new "missing" document to allow the tracker to track these files
main
Eric Amodio 7 years ago
parent
commit
7cd0eb5b3c
3 changed files with 95 additions and 24 deletions
  1. +13
    -11
      src/gitService.ts
  2. +80
    -11
      src/trackers/documentTracker.ts
  3. +2
    -2
      src/trackers/trackedDocument.ts

+ 13
- 11
src/gitService.ts View File

@ -936,7 +936,7 @@ export class GitService extends Disposable {
key += `:n${options.maxCount}`;
}
const doc = await Container.tracker.getOrAdd(fileName);
const doc = await Container.tracker.getOrAdd(new GitUri(Uri.file(fileName), { repoPath: repoPath!, sha: options.ref }));
if (this.UseCaching && options.range === undefined && !options.reverse) {
if (doc.state !== undefined) {
const cachedLog = doc.state.get<CachedLog>(key);
@ -1089,13 +1089,13 @@ export class GitService extends Disposable {
}
}
async getRepoPath(filePath: string): Promise<string | undefined>;
async getRepoPath(uri: Uri | undefined): Promise<string | undefined>;
async getRepoPath(filePathOrUri: string | Uri | undefined): Promise<string | undefined> {
async getRepoPath(filePath: string, options?: { ref?: string, skipTrackingCheck?: boolean }): Promise<string | undefined>;
async getRepoPath(uri: Uri | undefined, options?: { ref?: string, skipTrackingCheck?: boolean }): Promise<string | undefined>;
async getRepoPath(filePathOrUri: string | Uri | undefined, options: { ref?: string, skipTrackingCheck?: boolean } = {}): Promise<string | undefined> {
if (filePathOrUri === undefined) return await this.getActiveRepoPath();
if (filePathOrUri instanceof GitUri) return filePathOrUri.repoPath;
const repo = await this.getRepository(filePathOrUri);
const repo = await this.getRepository(filePathOrUri, options);
if (repo !== undefined) return repo.path;
const rp = await this.getRepoPathCore(typeof filePathOrUri === 'string' ? filePathOrUri : filePathOrUri.fsPath, false);
@ -1149,10 +1149,10 @@ export class GitService extends Disposable {
return this._repositoryTree;
}
async getRepository(repoPath: string): Promise<Repository | undefined>;
async getRepository(uri: Uri): Promise<Repository | undefined>;
async getRepository(repoPathOrUri: string | Uri): Promise<Repository | undefined>;
async getRepository(repoPathOrUri: string | Uri): Promise<Repository | undefined> {
async getRepository(repoPath: string, options?: { ref?: string, skipTrackingCheck?: boolean }): Promise<Repository | undefined>;
async getRepository(uri: Uri, options?: { ref?: string, skipTrackingCheck?: boolean }): Promise<Repository | undefined>;
async getRepository(repoPathOrUri: string | Uri, options?: { ref?: string, skipTrackingCheck?: boolean }): Promise<Repository | undefined>;
async getRepository(repoPathOrUri: string | Uri, options: { ref?: string, skipTrackingCheck?: boolean } = {}): Promise<Repository | undefined> {
const repositoryTree = await this.getRepositoryTree();
let path: string;
@ -1179,8 +1179,10 @@ export class GitService extends Disposable {
const repo = repositoryTree.findSubstr(path);
if (repo === undefined) return undefined;
// Make sure the file is tracked in that repo, before returning
if (!await this.isTrackedCore(repo.path, path)) return undefined;
if (!options.skipTrackingCheck) {
// Make sure the file is tracked in that repo, before returning
if (!await this.isTrackedCore(repo.path, path, options.ref)) return undefined;
}
return repo;
}

+ 80
- 11
src/trackers/documentTracker.ts View File

@ -1,6 +1,6 @@
'use strict';
import { Functions, IDeferrable } from './../system';
import { ConfigurationChangeEvent, Disposable, Event, EventEmitter, TextDocument, TextDocumentChangeEvent, TextEditor, Uri, window, workspace } from 'vscode';
import { ConfigurationChangeEvent, Disposable, EndOfLine, Event, EventEmitter, Position, Range, TextDocument, TextDocumentChangeEvent, TextEditor, TextLine, Uri, window, workspace } from 'vscode';
import { configuration } from './../configuration';
import { CommandContext, DocumentSchemes, isActiveDocument, isTextEditor, setCommandContext } from './../constants';
import { GitUri } from '../gitService';
@ -174,10 +174,9 @@ export class DocumentTracker extends Disposable {
// }
// }
async add(fileName: string): Promise<TrackedDocument<T>>;
async add(document: TextDocument): Promise<TrackedDocument<T>>;
async add(uri: Uri): Promise<TrackedDocument<T>>;
async add(documentOrId: string | TextDocument | Uri): Promise<TrackedDocument<T>> {
async add(documentOrId: TextDocument | Uri): Promise<TrackedDocument<T>> {
return this._add(documentOrId);
}
@ -196,10 +195,9 @@ export class DocumentTracker extends Disposable {
return await this._get(documentOrId);
}
async getOrAdd(fileName: string): Promise<TrackedDocument<T>>;
async getOrAdd(document: TextDocument): Promise<TrackedDocument<T>>;
async getOrAdd(uri: Uri): Promise<TrackedDocument<T>>;
async getOrAdd(documentOrId: string | TextDocument | Uri): Promise<TrackedDocument<T>> {
async getOrAdd(documentOrId: TextDocument | Uri): Promise<TrackedDocument<T>> {
return await this._get(documentOrId) || await this._add(documentOrId);
}
@ -213,12 +211,22 @@ export class DocumentTracker extends Disposable {
return this._documentMap.has(key);
}
private async _add(documentOrId: string | TextDocument | Uri): Promise<TrackedDocument<T>> {
if (typeof documentOrId === 'string') {
documentOrId = await workspace.openTextDocument(documentOrId);
}
else if (documentOrId instanceof GitUri) {
documentOrId = await workspace.openTextDocument(documentOrId.fileUri({ useVersionedPath: true }));
private async _add(documentOrId: TextDocument | Uri): Promise<TrackedDocument<T>> {
if (documentOrId instanceof GitUri) {
try {
documentOrId = await workspace.openTextDocument(documentOrId.fileUri({ useVersionedPath: true }));
}
catch (ex) {
if (!ex.toString().includes('File not found')) throw ex;
// If we can't find the file, assume it is because the file has been renamed or deleted at some point
documentOrId = new MissingRevisionTextDocument(documentOrId);
// const [fileName, repoPath] = await Container.git.findWorkingFileName(documentOrId, undefined, ref);
// if (fileName === undefined) throw new Error(`Failed to add tracking for document: ${documentOrId}`);
// documentOrId = await workspace.openTextDocument(path.resolve(repoPath!, fileName));
}
}
else if (documentOrId instanceof Uri) {
documentOrId = await workspace.openTextDocument(documentOrId);
@ -303,3 +311,64 @@ export class DocumentTracker extends Disposable {
this._dirtyStateChangedDebounced(e);
}
}
class MissingRevisionTextDocument implements TextDocument {
readonly eol: EndOfLine;
readonly fileName: string;
readonly isClosed: boolean;
readonly isDirty: boolean;
readonly isUntitled: boolean;
readonly languageId: string;
readonly lineCount: number;
readonly uri: Uri;
readonly version: number;
constructor(
public readonly gitUri: GitUri
) {
this.uri = gitUri.fileUri({ useVersionedPath: true });
this.eol = EndOfLine.LF;
this.fileName = this.uri.fsPath;
this.isClosed = false;
this.isDirty = false;
this.isUntitled = false;
this.lineCount = 0;
this.version = 0;
}
getText(range?: Range | undefined): string {
throw new Error('Method not supported.');
}
getWordRangeAtPosition(position: Position, regex?: RegExp | undefined): Range | undefined {
throw new Error('Method not supported.');
}
lineAt(line: number): TextLine;
lineAt(position: Position): TextLine;
lineAt(position: any): TextLine {
throw new Error('Method not supported.');
}
offsetAt(position: Position): number {
throw new Error('Method not supported.');
}
positionAt(offset: number): Position {
throw new Error('Method not supported.');
}
save(): Thenable<boolean> {
throw new Error('Method not supported.');
}
validatePosition(position: Position): Position {
throw new Error('Method not supported.');
}
validateRange(range: Range): Range {
throw new Error('Method not supported.');
}
}

+ 2
- 2
src/trackers/trackedDocument.ts View File

@ -145,7 +145,7 @@ export class TrackedDocument extends Disposable {
this._blameFailed = true;
if (wasBlameable && isActiveDocument(this.document)) {
if (wasBlameable && isActiveDocument(this._document)) {
this.update({ forceBlameChange: true});
}
}
@ -168,7 +168,7 @@ export class TrackedDocument extends Disposable {
this._isDirtyIdle = false;
const active = getEditorIfActive(this.document);
const active = getEditorIfActive(this._document);
const wasBlameable = options.forceBlameChange ? undefined : this.isBlameable;
this._isTracked = await Container.git.isTracked(this._uri);

Loading…
Cancel
Save