Browse Source

Adds timeout to resolve refs

Merge commits can take a long time to resolve (if at all)
main
Eric Amodio 4 years ago
parent
commit
c5ab5757a8
3 changed files with 29 additions and 15 deletions
  1. +2
    -2
      src/commands/diffWith.ts
  2. +7
    -9
      src/git/git.ts
  3. +20
    -4
      src/git/gitService.ts

+ 2
- 2
src/commands/diffWith.ts View File

@ -88,8 +88,8 @@ export class DiffWithCommand extends Command {
let rhsSha = args.rhs.sha;
[args.lhs.sha, args.rhs.sha] = await Promise.all([
await Container.git.resolveReference(args.repoPath, args.lhs.sha, args.lhs.uri),
await Container.git.resolveReference(args.repoPath, args.rhs.sha, args.rhs.uri),
await Container.git.resolveReference(args.repoPath, args.lhs.sha, args.lhs.uri, { timeout: 100 }),
await Container.git.resolveReference(args.repoPath, args.rhs.sha, args.rhs.uri, { timeout: 100 }),
]);
if (args.lhs.sha !== GitRevision.deletedOrMissing) {

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

@ -823,15 +823,13 @@ export namespace Git {
return data.length === 0 ? undefined : data.trim();
}
export async function log__find_object(repoPath: string, objectId: string, ref: string) {
const data = await git<string>(
{ cwd: repoPath, errors: GitErrorHandling.Ignore },
'log',
'-n1',
'--format=%H',
`--find-object=${objectId}`,
ref,
);
export async function log__find_object(repoPath: string, objectId: string, ref: string, file?: string) {
const params = ['log', '-n1', '--no-renames', '--format=%H', `--find-object=${objectId}`, ref];
if (file) {
params.push('--', file);
}
const data = await git<string>({ cwd: repoPath, errors: GitErrorHandling.Ignore }, ...params);
return data.length === 0 ? undefined : data.trim();
}

+ 20
- 4
src/git/gitService.ts View File

@ -27,6 +27,7 @@ import { Messages } from '../messages';
import {
Arrays,
debug,
Functions,
gate,
Iterables,
log,
@ -3155,10 +3156,20 @@ export class GitService implements Disposable {
return Git.difftool__dir_diff(repoPath, tool, ref1, ref2);
}
async resolveReference(repoPath: string, ref: string, fileName?: string): Promise<string>;
async resolveReference(repoPath: string, ref: string, uri?: Uri): Promise<string>;
async resolveReference(
repoPath: string,
ref: string,
fileName?: string,
options?: { timeout?: number },
): Promise<string>;
async resolveReference(repoPath: string, ref: string, uri?: Uri, options?: { timeout?: number }): Promise<string>;
@log()
async resolveReference(repoPath: string, ref: string, fileNameOrUri?: string | Uri) {
async resolveReference(
repoPath: string,
ref: string,
fileNameOrUri?: string | Uri,
options?: { timeout?: number },
) {
if (ref == null || ref.length === 0 || ref === GitRevision.deletedOrMissing || GitRevision.isUncommitted(ref)) {
return ref;
}
@ -3177,7 +3188,12 @@ export class GitService implements Disposable {
const blob = await Git.rev_parse__verify(repoPath, ref, fileName);
if (blob == null) return GitRevision.deletedOrMissing;
return (await Git.log__find_object(repoPath, blob, ref)) ?? ref;
let promise: Promise<string | void | undefined> = Git.log__find_object(repoPath, blob, ref, fileName);
if (options?.timeout != null) {
promise = Promise.race([promise, Functions.wait(options.timeout)]);
}
return (await promise) ?? ref;
}
@log()

Loading…
Cancel
Save