Browse Source

Adds support for `.git-blame-ignore-rev` files

main
Eric Amodio 1 year ago
parent
commit
ea78a75267
5 changed files with 67 additions and 37 deletions
  1. +0
    -0
      .git-blame-ignore-revs
  2. +0
    -1
      .vscode/settings.json
  3. +1
    -0
      CHANGELOG.md
  4. +57
    -27
      src/env/node/git/git.ts

.gitignore-revs → .git-blame-ignore-revs View File


+ 0
- 1
.vscode/settings.json View File

@ -38,7 +38,6 @@
"query": "state:open repo:${owner}/${repository} sort:updated-desc"
}
],
"gitlens.advanced.blame.customArguments": ["--ignore-revs-file", ".gitignore-revs"],
"[html][javascript][json][jsonc][markdown][scss][svg][typescript][typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},

+ 1
- 0
CHANGELOG.md View File

@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- Adds an experimental _Generate Commit Message (Experimental)_ command to use OpenAI to generate a commit message for staged changes — currently only available in the pre-release edition
- Adds a _Open Git Worktree..._ command to jump directly to opening a worktree in the _Git Command Palette_
- Adds auto-detection for `.git-blame-ignore-revs` files and excludes the commits listed within from the blame annotations
### Fixed

+ 57
- 27
src/env/node/git/git.ts View File

@ -294,17 +294,31 @@ export class Git {
return proc;
}
private gitLocator!: () => Promise<GitLocation>;
private _gitLocation: GitLocation | undefined;
private _gitLocationPromise: Promise<GitLocation> | undefined;
private async getLocation(): Promise<GitLocation> {
if (this._gitLocation == null) {
if (this._gitLocationPromise == null) {
this._gitLocationPromise = this._gitLocator();
}
this._gitLocation = await this._gitLocationPromise;
}
return this._gitLocation;
}
private _gitLocator!: () => Promise<GitLocation>;
setLocator(locator: () => Promise<GitLocation>): void {
this.gitLocator = locator;
this._gitLocator = locator;
this._gitLocationPromise = undefined;
this._gitLocation = undefined;
}
async path(): Promise<string> {
return (await this.gitLocator()).path;
return (await this.getLocation()).path;
}
async version(): Promise<string> {
return (await this.gitLocator()).version;
return (await this.getLocation()).version;
}
async isAtLeastVersion(minimum: string): Promise<boolean> {
@ -312,6 +326,12 @@ export class Git {
return result !== -1;
}
maybeIsAtLeastVersion(minimum: string): boolean | undefined {
return this._gitLocation != null
? compare(fromString(this._gitLocation.version), fromString(minimum)) !== -1
: undefined;
}
// Git commands
add(repoPath: string | undefined, pathspec: string) {
@ -346,38 +366,48 @@ export class Git {
}
if (options.args != null) {
params.push(...options.args);
}
const index = params.indexOf('--ignore-revs-file');
if (index !== -1) {
// Ensure the version of Git supports the --ignore-revs-file flag, otherwise the blame will fail
let supported = await this.isAtLeastVersion('2.23');
if (supported) {
let ignoreRevsFile = params[index + 1];
if (!isAbsolute(ignoreRevsFile)) {
ignoreRevsFile = joinPaths(repoPath ?? '', ignoreRevsFile);
}
// Ensure the version of Git supports the --ignore-revs-file flag, otherwise the blame will fail
let supportsIgnoreRevsFile = this.maybeIsAtLeastVersion('2.23');
if (supportsIgnoreRevsFile === undefined) {
supportsIgnoreRevsFile = await this.isAtLeastVersion('2.23');
}
const exists = this.ignoreRevsFileMap.get(ignoreRevsFile);
if (exists !== undefined) {
supported = exists;
} else {
// Ensure the specified --ignore-revs-file exists, otherwise the blame will fail
try {
supported = await fsExists(ignoreRevsFile);
} catch {
supported = false;
}
const ignoreRevsIndex = params.indexOf('--ignore-revs-file');
this.ignoreRevsFileMap.set(ignoreRevsFile, supported);
}
if (supportsIgnoreRevsFile) {
let ignoreRevsFile;
if (ignoreRevsIndex !== -1) {
ignoreRevsFile = params[ignoreRevsIndex + 1];
if (!isAbsolute(ignoreRevsFile)) {
ignoreRevsFile = joinPaths(root, ignoreRevsFile);
}
} else {
ignoreRevsFile = joinPaths(root, '.git-blame-ignore-revs');
}
if (!supported) {
params.splice(index, 2);
const exists = this.ignoreRevsFileMap.get(ignoreRevsFile);
if (exists !== undefined) {
supportsIgnoreRevsFile = exists;
} else {
// Ensure the specified --ignore-revs-file exists, otherwise the blame will fail
try {
supportsIgnoreRevsFile = await fsExists(ignoreRevsFile);
} catch {
supportsIgnoreRevsFile = false;
}
this.ignoreRevsFileMap.set(ignoreRevsFile, supportsIgnoreRevsFile);
}
}
if (!supportsIgnoreRevsFile && ignoreRevsIndex !== -1) {
params.splice(ignoreRevsIndex, 2);
} else if (supportsIgnoreRevsFile && ignoreRevsIndex === -1) {
params.push('--ignore-revs-file', '.git-blame-ignore-revs');
}
let stdin;
if (ref) {
if (isUncommittedStaged(ref)) {

Loading…
Cancel
Save