Skip to content

Commit

Permalink
Fix multiple parallel blames and use vscode.git
Browse files Browse the repository at this point in the history
  • Loading branch information
Sertion committed Oct 21, 2018
1 parent a609ce9 commit 5c4ce91
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 51 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 2.5.0 (October 20, 2018)

* Bug: Sometimes gitblame blamed the same file multiple time in parallel. This is no longer the case.
* Feature: We now use `vscode.git` to find your git binary.
* Fix: Change the default info message format to be prefixed by the date instead of the commit hash. It is in ISO 8601 with dashes for separator.
* Fix: Updating Readme to better guide Bitbucket users to the `isWebPathPlural` setting.
* Fix: Removed `internalHashLength` setting. We now alsways use the whole hash.
Expand Down
7 changes: 7 additions & 0 deletions src/git.api.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface IVscodeGitExtension {
git: IGitPath;
}

export interface IGitPath {
path: string;
}
4 changes: 3 additions & 1 deletion src/git/blame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { execute } from "../util/execcommand";
import { getGitCommand } from "../util/gitcommand";
import { Property } from "../util/property";
import { TextDecorator } from "../util/textdecorator";
import { throttleFunction } from "../util/throttle.function";
import { StatusBarView } from "../view";
import { GitFile } from "./file";
import { GitFileFactory } from "./filefactory";
Expand Down Expand Up @@ -173,6 +174,7 @@ export class GitBlame {
this.onTextEditorMove();
}

@throttleFunction(16)
private async onTextEditorMove(): Promise<void> {
const beforeBlameOpenFile = this.getCurrentActiveFileName();
const beforeBlameLineNumber = this.getCurrentActiveLineNumber();
Expand Down Expand Up @@ -354,7 +356,7 @@ export class GitBlame {
return "";
}

const gitCommand = await getGitCommand();
const gitCommand = getGitCommand();
const activeFile = window.activeTextEditor.document.fileName;
const activeFileFolder = parse(activeFile).dir;
const originUrl = await execute(gitCommand, [
Expand Down
21 changes: 16 additions & 5 deletions src/git/filephysical.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ export class GitFilePhysical extends GitFile {
this.workTreePromise = this.findWorkTree();
}

this.workTree = await this.workTreePromise;
try {
this.workTree = await this.workTreePromise;
} catch (err) {
delete this.workTreePromise;
throw new Error("Unable to get git work tree");
}

return this.workTree;
}
Expand All @@ -87,7 +92,7 @@ export class GitFilePhysical extends GitFile {

private async executeGitRevParseCommand(command: string): Promise<string> {
const currentDirectory = dirname(this.fileName.fsPath);
const gitCommand = await getGitCommand();
const gitCommand = getGitCommand();
const gitExecArguments = ["rev-parse", command];
const gitExecOptions = {
cwd: currentDirectory,
Expand All @@ -102,12 +107,18 @@ export class GitFilePhysical extends GitFile {
}

private async findBlameInfo(): Promise<IGitBlameInfo> {
const workTree = await this.getGitWorkTree();
const blameInfo = GitBlame.blankBlameInfo();
let workTree: string;

try {
workTree = await this.getGitWorkTree();
} catch (err) {
return GitBlame.blankBlameInfo();
}

if (workTree) {
this.blameInfoPromise = new Promise<IGitBlameInfo>(
(resolve, reject) => {
const blameInfo = GitBlame.blankBlameInfo();
this.blameProcess = new GitBlameStream(
this.fileName,
workTree,
Expand Down Expand Up @@ -140,7 +151,7 @@ export class GitFilePhysical extends GitFile {
this.fileName.fsPath
}" is not a decendant of a git repository`,
);
this.blameInfoPromise = Promise.resolve(blameInfo);
this.blameInfoPromise = Promise.resolve(GitBlame.blankBlameInfo());
}

return this.blameInfoPromise;
Expand Down
23 changes: 11 additions & 12 deletions src/git/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class GitBlameStream extends EventEmitter {

private readonly file: Uri;
private readonly workTree: string;
private process: ChildProcess | undefined;
private readonly process: ChildProcess | undefined;
private readonly emittedCommits: { [hash: string]: true } = {};

constructor(file: Uri, workTree: string) {
Expand All @@ -23,20 +23,19 @@ export class GitBlameStream extends EventEmitter {
this.file = file;
this.workTree = workTree;

getGitCommand().then((gitCommand) => {
const args = this.generateArguments();
const spawnOptions = {
cwd: workTree,
};
const gitCommand = getGitCommand();
const args = this.generateArguments();
const spawnOptions = {
cwd: workTree,
};

ErrorHandler.logCommand(
`${gitCommand} ${args.join(" ")}`,
);
ErrorHandler.logCommand(
`${gitCommand} ${args.join(" ")}`,
);

this.process = spawn(gitCommand, args, spawnOptions);
this.process = spawn(gitCommand, args, spawnOptions);

this.setupListeners();
});
this.setupListeners();
}

public terminate(): void {
Expand Down
49 changes: 16 additions & 33 deletions src/util/gitcommand.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,21 @@
import { access, constants as FSConstant } from "fs";
import { normalize } from "path";

import { workspace } from "vscode";
import { extensions } from "vscode";

import { GIT_COMMAND_IN_PATH } from "../constants";
import { ErrorHandler } from "./errorhandler";

export function getGitCommand(): Promise<string> {
const gitConfig = workspace.getConfiguration("git");
const pathCommand = gitConfig.get("path") as string;
const promise = new Promise<string>((resolve, reject) => {
if (!pathCommand) {
resolve(GIT_COMMAND_IN_PATH);
}

const commandPath = normalize(pathCommand);
import { IVscodeGitExtension } from "../git.api.interface";

access(commandPath, FSConstant.X_OK, (err) => {
if (err) {
ErrorHandler.logError(
new Error(
`Can not execute "${
commandPath
}" (your git.path property) falling back to "${
GIT_COMMAND_IN_PATH
}"`,
),
);
resolve(GIT_COMMAND_IN_PATH);
} else {
resolve(commandPath);
}
});
});
export function getGitCommand(): string {
const vscodeGit = extensions.getExtension<IVscodeGitExtension>(
"vscode.git",
);

return promise;
if (
vscodeGit
&& vscodeGit.exports
&& vscodeGit.exports.git
&& vscodeGit.exports.git.path
) {
return vscodeGit.exports.git.path;
} else {
return GIT_COMMAND_IN_PATH;
}
}
32 changes: 32 additions & 0 deletions src/util/throttle.function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const cache: Set<symbol> = new Set();

/**
* Throttle a function. It will ignore any calls to it in the
* timeout time since it was last called successfully.
*
* @param timeout in milliseconds
*/
export function throttleFunction(timeout: number): (
target: any,
propertyKey: string,
descriptor: TypedPropertyDescriptor<any>,
) => void {
return (
target: any,
propertyKey: string,
descriptor: TypedPropertyDescriptor<any>,
) => {
const oldMethod = descriptor.value;
const identifier = Symbol();

descriptor.value = function(...args: any[]): void {
if (!cache.has(identifier)) {
oldMethod.call(this, args);
cache.add(identifier);
setTimeout(() => {
cache.delete(identifier);
}, timeout);
}
};
};
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"sourceMap": true,
"rootDir": ".",
"baseUrl": "src",
"experimentalDecorators": true,
},
"exclude": [
"node_modules",
Expand Down

0 comments on commit 5c4ce91

Please sign in to comment.