mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-18 01:35:36 -05:00
145 lines
5.0 KiB
TypeScript
145 lines
5.0 KiB
TypeScript
'use strict';
|
|
import { Strings } from '../system';
|
|
import { Uri } from 'vscode';
|
|
import { DocumentSchemes, GlyphChars } 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;
|
|
for (const key in uri) {
|
|
if (uri.hasOwnProperty(key)) {
|
|
base[key] = (uri as any)[key];
|
|
}
|
|
}
|
|
|
|
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 && GitService.shortenSha(this.sha);
|
|
}
|
|
|
|
fileUri() {
|
|
return Uri.file(this.sha ? this.path : this.fsPath);
|
|
}
|
|
|
|
getFormattedPath(separator: string = Strings.pad(GlyphChars.Dot, 2, 2)): 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);
|
|
|
|
// If this is a git uri, assume it is showing the most recent commit
|
|
if (uri.scheme === DocumentSchemes.Git) {
|
|
const commit = await git.getLogCommit(undefined, uri.fsPath);
|
|
if (commit !== undefined) return new GitUri(uri, commit);
|
|
}
|
|
|
|
const gitUri = git.getGitUriForFile(uri);
|
|
if (gitUri) return gitUri;
|
|
|
|
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);
|
|
}
|
|
|
|
static getDirectory(fileName: string): string {
|
|
const directory: string | undefined = GitService.normalizePath(path.dirname(fileName));
|
|
return (!directory || directory === '.') ? '' : directory;
|
|
}
|
|
|
|
static getFormattedPath(fileNameOrUri: string | Uri, separator: string = Strings.pad(GlyphChars.Dot, 2, 2)): string {
|
|
let fileName: string;
|
|
if (fileNameOrUri instanceof Uri) {
|
|
if (fileNameOrUri instanceof GitUri) return fileNameOrUri.getFormattedPath(separator);
|
|
|
|
fileName = fileNameOrUri.fsPath;
|
|
}
|
|
else {
|
|
fileName = fileNameOrUri;
|
|
}
|
|
|
|
const directory = GitUri.getDirectory(fileName);
|
|
return !directory
|
|
? path.basename(fileName)
|
|
: `${path.basename(fileName)}${separator}${directory}`;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|