Browse Source

Adds get next comparison uris for GitHub

Adds get previous line comparison uris for GitHub
Improves perf of get previous comparison uris for GitHub
Replaces HEAD usage with proper revision for GitHub
Renames comparison uri methods for clarity
main
Eric Amodio 3 years ago
parent
commit
0d9f9c3871
14 changed files with 298 additions and 219 deletions
  1. +1
    -1
      .vscode/queries.github-graphql-nb
  2. +1
    -1
      src/commands/diffLineWithPrevious.ts
  3. +1
    -1
      src/commands/diffWithNext.ts
  4. +1
    -1
      src/commands/diffWithPrevious.ts
  5. +5
    -1
      src/commands/diffWithWorking.ts
  6. +1
    -1
      src/commands/openFileAtRevision.ts
  7. +9
    -9
      src/env/node/git/localGitProvider.ts
  8. +3
    -12
      src/git/gitProvider.ts
  9. +9
    -40
      src/git/gitProviderService.ts
  10. +5
    -3
      src/git/models/commit.ts
  11. +5
    -5
      src/hovers/hovers.ts
  12. +0
    -17
      src/hovers/lineHoverController.ts
  13. +119
    -15
      src/premium/github/github.ts
  14. +138
    -112
      src/premium/github/githubGitProvider.ts

+ 1
- 1
.vscode/queries.github-graphql-nb
File diff suppressed because it is too large
View File


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

@ -32,7 +32,7 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand {
const gitUri = args.commit?.getGitUri() ?? (await GitUri.fromUri(uri));
try {
const diffUris = await this.container.git.getPreviousLineDiffUris(
const diffUris = await this.container.git.getPreviousComparisonUrisForLine(
gitUri.repoPath!,
gitUri,
args.line,

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

@ -41,7 +41,7 @@ export class DiffWithNextCommand extends ActiveEditorCommand {
const gitUri = args.commit?.getGitUri() ?? (await GitUri.fromUri(uri));
try {
const diffUris = await this.container.git.getNextDiffUris(
const diffUris = await this.container.git.getNextComparisonUris(
gitUri.repoPath!,
gitUri,
gitUri.sha,

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

@ -82,7 +82,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand {
// }
try {
const diffUris = await this.container.git.getPreviousDiffUris(
const diffUris = await this.container.git.getPreviousComparisonUris(
gitUri.repoPath!,
gitUri,
gitUri.sha,

+ 5
- 1
src/commands/diffWithWorking.ts View File

@ -37,7 +37,11 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand {
if (args.inDiffRightEditor) {
try {
const diffUris = await this.container.git.getPreviousDiffUris(gitUri.repoPath!, gitUri, gitUri.sha, 0);
const diffUris = await this.container.git.getPreviousComparisonUris(
gitUri.repoPath!,
gitUri,
gitUri.sha,
);
gitUri = diffUris?.previous ?? gitUri;
} catch (ex) {
Logger.error(

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

@ -60,7 +60,7 @@ export class OpenFileAtRevisionCommand extends ActiveEditorCommand {
const blame = await this.container.git.getBlameForLine(gitUri, editorLine);
if (blame != null) {
if (blame.commit.isUncommitted) {
const diffUris = await blame.commit.getPreviousLineDiffUris(
const diffUris = await blame.commit.getPreviousComparisonUrisForLine(
gitUri,
editorLine,
gitUri.sha,

+ 9
- 9
src/env/node/git/localGitProvider.ts View File

@ -1073,7 +1073,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
@log()
async getBlameForLine(
uri: GitUri,
editorLine: number,
editorLine: number, // 0-based, Git is 1-based
document?: TextDocument | undefined,
options?: { forceSingleLine?: boolean },
): Promise<GitBlameLine | undefined> {
@ -1126,7 +1126,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
@log<LocalGitProvider['getBlameForLineContents']>({ args: { 2: '<contents>' } })
async getBlameForLineContents(
uri: GitUri,
editorLine: number,
editorLine: number, // 0-based, Git is 1-based
contents: string,
options?: { forceSingleLine?: boolean },
): Promise<GitBlameLine | undefined> {
@ -1831,7 +1831,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
@log()
async getDiffForLine(
uri: GitUri,
editorLine: number,
editorLine: number, // 0-based, Git is 1-based
ref1: string | undefined,
ref2?: string,
): Promise<GitDiffHunkLine | undefined> {
@ -2672,7 +2672,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
}
@log()
async getNextDiffUris(
async getNextComparisonUris(
repoPath: string,
uri: Uri,
ref: string | undefined,
@ -2719,7 +2719,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
}
@log()
async getNextUri(
private async getNextUri(
repoPath: string,
uri: Uri,
ref?: string,
@ -2775,7 +2775,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
}
@log()
async getPreviousDiffUris(
async getPreviousComparisonUris(
repoPath: string,
uri: Uri,
ref: string | undefined,
@ -2852,10 +2852,10 @@ export class LocalGitProvider implements GitProvider, Disposable {
}
@log()
async getPreviousLineDiffUris(
async getPreviousComparisonUrisForLine(
repoPath: string,
uri: Uri,
editorLine: number,
editorLine: number, // 0-based, Git is 1-based
ref: string | undefined,
skip: number = 0,
): Promise<{ current: GitUri; previous: GitUri | undefined; line: number } | undefined> {
@ -2971,7 +2971,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
}
@log()
async getPreviousUri(
private async getPreviousUri(
repoPath: string,
uri: Uri,
ref?: string,

+ 3
- 12
src/git/gitProvider.ts View File

@ -295,35 +295,26 @@ export interface GitProvider extends Disposable {
): Promise<string | undefined>;
getMergeStatus(repoPath: string): Promise<GitMergeStatus | undefined>;
getRebaseStatus(repoPath: string): Promise<GitRebaseStatus | undefined>;
getNextDiffUris(
getNextComparisonUris(
repoPath: string,
uri: Uri,
ref: string | undefined,
skip?: number,
): Promise<{ current: GitUri; next: GitUri | undefined; deleted?: boolean | undefined } | undefined>;
getNextUri(repoPath: string, uri: Uri, ref?: string, skip?: number): Promise<GitUri | undefined>;
getPreviousDiffUris(
getPreviousComparisonUris(
repoPath: string,
uri: Uri,
ref: string | undefined,
skip?: number,
firstParent?: boolean,
): Promise<{ current: GitUri; previous: GitUri | undefined } | undefined>;
getPreviousLineDiffUris(
getPreviousComparisonUrisForLine(
repoPath: string,
uri: Uri,
editorLine: number,
ref: string | undefined,
skip?: number,
): Promise<{ current: GitUri; previous: GitUri | undefined; line: number } | undefined>;
getPreviousUri(
repoPath: string,
uri: Uri,
ref?: string,
skip?: number,
editorLine?: number,
firstParent?: boolean,
): Promise<GitUri | undefined>;
getIncomingActivity(
repoPath: string,
options?: {

+ 9
- 40
src/git/gitProviderService.ts View File

@ -1264,75 +1264,44 @@ export class GitProviderService implements Disposable {
}
@log()
async getNextDiffUris(
getNextComparisonUris(
repoPath: string | Uri,
uri: Uri,
ref: string | undefined,
skip: number = 0,
): Promise<{ current: GitUri; next: GitUri | undefined; deleted?: boolean } | undefined> {
// If we have no ref (or staged ref) there is no next commit
if (ref == null || ref.length === 0) return undefined;
if (!ref) return Promise.resolve(undefined);
const { provider, path } = this.getProvider(repoPath);
return provider.getNextDiffUris(path, uri, ref, skip);
return provider.getNextComparisonUris(path, uri, ref, skip);
}
@log()
async getNextUri(
repoPath: string | Uri,
uri: Uri,
ref?: string,
skip: number = 0,
// editorLine?: number
): Promise<GitUri | undefined> {
// If we have no ref (or staged ref) there is no next commit
if (ref == null || ref.length === 0 || GitRevision.isUncommittedStaged(ref)) return undefined;
const { provider, path } = this.getProvider(repoPath);
return provider.getNextUri(path, uri, ref, skip);
}
@log()
async getPreviousDiffUris(
getPreviousComparisonUris(
repoPath: string | Uri,
uri: Uri,
ref: string | undefined,
skip: number = 0,
firstParent: boolean = false,
): Promise<{ current: GitUri; previous: GitUri | undefined } | undefined> {
if (ref === GitRevision.deletedOrMissing) return undefined;
if (ref === GitRevision.deletedOrMissing) return Promise.resolve(undefined);
const { provider, path } = this.getProvider(repoPath);
return provider.getPreviousDiffUris(path, uri, ref, skip, firstParent);
return provider.getPreviousComparisonUris(path, uri, ref, skip, firstParent);
}
@log()
async getPreviousLineDiffUris(
getPreviousComparisonUrisForLine(
repoPath: string | Uri,
uri: Uri,
editorLine: number,
ref: string | undefined,
skip: number = 0,
): Promise<{ current: GitUri; previous: GitUri | undefined; line: number } | undefined> {
if (ref === GitRevision.deletedOrMissing) return undefined;
const { provider, path } = this.getProvider(repoPath);
return provider.getPreviousLineDiffUris(path, uri, editorLine, ref, skip);
}
@log()
async getPreviousUri(
repoPath: string | Uri,
uri: Uri,
ref?: string,
skip: number = 0,
editorLine?: number,
firstParent: boolean = false,
): Promise<GitUri | undefined> {
if (ref === GitRevision.deletedOrMissing) return undefined;
if (ref === GitRevision.deletedOrMissing) return Promise.resolve(undefined);
const { provider, path } = this.getProvider(repoPath);
return provider.getPreviousUri(path, uri, ref, skip, editorLine, firstParent);
return provider.getPreviousComparisonUrisForLine(path, uri, editorLine, ref, skip);
}
async getPullRequestForBranch(

+ 5
- 3
src/git/models/commit.ts View File

@ -406,10 +406,10 @@ export class GitCommit implements GitRevisionReference {
});
}
@memoize<GitCommit['getPreviousLineDiffUris']>((u, e, r) => `${u.toString()}|${e}|${r ?? ''}`)
getPreviousLineDiffUris(uri: Uri, editorLine: number, ref: string | undefined) {
@memoize<GitCommit['getPreviousComparisonUrisForLine']>((u, e, r) => `${u.toString()}|${e}|${r ?? ''}`)
getPreviousComparisonUrisForLine(uri: Uri, editorLine: number, ref: string | undefined) {
return this.file?.path
? this.container.git.getPreviousLineDiffUris(this.repoPath, uri, editorLine, ref)
? this.container.git.getPreviousComparisonUrisForLine(this.repoPath, uri, editorLine, ref)
: Promise.resolve(undefined);
}
@ -494,7 +494,9 @@ export class GitCommitIdentity {
export interface GitCommitLine {
sha: string;
previousSha?: string | undefined;
/** The original (previous) line number prior to this commit; 1-based */
originalLine: number;
/** The current line number in this commit; 1-based */
line: number;
}

+ 5
- 5
src/hovers/hovers.ts View File

@ -15,7 +15,7 @@ export namespace Hovers {
export async function changesMessage(
commit: GitCommit,
uri: GitUri,
editorLine: number,
editorLine: number, // 0-based, Git is 1-based
document: TextDocument,
): Promise<MarkdownString | undefined> {
const documentRef = uri.sha;
@ -76,7 +76,7 @@ export namespace Hovers {
let previous;
let current;
if (commit.isUncommitted) {
const diffUris = await commit.getPreviousLineDiffUris(uri, editorLine, documentRef);
const diffUris = await commit.getPreviousComparisonUrisForLine(uri, editorLine, documentRef);
if (diffUris?.previous == null) return undefined;
message = `[$(compare-changes)](${DiffWithCommand.getMarkdownCommandArgs({
@ -144,7 +144,7 @@ export namespace Hovers {
export async function localChangesMessage(
fromCommit: GitCommit | undefined,
uri: GitUri,
editorLine: number,
editorLine: number, // 0-based, Git is 1-based
hunk: GitDiffHunk,
): Promise<MarkdownString | undefined> {
const diff = getDiffFromHunk(hunk);
@ -191,7 +191,7 @@ export namespace Hovers {
export async function detailsMessage(
commit: GitCommit,
uri: GitUri,
editorLine: number,
editorLine: number, // 0-based, Git is 1-based
format: string,
dateFormat: string | null,
options?: {
@ -224,7 +224,7 @@ export namespace Hovers {
if (options?.cancellationToken?.isCancellationRequested) return new MarkdownString();
const [previousLineDiffUris, autolinkedIssuesOrPullRequests, pr, presence] = await Promise.all([
commit.isUncommitted ? commit.getPreviousLineDiffUris(uri, editorLine, uri.sha) : undefined,
commit.isUncommitted ? commit.getPreviousComparisonUrisForLine(uri, editorLine, uri.sha) : undefined,
getAutoLinkedIssuesOrPullRequests(message, remotes),
options?.pullRequests?.pr ??
getPullRequestForCommit(commit.ref, remotes, {

+ 0
- 17
src/hovers/lineHoverController.ts View File

@ -116,23 +116,6 @@ export class LineHoverController implements Disposable {
);
if (!wholeLine && range.start.character !== position.character) return undefined;
// // Get the full commit message -- since blame only returns the summary
// let logCommit = lineState?.logCommit;
// if (logCommit == null && !commit.isUncommitted) {
// logCommit = await this.container.git.getCommitForFile(commit.repoPath, commit.uri, {
// ref: commit.sha,
// });
// if (logCommit != null) {
// // Preserve the previous commit from the blame commit
// logCommit.previousSha = commit.previousSha;
// logCommit.previousFileName = commit.previousFileName;
// if (lineState != null) {
// lineState.logCommit = logCommit;
// }
// }
// }
let editorLine = position.line;
const line = editorLine + 1;
const commitLine = commit.lines.find(l => l.line === line) ?? commit.lines[0];

+ 119
- 15
src/premium/github/github.ts View File

@ -521,7 +521,6 @@ export class GitHubApi {
ranges {
startingLine
endingLine
age
commit {
oid
parents(first: 3) { nodes { oid } }
@ -1093,12 +1092,13 @@ export class GitHubApi {
options?: {
after?: string;
before?: string;
limit?: number;
first?: number;
last?: number;
path?: string;
since?: Date;
until?: Date;
since?: string;
until?: string;
},
): Promise<string[]> {
): Promise<GitHubPagedResult<GitHubCommitRef> | undefined> {
const cc = Logger.getCorrelationContext();
interface QueryResult {
@ -1107,7 +1107,9 @@ export class GitHubApi {
object:
| {
history: {
nodes: { oid: string }[];
pageInfo: GitHubPageInfo;
totalCount: number;
nodes: GitHubCommitRef[];
};
}
| null
@ -1124,7 +1126,8 @@ export class GitHubApi {
$ref: String!
$after: String
$before: String
$limit: Int = 1
$first: Int
$last: Int
$path: String
$since: GitTimestamp
$until: GitTimestamp
@ -1132,7 +1135,9 @@ export class GitHubApi {
repository(name: $repo, owner: $owner) {
object(expression: $ref) {
... on Commit {
history(first: $limit, path: $path, since: $since, until: $until, after: $after, before: $before) {
history(first: $first, last: $last, path: $path, since: $since, until: $until, after: $after, before: $before) {
pageInfo { startCursor, endCursor, hasNextPage, hasPreviousPage }
totalCount
nodes { oid }
}
}
@ -1145,19 +1150,102 @@ export class GitHubApi {
repo: repo,
ref: ref,
path: options?.path,
limit: Math.max(1, options?.limit ?? 1),
first: options?.first,
last: options?.last,
after: options?.after,
before: options?.before,
since: options?.since?.toISOString(),
until: options?.until?.toISOString(),
since: options?.since,
until: options?.until,
});
const history = rsp?.repository?.object?.history;
if (history == null) return [];
if (history == null) return undefined;
return history.nodes.map(n => n.oid);
return {
pageInfo: history.pageInfo,
totalCount: history.totalCount,
values: history.nodes,
};
} catch (ex) {
debugger;
return this.handleRequestError<string[]>(ex, cc, []);
return this.handleRequestError(ex, cc, undefined);
}
}
@debug<GitHubApi['getNextCommitRefs']>({ args: { 0: '<token>' } })
async getNextCommitRefs(
token: string,
owner: string,
repo: string,
ref: string,
path: string,
sha: string,
): Promise<string[]> {
// Get the commit date of the current commit
const commitDate = await this.getCommitDate(token, owner, repo, sha);
if (commitDate == null) return [];
// Get a resultset (just need the cursor and totals), to get the page info we need to construct a cursor to page backwards
let result = await this.getCommitRefs(token, owner, repo, ref, { path: path, first: 1, since: commitDate });
if (result == null) return [];
// Construct a cursor to allow use to walk backwards in time (starting at the tip going back in time until the commit date)
const cursor = `${result.pageInfo.startCursor!.split(' ', 1)[0]} ${result.totalCount}`;
let last;
[, last] = cursor.split(' ', 2);
// We can't ask for more commits than are left in the cursor (but try to get more to be safe, since the date isn't exact enough)
last = Math.min(parseInt(last, 10), 5);
// Get the set of refs before the cursor
result = await this.getCommitRefs(token, owner, repo, ref, { path: path, last: last, before: cursor });
if (result == null) return [];
const nexts: string[] = [];
for (const { oid } of result.values) {
if (oid === sha) break;
nexts.push(oid);
}
return nexts.reverse();
}
private async getCommitDate(token: string, owner: string, repo: string, sha: string): Promise<string | undefined> {
const cc = Logger.getCorrelationContext();
interface QueryResult {
repository:
| {
object: { committer: { date: string } } | null | undefined;
}
| null
| undefined;
}
try {
const query = `query getCommitDate(
$owner: String!
$repo: String!
$sha: GitObjectID!
) {
repository(name: $repo, owner: $owner) {
object(oid: $sha) {
... on Commit { committer { date } }
}
}
}`;
const rsp = await this.graphql<QueryResult>(token, query, {
owner: owner,
repo: repo,
sha: sha,
});
const date = rsp?.repository?.object?.committer.date;
return date;
} catch (ex) {
debugger;
return this.handleRequestError(ex, cc, undefined);
}
}
@ -1549,7 +1637,6 @@ export interface GitHubBlame {
export interface GitHubBlameRange {
startingLine: number;
endingLine: number;
age: number;
commit: GitHubCommit;
}
@ -1576,6 +1663,10 @@ export interface GitHubCommit {
files?: Endpoints['GET /repos/{owner}/{repo}/commits/{ref}']['response']['data']['files'];
}
export interface GitHubCommitRef {
oid: string;
}
export type GitHubContributor = Endpoints['GET /repos/{owner}/{repo}/contributors']['response']['data'][0];
interface GitHubIssueOrPullRequest {
@ -1588,6 +1679,19 @@ interface GitHubIssueOrPullRequest {
url: string;
}
export interface GitHubPagedResult<T> {
pageInfo: GitHubPageInfo;
totalCount: number;
values: T[];
}
interface GitHubPageInfo {
startCursor?: string | null;
endCursor?: string | null;
hasNextPage: boolean;
hasPreviousPage: boolean;
}
type GitHubPullRequestState = 'OPEN' | 'CLOSED' | 'MERGED';
interface GitHubPullRequest {

+ 138
- 112
src/premium/github/githubGitProvider.ts View File

@ -402,7 +402,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
// const sha = await this.resolveReferenceCore(uri.repoPath!, metadata, uri.sha);
// if (sha == null) return undefined;
const ref = uri.sha ?? 'HEAD';
const ref = uri.sha ?? (await metadata.getRevision()).revision;
const blame = await github.getBlame(
session?.accessToken,
metadata.repo.owner,
@ -453,6 +453,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
}
for (let i = range.startingLine; i <= range.endingLine; i++) {
// GitHub doesn't currently support returning the original line number, so we are just using the current one
const line: GitCommitLine = { sha: c.oid, originalLine: i, line: i };
commit.lines.push(line);
@ -500,7 +501,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
@log()
async getBlameForLine(
uri: GitUri,
editorLine: number,
editorLine: number, // 0-based, Git is 1-based
document?: TextDocument | undefined,
options?: { forceSingleLine?: boolean },
): Promise<GitBlameLine | undefined> {
@ -547,7 +548,8 @@ export class GitHubGitProvider implements GitProvider, Disposable {
relativePath,
);
const range = blame.ranges.find(r => r.startingLine === editorLine);
const startingLine = editorLine + 1;
const range = blame.ranges.find(r => r.startingLine === startingLine);
if (range == null) return undefined;
const c = range.commit;
@ -571,6 +573,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
);
for (let i = range.startingLine; i <= range.endingLine; i++) {
// GitHub doesn't currently support returning the original line number, so we are just using the current one
const line: GitCommitLine = { sha: c.oid, originalLine: i, line: i };
commit.lines.push(line);
@ -582,7 +585,8 @@ export class GitHubGitProvider implements GitProvider, Disposable {
lineCount: range.endingLine - range.startingLine + 1,
},
commit: commit,
line: { sha: c.oid, originalLine: range.startingLine, line: editorLine },
// GitHub doesn't currently support returning the original line number, so we are just using the current one
line: { sha: c.oid, originalLine: range.startingLine, line: range.startingLine },
};
} catch (ex) {
debugger;
@ -594,7 +598,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
@log<GitHubGitProvider['getBlameForLineContents']>({ args: { 2: '<contents>' } })
async getBlameForLineContents(
_uri: GitUri,
_editorLine: number,
_editorLine: number, // 0-based, Git is 1-based
_contents: string,
_options?: { forceSingleLine?: boolean },
): Promise<GitBlameLine | undefined> {
@ -917,7 +921,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
session?.accessToken,
metadata.repo.owner,
metadata.repo.name,
options?.ref ?? 'HEAD',
options?.ref ?? (await metadata.getRevision()).revision,
file,
);
if (commit == null) return undefined;
@ -1080,7 +1084,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
@log()
async getDiffForLine(
_uri: GitUri,
_editorLine: number,
_editorLine: number, // 0-based, Git is 1-based
_ref1: string | undefined,
_ref2?: string,
): Promise<GitDiffHunkLine | undefined> {
@ -1134,7 +1138,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
try {
const { metadata, github, session } = await this.ensureRepositoryContext(repoPath);
const ref = options?.ref ?? 'HEAD';
const ref = options?.ref ?? (await metadata.getRevision()).revision;
const result = await github.getCommits(session?.accessToken, metadata.repo.owner, metadata.repo.name, ref, {
all: options?.all,
authors: options?.authors,
@ -1518,7 +1522,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
// range = new Range(range.end, range.start);
// }
const ref = options?.ref ?? 'HEAD';
const ref = options?.ref ?? (await metadata.getRevision()).revision;
const result = await github.getCommits(session?.accessToken, metadata.repo.owner, metadata.repo.name, ref, {
all: options?.all,
cursor: options?.cursor,
@ -1710,119 +1714,57 @@ export class GitHubGitProvider implements GitProvider, Disposable {
}
@log()
async getNextDiffUris(
async getNextComparisonUris(
repoPath: string,
uri: Uri,
ref: string | undefined,
skip: number = 0,
): Promise<{ current: GitUri; next: GitUri | undefined; deleted?: boolean } | undefined> {
// If we have no ref (or staged ref) there is no next commit
// If we have no ref there is no next commit
if (!ref) return undefined;
const relativePath = this.getRelativePath(uri, repoPath);
return {
current:
skip === 0
? GitUri.fromFile(relativePath, repoPath, ref)
: (await this.getNextUri(repoPath, uri, ref, skip - 1))!,
next: await this.getNextUri(repoPath, uri, ref, skip),
};
}
@log()
async getNextUri(
_repoPath: string,
_uri: Uri,
ref?: string,
_skip: number = 0,
// editorLine?: number
): Promise<GitUri | undefined> {
// If we have no ref (or staged ref) there is no next commit
if (!ref || GitRevision.isUncommittedStaged(ref)) return undefined;
return undefined;
// const cc = Logger.getCorrelationContext();
// // const relativePath = this.getRelativePath(uri, repoPath);
// try {
// const context = await this.ensureRepositoryContext(repoPath);
// if (context == null) return undefined;
// const { metadata, github, remotehub, session } = context;
const cc = Logger.getCorrelationContext();
// const relativePath = this.getRelativePath(uri, remotehub.getProviderRootUri(uri));
try {
const context = await this.ensureRepositoryContext(repoPath);
if (context == null) return undefined;
// const refs = await github.getCommitRefs(
// session.accessToken,
// metadata.repo.owner,
// metadata.repo.name,
// ref ?? 'HEAD',
// {
// path: relativePath,
// limit: skip + 2,
// before: `${ref} 0`,
// },
// );
const { metadata, github, remotehub, session } = context;
const relativePath = this.getRelativePath(uri, remotehub.getProviderRootUri(uri));
const revision = await metadata.getRevision();
// const nextRef = refs[skip];
// if (nextRef == null) return undefined;
const refs = await github.getNextCommitRefs(
session.accessToken,
metadata.repo.owner,
metadata.repo.name,
revision.revision,
relativePath,
ref,
);
// const next = await this.getBestRevisionUri(repoPath, relativePath, nextRef);
// return new GitUri(next);
// } catch (ex) {
// Logger.error(ex, cc);
// debugger;
return {
current:
skip === 0
? GitUri.fromFile(relativePath, repoPath, ref)
: new GitUri(await this.getBestRevisionUri(repoPath, relativePath, refs[skip - 1])),
next: new GitUri(await this.getBestRevisionUri(repoPath, relativePath, refs[skip])),
};
} catch (ex) {
Logger.error(ex, cc);
debugger;
// throw ex;
// }
throw ex;
}
}
@log()
async getPreviousDiffUris(
async getPreviousComparisonUris(
repoPath: string,
uri: Uri,
ref: string | undefined,
skip: number = 0,
firstParent: boolean = false,
): Promise<{ current: GitUri; previous: GitUri | undefined } | undefined> {
if (ref === GitRevision.deletedOrMissing) return undefined;
const relativePath = this.getRelativePath(uri, repoPath);
// If we are at a commit, diff commit with previous
const current =
skip === 0
? GitUri.fromFile(relativePath, repoPath, ref)
: (await this.getPreviousUri(repoPath, uri, ref, skip - 1, undefined, firstParent))!;
if (current == null || current.sha === GitRevision.deletedOrMissing) return undefined;
return {
current: current,
previous: await this.getPreviousUri(repoPath, uri, ref, skip, undefined, firstParent),
};
}
@log()
async getPreviousLineDiffUris(
_repoPath: string,
_uri: Uri,
_editorLine: number,
_ref: string | undefined,
_skip: number = 0,
): Promise<{ current: GitUri; previous: GitUri | undefined; line: number } | undefined> {
return undefined;
}
@log()
async getPreviousUri(
repoPath: string,
uri: Uri,
ref?: string,
skip: number = 0,
_editorLine?: number,
_firstParent: boolean = false,
): Promise<GitUri | undefined> {
): Promise<{ current: GitUri; previous: GitUri | undefined } | undefined> {
if (ref === GitRevision.deletedOrMissing) return undefined;
const cc = Logger.getCorrelationContext();
@ -1834,29 +1776,113 @@ export class GitHubGitProvider implements GitProvider, Disposable {
try {
const context = await this.ensureRepositoryContext(repoPath);
if (context == null) return undefined;
const { metadata, github, remotehub, session } = context;
const { metadata, github, remotehub, session } = context;
const relativePath = this.getRelativePath(uri, remotehub.getProviderRootUri(uri));
const offset = ref != null ? 1 : 0;
const refs = await github.getCommitRefs(
const result = await github.getCommitRefs(
session.accessToken,
metadata.repo.owner,
metadata.repo.name,
ref ?? 'HEAD',
ref ? ref : (await metadata.getRevision()).revision,
{
path: relativePath,
limit: offset + skip + 1,
first: offset + skip + 1,
},
);
if (result == null) return undefined;
const previous = await this.getBestRevisionUri(
repoPath,
relativePath,
refs[offset + skip] ?? GitRevision.deletedOrMissing,
);
return new GitUri(previous);
// If we are at a commit, diff commit with previous
const current =
skip === 0
? GitUri.fromFile(relativePath, repoPath, ref)
: new GitUri(
await this.getBestRevisionUri(
repoPath,
relativePath,
result.values[offset + skip - 1]?.oid ?? GitRevision.deletedOrMissing,
),
);
if (current == null || current.sha === GitRevision.deletedOrMissing) return undefined;
return {
current: current,
previous: new GitUri(
await this.getBestRevisionUri(
repoPath,
relativePath,
result.values[offset + skip]?.oid ?? GitRevision.deletedOrMissing,
),
),
};
} catch (ex) {
Logger.error(ex, cc);
debugger;
throw ex;
}
}
@log()
async getPreviousComparisonUrisForLine(
repoPath: string,
uri: Uri,
editorLine: number, // 0-based, Git is 1-based
ref: string | undefined,
skip: number = 0,
): Promise<{ current: GitUri; previous: GitUri | undefined; line: number } | undefined> {
if (ref === GitRevision.deletedOrMissing) return undefined;
const cc = Logger.getCorrelationContext();
try {
const context = await this.ensureRepositoryContext(repoPath);
if (context == null) return undefined;
const { remotehub } = context;
let relativePath = this.getRelativePath(uri, remotehub.getProviderRootUri(uri));
// FYI, GitHub doesn't currently support returning the original line number, nor the previous sha, so this is untrustworthy
let current = GitUri.fromFile(relativePath, repoPath, ref);
let currentLine = editorLine;
let previous;
let previousLine = editorLine;
let nextLine = editorLine;
for (let i = 0; i < Math.max(0, skip) + 2; i++) {
const blameLine = await this.getBlameForLine(previous ?? current, nextLine, undefined, {
forceSingleLine: true,
});
if (blameLine == null) break;
// Diff with line ref with previous
ref = blameLine.commit.sha;
relativePath = blameLine.commit.file?.path ?? blameLine.commit.file?.originalPath ?? relativePath;
nextLine = blameLine.line.originalLine - 1;
const gitUri = GitUri.fromFile(relativePath, repoPath, ref);
if (previous == null) {
previous = gitUri;
previousLine = nextLine;
} else {
current = previous;
currentLine = previousLine;
previous = gitUri;
previousLine = nextLine;
}
}
if (current == null) return undefined;
return {
current: current,
previous: previous,
line: (currentLine ?? editorLine) + 1, // 1-based
};
} catch (ex) {
Logger.error(ex, cc);
debugger;

Loading…
Cancel
Save