Browse Source

Fixes issues with tracking renamed revisions

main
Eric Amodio 7 years ago
parent
commit
9f25ad5ce1
5 changed files with 49 additions and 17 deletions
  1. +7
    -2
      src/git/git.ts
  2. +1
    -1
      src/git/gitUri.ts
  3. +9
    -3
      src/git/models/repository.ts
  4. +29
    -9
      src/gitService.ts
  5. +3
    -2
      src/views/gitExplorer.ts

+ 7
- 2
src/git/git.ts View File

@ -370,9 +370,14 @@ export class Git {
return gitCommand({ cwd: repoPath }, ...params);
}
static async ls_files(repoPath: string, fileName: string): Promise<string> {
static async ls_files(repoPath: string, fileName: string, sha?: string): Promise<string> {
const params = [`ls-files`];
if (sha) {
params.push(`--with-tree=${sha}`);
}
try {
const data = await gitCommand({ cwd: repoPath, willHandleErrors: true }, 'ls-files', fileName);
const data = await gitCommand({ cwd: repoPath, willHandleErrors: true }, ...params, fileName);
return data.trim();
}
catch {

+ 1
- 1
src/git/gitUri.ts View File

@ -107,7 +107,7 @@ export class GitUri extends ((Uri as any) as UriEx) {
if (commit !== undefined) return new GitUri(uri, commit);
}
const gitUri = git.getGitUriForFile(uri);
const gitUri = git.getGitUriForVersionedFile(uri);
if (gitUri) return gitUri;
return new GitUri(uri, await git.getRepoPath(uri));

+ 9
- 3
src/git/models/repository.ts View File

@ -13,7 +13,7 @@ export class RepositoryChangeEvent {
readonly changes: RepositoryChange[] = [];
constructor(
public repository?: Repository
public readonly repository?: Repository
) { }
changed(change: RepositoryChange, solely: boolean = false) {
@ -33,8 +33,8 @@ export class RepositoryChangeEvent {
}
export interface RepositoryFileSystemChangeEvent {
repository?: Repository;
uris: Uri[];
readonly repository?: Repository;
readonly uris: Uri[];
}
export enum RepositoryStorage {
@ -168,6 +168,12 @@ export class Repository extends Disposable {
}
containsUri(uri: Uri) {
if (uri instanceof GitUri) {
uri = uri.repoPath !== undefined
? Uri.file(uri.repoPath)
: uri.fileUri();
}
return this.folder === workspace.getWorkspaceFolder(uri);
}

+ 29
- 9
src/gitService.ts View File

@ -588,7 +588,7 @@ export class GitService extends Disposable {
return await Git.config_get(key, repoPath);
}
getGitUriForFile(uri: Uri) {
getGitUriForVersionedFile(uri: Uri) {
const cacheKey = this.getCacheEntryKey(uri);
const entry = this._versionedUriCache.get(cacheKey);
return entry && entry.uri;
@ -942,8 +942,21 @@ export class GitService extends Disposable {
return this._repositories;
}
async getRepository(uri: Uri): Promise<Repository | undefined> {
const folder = workspace.getWorkspaceFolder(uri);
async getRepository(repoPath: string): Promise<Repository | undefined>;
async getRepository(uri: Uri): Promise<Repository | undefined>;
async getRepository(repoPathOrUri: string | Uri): Promise<Repository | undefined> {
if (repoPathOrUri instanceof GitUri) {
repoPathOrUri = repoPathOrUri.repoPath !== undefined
? Uri.file(repoPathOrUri.repoPath)
: repoPathOrUri.fileUri();
}
if (typeof repoPathOrUri === 'string') {
const repositories = await this.getRepositoriesCore();
return Iterables.find(repositories.values(), r => r !== undefined && r.path === repoPathOrUri) || undefined;
}
const folder = workspace.getWorkspaceFolder(repoPathOrUri);
if (folder === undefined) return undefined;
const repositories = await this.getRepositoriesCore();
@ -1037,6 +1050,7 @@ export class GitService extends Disposable {
async isTracked(fileNameOrUri: string | GitUri, repoPath?: string): Promise<boolean> {
let cacheKey: string;
let fileName: string;
let sha: string | undefined;
if (typeof fileNameOrUri === 'string') {
[fileName, repoPath] = Git.splitPath(fileNameOrUri, repoPath);
cacheKey = this.getCacheEntryKey(fileNameOrUri);
@ -1046,10 +1060,11 @@ export class GitService extends Disposable {
fileName = fileNameOrUri.fsPath;
repoPath = fileNameOrUri.repoPath;
cacheKey = this.getCacheEntryKey(fileNameOrUri);
sha = fileNameOrUri.sha;
cacheKey = this.getCacheEntryKey(fileName);
}
Logger.log(`isTracked('${fileName}', '${repoPath}')`);
Logger.log(`isTracked('${fileName}', '${repoPath}', '${sha}')`);
let tracked = this._trackedCache.get(cacheKey);
if (tracked !== undefined) {
@ -1057,7 +1072,7 @@ export class GitService extends Disposable {
return await tracked;
}
tracked = this.isTrackedCore(repoPath === undefined ? '' : repoPath, fileName);
tracked = this.isTrackedCore(repoPath === undefined ? '' : repoPath, fileName, sha);
this._trackedCache.set(cacheKey, tracked);
tracked = await tracked;
@ -1066,10 +1081,15 @@ export class GitService extends Disposable {
return tracked;
}
private async isTrackedCore(repoPath: string, fileName: string) {
const result = await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName);
return !!result;
private async isTrackedCore(repoPath: string, fileName: string, sha?: string) {
// Even if we have a sha, check first to see if the file exists (that way the cache will be better reused)
let tracked = !!await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName);
if (!tracked && sha !== undefined) {
tracked = !!await Git.ls_files(repoPath === undefined ? '' : repoPath, fileName, sha);
}
return tracked;
}
openDiffTool(repoPath: string, uri: Uri, staged: boolean) {
Logger.log(`openDiffTool('${repoPath}', '${uri.fsPath}', ${staged})`);

+ 3
- 2
src/views/gitExplorer.ts View File

@ -146,10 +146,11 @@ export class GitExplorer implements TreeDataProvider {
// If we do have a visible trackable editor, don't change from the last state (avoids issues when focus switches to the problems/output/debug console panes)
if (editor.document === undefined || !this.git.isTrackable(editor.document.uri)) return this._root;
const repo = await this.git.getRepository(editor.document.uri);
const uri = await GitUri.fromUri(editor.document.uri, this.git);
const repo = await this.git.getRepository(uri);
if (repo === undefined) return undefined;
const uri = this.git.getGitUriForFile(editor.document.uri) || new GitUri(editor.document.uri, { repoPath: repo.path, fileName: editor.document.uri.fsPath });
if (UriComparer.equals(uri, this._root && this._root.uri)) return this._root;
return new HistoryNode(uri, repo, this);

Loading…
Cancel
Save