Files
vscode-gitlens/src/git/gitUri.ts
Eric Amodio 49fa9b5078 Fixes issues with missing repoPath
Allows commit search without an active editor
2017-05-22 16:04:46 -04:00

121 lines
4.2 KiB
TypeScript

'use strict';
import { Uri } from 'vscode';
import { DocumentSchemes } from '../constants';
import { GitService, IGitStatusFile } from '../gitService';
import * as path from 'path';
export class GitUri extends Uri {
offset: number;
repoPath?: string | undefined;
sha?: string | undefined;
constructor(uri?: Uri, commit?: IGitCommitInfo);
constructor(uri?: Uri, repoPath?: string);
constructor(uri?: Uri, commitOrRepoPath?: IGitCommitInfo | string);
constructor(uri?: Uri, commitOrRepoPath?: IGitCommitInfo | string) {
super();
if (!uri) return;
const base = this as any;
base._scheme = uri.scheme;
base._authority = uri.authority;
base._path = uri.path;
base._query = uri.query;
base._fragment = uri.fragment;
this.offset = 0;
if (uri.scheme === DocumentSchemes.GitLensGit) {
const data = GitService.fromGitContentUri(uri);
base._fsPath = path.resolve(data.repoPath, data.originalFileName || data.fileName);
this.offset = (data.decoration && data.decoration.split('\n').length) || 0;
if (!GitService.isUncommitted(data.sha)) {
this.sha = data.sha;
this.repoPath = data.repoPath;
}
}
else if (commitOrRepoPath) {
if (typeof commitOrRepoPath === 'string') {
this.repoPath = commitOrRepoPath;
}
else {
const commit = commitOrRepoPath;
base._fsPath = path.resolve(commit.repoPath, commit.originalFileName || commit.fileName);
if (commit.repoPath !== undefined) {
this.repoPath = commit.repoPath;
}
if (commit.sha !== undefined && !GitService.isUncommitted(commit.sha)) {
this.sha = commit.sha;
}
}
}
}
get shortSha() {
return this.sha && this.sha.substring(0, 8);
}
fileUri() {
return Uri.file(this.sha ? this.path : this.fsPath);
}
getFormattedPath(separator: string = ' \u00a0\u2022\u00a0 '): string {
let directory = path.dirname(this.fsPath);
if (this.repoPath) {
directory = path.relative(this.repoPath, directory);
}
directory = GitService.normalizePath(directory);
return (!directory || directory === '.')
? path.basename(this.fsPath)
: `${path.basename(this.fsPath)}${separator}${directory}`;
}
getRelativePath(): string {
return GitService.normalizePath(path.relative(this.repoPath || '', this.fsPath));
}
static async fromUri(uri: Uri, git: GitService) {
if (uri instanceof GitUri) return uri;
if (!git.isTrackable(uri)) return new GitUri(uri, git.repoPath);
const gitUri = git.getGitUriForFile(uri.fsPath);
if (gitUri) return gitUri;
// If this is a git uri, assume it is showing the most recent commit
if (uri.scheme === DocumentSchemes.Git && uri.query === '~') {
const commit = await git.getLogCommit(undefined, uri.fsPath);
if (commit) return new GitUri(uri, commit);
}
return new GitUri(uri, (await git.getRepoPathFromFile(uri.fsPath)) || git.repoPath);
}
static fromFileStatus(status: IGitStatusFile, repoPath: string, original?: boolean): GitUri;
static fromFileStatus(status: IGitStatusFile, commit: IGitCommitInfo, original?: boolean): GitUri;
static fromFileStatus(status: IGitStatusFile, repoPathOrCommit: string | IGitCommitInfo, original: boolean = false): GitUri {
const repoPath = typeof repoPathOrCommit === 'string' ? repoPathOrCommit : repoPathOrCommit.repoPath;
const uri = Uri.file(path.resolve(repoPath, original ? status.originalFileName || status.fileName : status.fileName));
return new GitUri(uri, repoPathOrCommit);
}
}
export interface IGitCommitInfo {
fileName: string;
repoPath: string;
sha?: string;
originalFileName?: string;
}
export interface IGitUriData {
sha: string;
fileName: string;
repoPath: string;
originalFileName?: string;
index?: number;
decoration?: string;
}