diff --git a/src/commands/diffWith.ts b/src/commands/diffWith.ts index ac1b59b..3b04033 100644 --- a/src/commands/diffWith.ts +++ b/src/commands/diffWith.ts @@ -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) { diff --git a/src/git/git.ts b/src/git/git.ts index f56609f..f1a4ab1 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -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( - { 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({ cwd: repoPath, errors: GitErrorHandling.Ignore }, ...params); return data.length === 0 ? undefined : data.trim(); } diff --git a/src/git/gitService.ts b/src/git/gitService.ts index 15d1002..9d5c4c3 100644 --- a/src/git/gitService.ts +++ b/src/git/gitService.ts @@ -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; - async resolveReference(repoPath: string, ref: string, uri?: Uri): Promise; + async resolveReference( + repoPath: string, + ref: string, + fileName?: string, + options?: { timeout?: number }, + ): Promise; + async resolveReference(repoPath: string, ref: string, uri?: Uri, options?: { timeout?: number }): Promise; @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 = 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()