Skip to content
This repository was archived by the owner on Feb 15, 2025. It is now read-only.

Commit 3e7411e

Browse files
committed
feat: add git operations for fetching bulk blame for file
1 parent 97a84c8 commit 3e7411e

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

src/git.ts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { exec } from 'child_process';
2+
3+
export interface CommitInfo {
4+
commitHash: string;
5+
author: string;
6+
lineNumber: number;
7+
commitTitle: string;
8+
}
9+
10+
export function fetchFileBlame(file: string): Promise<CommitInfo[]> {
11+
return new Promise<CommitInfo[]>((resolve, reject) => {
12+
// Run git blame
13+
exec(`git blame -w ${file}`, async (error, stdout, stderr) => {
14+
if (error) {
15+
console.error(`Error executing git blame: ${error.message}`);
16+
reject(error.message);
17+
return;
18+
}
19+
20+
const commitInfos: CommitInfo[] = [];
21+
const commitHashes = new Set<string>();
22+
23+
stdout.split('\n').forEach(line => {
24+
if (line.trim() === '') {
25+
return;
26+
}
27+
28+
const match = line.match(/^([^\s]+) \(([^)]+)\s+(\d+)\) .*/);
29+
if (match) {
30+
const commitHash = match[1];
31+
const authorInfo = match[2];
32+
const lineNumber = parseInt(match[3], 10);
33+
34+
// Extract the author's name from authorInfo
35+
const authorName = authorInfo.split(' ').slice(0, -3).join(' ');
36+
37+
commitHashes.add(commitHash);
38+
39+
commitInfos.push({
40+
commitHash,
41+
author: authorName,
42+
lineNumber,
43+
commitTitle: '', // Placeholder for commit title
44+
});
45+
} else {
46+
console.warn(`Unexpected format for line: ${line}`);
47+
}
48+
});
49+
50+
// Fetch commit titles for the found commit hashes
51+
try {
52+
const commitTitles = await fetchCommitTitles(Array.from(commitHashes));
53+
54+
// Assign commit titles to commitInfos
55+
commitInfos.forEach(info => {
56+
if (commitTitles.has(info.commitHash)) {
57+
info.commitTitle = commitTitles.get(info.commitHash) || '';
58+
}
59+
});
60+
61+
resolve(commitInfos);
62+
} catch (fetchError) {
63+
reject(`Error fetching commit titles: ${fetchError}`);
64+
}
65+
});
66+
});
67+
}
68+
69+
// Function to fetch commit titles from commit hashes using git log
70+
function fetchCommitTitles(commitHashes: string[]): Promise<Map<string, string>> {
71+
return new Promise<Map<string, string>>((resolve, reject) => {
72+
const gitLogCommand = `git log --format="%H %s" ${commitHashes.join(' ')}`;
73+
74+
exec(gitLogCommand, (error, stdout, stderr) => {
75+
if (error) {
76+
reject(`Error executing git log: ${error.message}`);
77+
return;
78+
}
79+
80+
const commitTitles = new Map<string, string>();
81+
82+
stdout.split('\n').forEach(line => {
83+
if (line.trim() !== '') {
84+
const [commitHash, ...titleParts] = line.trim().split(' ');
85+
const commitTitle = titleParts.join(' ');
86+
commitTitles.set(commitHash, commitTitle);
87+
}
88+
});
89+
90+
resolve(commitTitles);
91+
});
92+
});
93+
}

0 commit comments

Comments
 (0)