git_blame
Retrieve blame information to identify the author and commit for each line in a file from a Git repository. Specify repository path, file path, and revision to analyze code changes.
Instructions
Get blame information for a file.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file_path | Yes | Path to the file | |
| repo_path | Yes | The path to the local Git repository | |
| rev | No | Revision to blame (default: HEAD) | HEAD |
Implementation Reference
- src/handlers/other-operations.js:478-577 (handler)The handler function that performs 'git blame' on a specified file in a repository, parses the porcelain-format output to extract commit hash, author, and line content for each line, and returns structured JSON data./** * Gets blame information for a file * @param {string} repoPath - Path to the local repository * @param {string} filePath - Path to the file * @param {string} rev - Revision to blame (default: HEAD) * @returns {Object} - Blame result */ export async function handleGitBlame({ repo_path, file_path, rev = "HEAD" }) { try { const git = simpleGit(repo_path); // Run git blame const blameResult = await git.raw([ "blame", "--line-porcelain", rev, "--", file_path, ]); // Parse the output const lines = blameResult.split("\n"); const blameInfo = []; let currentCommit = null; for (let i = 0; i < lines.length; i++) { const line = lines[i]; // Start of a new blame entry if (line.match(/^[0-9a-f]{40}/)) { if (currentCommit) { blameInfo.push(currentCommit); } const parts = line.split(" "); currentCommit = { hash: parts[0], originalLine: parseInt(parts[1]), finalLine: parseInt(parts[2]), lineCount: parseInt(parts[3] || 1), author: "", authorMail: "", authorTime: 0, subject: "", content: "", }; } else if (line.startsWith("author ") && currentCommit) { currentCommit.author = line.substring(7); } else if (line.startsWith("author-mail ") && currentCommit) { currentCommit.authorMail = line.substring(12).replace(/[<>]/g, ""); } else if (line.startsWith("author-time ") && currentCommit) { currentCommit.authorTime = parseInt(line.substring(12)); } else if (line.startsWith("summary ") && currentCommit) { currentCommit.subject = line.substring(8); } else if (line.startsWith("\t") && currentCommit) { // This is the content line currentCommit.content = line.substring(1); blameInfo.push(currentCommit); currentCommit = null; } } // Add the last commit if there is one if (currentCommit) { blameInfo.push(currentCommit); } return { content: [ { type: "text", text: JSON.stringify( { success: true, file: file_path, blame: blameInfo, }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: "text", text: JSON.stringify( { error: `Failed to get blame information: ${error.message}` }, null, 2 ), }, ], isError: true, }; } }
- src/server.js:686-708 (schema)The input schema for the git_blame tool, defining required parameters repo_path and file_path, and optional rev parameter.{ name: "git_blame", description: "Get blame information for a file.", inputSchema: { type: "object", properties: { repo_path: { type: "string", description: "The path to the local Git repository", }, file_path: { type: "string", description: "Path to the file", }, rev: { type: "string", description: "Revision to blame (default: HEAD)", default: "HEAD", }, }, required: ["repo_path", "file_path"], }, },
- src/server.js:921-921 (registration)Registration of the git_blame tool name mapped to the handleGitBlame handler function in the server's handlersMap.git_blame: handleGitBlame,
- src/handlers/index.js:81-81 (registration)Re-export of handleGitBlame from other-operations.js in handlers index file, making it available for import in server.js.handleGitBlame,