mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-02 22:41:31 +01:00
Git - experimental git blame editor decoration (#234209)
* Initial implementation * Add setting, and cache blame information more aggressively
This commit is contained in:
@@ -1054,6 +1054,76 @@ function parseGitChanges(repositoryRoot: string, raw: string): Change[] {
|
||||
return result;
|
||||
}
|
||||
|
||||
export interface BlameInformation {
|
||||
readonly id: string;
|
||||
readonly date?: number;
|
||||
readonly message?: string;
|
||||
readonly authorName?: string;
|
||||
readonly authorEmail?: string;
|
||||
readonly ranges: {
|
||||
readonly startLineNumber: number;
|
||||
readonly endLineNumber: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
function parseGitBlame(data: string): BlameInformation[] {
|
||||
const lineSeparator = /\r?\n/;
|
||||
const commitRegex = /^([0-9a-f]{40})/gm;
|
||||
|
||||
const blameInformation = new Map<string, BlameInformation>();
|
||||
|
||||
let commitHash: string | undefined = undefined;
|
||||
let authorName: string | undefined = undefined;
|
||||
let authorEmail: string | undefined = undefined;
|
||||
let authorTime: number | undefined = undefined;
|
||||
let message: string | undefined = undefined;
|
||||
let startLineNumber: number | undefined = undefined;
|
||||
let endLineNumber: number | undefined = undefined;
|
||||
|
||||
for (const line of data.split(lineSeparator)) {
|
||||
// Commit
|
||||
const commitMatch = line.match(commitRegex);
|
||||
if (!commitHash && commitMatch) {
|
||||
const segments = line.split(' ');
|
||||
|
||||
commitHash = commitMatch[0];
|
||||
startLineNumber = Number(segments[2]);
|
||||
endLineNumber = Number(segments[2]) + Number(segments[3]) - 1;
|
||||
}
|
||||
|
||||
// Commit properties
|
||||
if (commitHash && line.startsWith('author ')) {
|
||||
authorName = line.substring('author '.length);
|
||||
}
|
||||
if (commitHash && line.startsWith('author-mail ')) {
|
||||
authorEmail = line.substring('author-mail '.length);
|
||||
}
|
||||
if (commitHash && line.startsWith('author-time ')) {
|
||||
authorTime = Number(line.substring('author-time '.length)) * 1000;
|
||||
}
|
||||
if (commitHash && line.startsWith('summary ')) {
|
||||
message = line.substring('summary '.length);
|
||||
}
|
||||
|
||||
// Commit end
|
||||
if (commitHash && startLineNumber && endLineNumber && line.startsWith('filename ')) {
|
||||
const existingCommit = blameInformation.get(commitHash);
|
||||
if (existingCommit) {
|
||||
existingCommit.ranges.push({ startLineNumber, endLineNumber });
|
||||
blameInformation.set(commitHash, existingCommit);
|
||||
} else {
|
||||
blameInformation.set(commitHash, {
|
||||
id: commitHash, authorName, authorEmail, date: authorTime, message, ranges: [{ startLineNumber, endLineNumber }]
|
||||
});
|
||||
}
|
||||
|
||||
commitHash = authorName = authorEmail = authorTime = message = startLineNumber = endLineNumber = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(blameInformation.values());
|
||||
}
|
||||
|
||||
export interface PullOptions {
|
||||
unshallow?: boolean;
|
||||
tags?: boolean;
|
||||
@@ -2137,6 +2207,18 @@ export class Repository {
|
||||
}
|
||||
}
|
||||
|
||||
async blame2(path: string): Promise<BlameInformation[] | undefined> {
|
||||
try {
|
||||
const args = ['blame', '--root', '--incremental', '--', sanitizePath(path)];
|
||||
const result = await this.exec(args);
|
||||
|
||||
return parseGitBlame(result.stdout.trim());
|
||||
}
|
||||
catch (err) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async createStash(message?: string, includeUntracked?: boolean, staged?: boolean): Promise<void> {
|
||||
try {
|
||||
const args = ['stash', 'push'];
|
||||
|
||||
Reference in New Issue
Block a user