Skip to main content
Glama

Frontend Test Generation & Code Review MCP Server

fetch-commit-changes.ts3.44 kB
import { execSync } from 'node:child_process'; import { existsSync } from 'node:fs'; import { logger } from '../utils/logger.js'; import { parseDiff, generateNumberedDiff } from '../utils/diff-parser.js'; import type { Diff } from '../schemas/diff.js'; export interface FetchCommitChangesInput { commitHash: string; repoPath?: string; } export interface FetchCommitChangesOutput { diff: Diff; commitInfo: { hash: string; author: string; date: string; message: string; }; } export class FetchCommitChangesTool { async fetch(input: FetchCommitChangesInput): Promise<FetchCommitChangesOutput> { const { commitHash, repoPath = process.cwd() } = input; try { // 验证 repo 路径 if (!existsSync(repoPath)) { throw new Error(`Repository path does not exist: ${repoPath}`); } // 验证是否是 git 仓库 try { execSync('git rev-parse --git-dir', { cwd: repoPath, stdio: 'pipe', }); } catch { throw new Error(`Not a git repository: ${repoPath}`); } logger.info(`Fetching commit changes for ${commitHash}...`); // 获取 commit 信息 const commitInfoRaw = execSync( `git show --no-patch --format="%H%n%an%n%ai%n%s" ${commitHash}`, { cwd: repoPath, encoding: 'utf-8', } ); const [hash, author, date, message] = commitInfoRaw.trim().split('\n'); // 获取 diff const diffRaw = execSync(`git show ${commitHash}`, { cwd: repoPath, encoding: 'utf-8', }); // 解析 diff const diff = parseDiff(diffRaw, `commit:${commitHash}`, { title: message, summary: `Commit by ${author} on ${date}`, author, }); // 生成带行号的 diff diff.numberedRaw = generateNumberedDiff(diff); logger.info( `Fetched commit ${commitHash.substring(0, 7)} with ${diff.files.length} files changed` ); return { diff, commitInfo: { hash, author, date, message, }, }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); logger.error(`Failed to fetch commit changes: ${commitHash}`, { error: errorMessage }); throw new Error(`Failed to fetch commit changes: ${errorMessage}`); } } /** * 获取多个 commits 的变更(用于分析一系列提交) */ async fetchRange( commitRange: string, repoPath?: string ): Promise<FetchCommitChangesOutput[]> { try { // 获取 commit 列表 const commitHashes = execSync(`git log --format=%H ${commitRange}`, { cwd: repoPath || process.cwd(), encoding: 'utf-8', }) .trim() .split('\n') .filter(Boolean); logger.info(`Fetching ${commitHashes.length} commits in range ${commitRange}...`); // 并行获取所有 commits const results = await Promise.all( commitHashes.map(hash => this.fetch({ commitHash: hash, repoPath }) ) ); return results; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); logger.error(`Failed to fetch commit range: ${commitRange}`, { error: errorMessage }); throw new Error(`Failed to fetch commit range: ${errorMessage}`); } } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NorthSeacoder/fe-testgen-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server