git-forensics
A TypeScript library for providing insights from git commit history
A TypeScript library that analyzes git commit history to surface actionable insights about code health, ownership, and risk — processing ~700ms for 100,000 commits.
Installation
npm install git-forensics
Features
- Hotspot detection — Identify frequently changed files that may need refactoring
- Churn analysis — Measure code volatility across the repository
- Coupled files — Discover hidden dependencies between files that change together
- Code age tracking — Detect stale code that may need attention
- Ownership mapping — Understand knowledge distribution across contributors
- Actionable insights — Severity-ranked recommendations (
warning,critical) - Percentile-based classification — Self-calibrating thresholds that work across any codebase size
- Composite risk scoring — Weighted multi-metric risk score per file
- Rename-aware — Follows file renames and deletions through history
- Optimized for CI — Store forensics between runs and generate insights only for changed files
Usage
import { simpleGit } from 'simple-git';
import { computeForensics } from 'git-forensics';
const git = simpleGit('/path/to/repo');
const forensics = await computeForensics(git);
forensics.hotspots; // files changed most often
forensics.coupledPairs; // hidden dependencies
forensics.ownership; // knowledge silos
Generating Insights
generateInsights transforms metrics into alerts with severity (warning, critical) and human-readable fragments. Thresholds are percentile-based — a file is flagged by where it ranks against the rest of the repository, so they self-calibrate across codebases of any size.
import { generateInsights } from 'git-forensics';
const insights = generateInsights(forensics);
for (const insight of insights) {
console.log(`${insight.file} — ${insight.fragments.title}`);
console.log(` Risk: ${insight.fragments.risk}`);
console.log(` Action: ${insight.fragments.suggestion}`);
}
Composite Risk Score
computeRiskScores combines percentile ranks across all metrics into a single 0–100 risk score per file, with configurable weights:
import { computeRiskScores } from 'git-forensics';
const scores = computeRiskScores(forensics);
// [{ file: 'src/core/engine.ts', riskScore: 87.5, breakdown: { ... } }, ...]