Skip to content

Commit 92e37bd

Browse files
committed
Fixes #2952 error msg for missing ignore revs file
1 parent e75ffd7 commit 92e37bd

4 files changed

Lines changed: 83 additions & 20 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
66

77
## [Unreleased]
88

9+
### Fixed
10+
11+
- Fixes [#2952](https://github.com/gitkraken/vscode-gitlens/issues/2952) - Inline blame not working because of missing ignoreRevsFile
12+
913
## [14.4.0] - 2023-10-13
1014

1115
### Added

src/env/node/git/git.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { GlyphChars } from '../../../constants';
1010
import type { GitCommandOptions, GitSpawnOptions } from '../../../git/commandOptions';
1111
import { GitErrorHandling } from '../../../git/commandOptions';
1212
import {
13+
BlameIgnoreRevsFileError,
1314
FetchError,
1415
FetchErrorReason,
1516
PullError,
@@ -68,6 +69,7 @@ const textDecoder = new TextDecoder('utf8');
6869
const rootSha = '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
6970

7071
export const GitErrors = {
72+
badIgnoreRevsFile: /could not open object name list: (.*)\w/i,
7173
badRevision: /bad revision '(.*?)'/i,
7274
cantLockRef: /cannot lock ref|unable to update local ref/i,
7375
changesWouldBeOverwritten: /Your local changes to the following files would be overwritten/i,
@@ -464,10 +466,20 @@ export class Git {
464466
}
465467
}
466468

467-
return this.git<string>({ cwd: root, stdin: stdin }, ...params, '--', file);
469+
try {
470+
const blame = await this.git<string>({ cwd: root, stdin: stdin }, ...params, '--', file);
471+
return blame;
472+
} catch (ex) {
473+
// Since `-c blame.ignoreRevsFile=` doesn't seem to work (unlike as the docs suggest), try to detect the error and throw a more helpful one
474+
const match = GitErrors.badIgnoreRevsFile.exec(ex.message);
475+
if (match != null) {
476+
throw new BlameIgnoreRevsFileError(match[1], ex);
477+
}
478+
throw ex;
479+
}
468480
}
469481

470-
blame__contents(
482+
async blame__contents(
471483
repoPath: string | undefined,
472484
fileName: string,
473485
contents: string,
@@ -496,12 +508,22 @@ export class Git {
496508
// Pipe the blame contents to stdin
497509
params.push('--contents', '-');
498510

499-
return this.git<string>(
500-
{ cwd: root, stdin: contents, correlationKey: options.correlationKey },
501-
...params,
502-
'--',
503-
file,
504-
);
511+
try {
512+
const blame = await this.git<string>(
513+
{ cwd: root, stdin: contents, correlationKey: options.correlationKey },
514+
...params,
515+
'--',
516+
file,
517+
);
518+
return blame;
519+
} catch (ex) {
520+
// Since `-c blame.ignoreRevsFile=` doesn't seem to work (unlike as the docs suggest), try to detect the error and throw a more helpful one
521+
const match = GitErrors.badIgnoreRevsFile.exec(ex.message);
522+
if (match != null) {
523+
throw new BlameIgnoreRevsFileError(match[1], ex);
524+
}
525+
throw ex;
526+
}
505527
}
506528

507529
branchOrTag__containsOrPointsAt(

src/env/node/git/localGitProvider.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { emojify } from '../../../emojis';
2121
import { Features } from '../../../features';
2222
import { GitErrorHandling } from '../../../git/commandOptions';
2323
import {
24+
BlameIgnoreRevsFileError,
2425
FetchError,
2526
GitSearchError,
2627
PullError,
@@ -1463,19 +1464,24 @@ export class LocalGitProvider implements GitProvider, Disposable {
14631464
const blame = parseGitBlame(this.container, data, root, await this.getCurrentUser(root));
14641465
return blame;
14651466
} catch (ex) {
1467+
Logger.error(ex, scope);
1468+
14661469
// Trap and cache expected blame errors
14671470
if (document.state != null) {
14681471
const msg = ex?.toString() ?? '';
1469-
Logger.debug(scope, `Cache replace (with empty promise): '${key}'`);
1472+
Logger.debug(scope, `Cache replace (with empty promise): '${key}'; reason=${msg}`);
14701473

14711474
const value: CachedBlame = {
14721475
item: emptyPromise as Promise<GitBlame>,
14731476
errorMessage: msg,
14741477
};
14751478
document.state.setBlame(key, value);
1476-
14771479
document.setBlameFailure();
14781480

1481+
if (ex instanceof BlameIgnoreRevsFileError) {
1482+
void window.showErrorMessage(ex.friendlyMessage);
1483+
}
1484+
14791485
return emptyPromise as Promise<GitBlame>;
14801486
}
14811487

@@ -1544,18 +1550,24 @@ export class LocalGitProvider implements GitProvider, Disposable {
15441550
const blame = parseGitBlame(this.container, data, root, await this.getCurrentUser(root));
15451551
return blame;
15461552
} catch (ex) {
1553+
Logger.error(ex, scope);
1554+
15471555
// Trap and cache expected blame errors
15481556
if (document.state != null) {
15491557
const msg = ex?.toString() ?? '';
1550-
Logger.debug(scope, `Cache replace (with empty promise): '${key}'`);
1558+
Logger.debug(scope, `Cache replace (with empty promise): '${key}'; reason=${msg}`);
15511559

15521560
const value: CachedBlame = {
15531561
item: emptyPromise as Promise<GitBlame>,
15541562
errorMessage: msg,
15551563
};
15561564
document.state.setBlame(key, value);
1557-
15581565
document.setBlameFailure();
1566+
1567+
if (ex instanceof BlameIgnoreRevsFileError) {
1568+
void window.showErrorMessage(ex.friendlyMessage);
1569+
}
1570+
15591571
return emptyPromise as Promise<GitBlame>;
15601572
}
15611573

@@ -1575,6 +1587,8 @@ export class LocalGitProvider implements GitProvider, Disposable {
15751587
): Promise<GitBlameLine | undefined> {
15761588
if (document?.isDirty) return this.getBlameForLineContents(uri, editorLine, document.getText(), options);
15771589

1590+
const scope = getLogScope();
1591+
15781592
if (!options?.forceSingleLine && this.useCaching) {
15791593
const blame = await this.getBlame(uri, document);
15801594
if (blame == null) return undefined;
@@ -1614,7 +1628,12 @@ export class LocalGitProvider implements GitProvider, Disposable {
16141628
commit: first(blame.commits.values())!,
16151629
line: blame.lines[editorLine],
16161630
};
1617-
} catch {
1631+
} catch (ex) {
1632+
Logger.error(ex, scope);
1633+
if (ex instanceof BlameIgnoreRevsFileError) {
1634+
void window.showErrorMessage(ex.friendlyMessage);
1635+
}
1636+
16181637
return undefined;
16191638
}
16201639
}

src/git/errors.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,30 @@ export class GitSearchError extends Error {
66
}
77
}
88

9+
export class BlameIgnoreRevsFileError extends Error {
10+
static is(ex: unknown): ex is BlameIgnoreRevsFileError {
11+
return ex instanceof BlameIgnoreRevsFileError;
12+
}
13+
14+
readonly friendlyMessage: string;
15+
16+
constructor(
17+
filename: string,
18+
public readonly original?: Error,
19+
) {
20+
super(`Invalid blame.ignoreRevsFile: '${filename}'`);
21+
22+
this.friendlyMessage = `Unable to show blame. Invalid or missing blame.ignoreRevsFile (${filename}) specified in your Git config.`;
23+
Error.captureStackTrace?.(this, BlameIgnoreRevsFileError);
24+
}
25+
}
26+
927
export const enum StashApplyErrorReason {
1028
WorkingChanges = 1,
1129
}
1230

1331
export class StashApplyError extends Error {
14-
static is(ex: any, reason?: StashApplyErrorReason): ex is StashApplyError {
32+
static is(ex: unknown, reason?: StashApplyErrorReason): ex is StashApplyError {
1533
return ex instanceof StashApplyError && (reason == null || ex.reason === reason);
1634
}
1735

@@ -46,7 +64,7 @@ export const enum StashPushErrorReason {
4664
}
4765

4866
export class StashPushError extends Error {
49-
static is(ex: any, reason?: StashPushErrorReason): ex is StashPushError {
67+
static is(ex: unknown, reason?: StashPushErrorReason): ex is StashPushError {
5068
return ex instanceof StashPushError && (reason == null || ex.reason === reason);
5169
}
5270

@@ -93,7 +111,7 @@ export const enum PushErrorReason {
93111
}
94112

95113
export class PushError extends Error {
96-
static is(ex: any, reason?: PushErrorReason): ex is PushError {
114+
static is(ex: unknown, reason?: PushErrorReason): ex is PushError {
97115
return ex instanceof PushError && (reason == null || ex.reason === reason);
98116
}
99117

@@ -164,7 +182,7 @@ export const enum PullErrorReason {
164182
}
165183

166184
export class PullError extends Error {
167-
static is(ex: any, reason?: PullErrorReason): ex is PullError {
185+
static is(ex: unknown, reason?: PullErrorReason): ex is PullError {
168186
return ex instanceof PullError && (reason == null || ex.reason === reason);
169187
}
170188

@@ -240,7 +258,7 @@ export const enum FetchErrorReason {
240258
}
241259

242260
export class FetchError extends Error {
243-
static is(ex: any, reason?: FetchErrorReason): ex is FetchError {
261+
static is(ex: unknown, reason?: FetchErrorReason): ex is FetchError {
244262
return ex instanceof FetchError && (reason == null || ex.reason === reason);
245263
}
246264

@@ -301,7 +319,7 @@ export const enum WorktreeCreateErrorReason {
301319
}
302320

303321
export class WorktreeCreateError extends Error {
304-
static is(ex: any, reason?: WorktreeCreateErrorReason): ex is WorktreeCreateError {
322+
static is(ex: unknown, reason?: WorktreeCreateErrorReason): ex is WorktreeCreateError {
305323
return ex instanceof WorktreeCreateError && (reason == null || ex.reason === reason);
306324
}
307325

@@ -343,7 +361,7 @@ export const enum WorktreeDeleteErrorReason {
343361
}
344362

345363
export class WorktreeDeleteError extends Error {
346-
static is(ex: any, reason?: WorktreeDeleteErrorReason): ex is WorktreeDeleteError {
364+
static is(ex: unknown, reason?: WorktreeDeleteErrorReason): ex is WorktreeDeleteError {
347365
return ex instanceof WorktreeDeleteError && (reason == null || ex.reason === reason);
348366
}
349367

0 commit comments

Comments
 (0)