git-contributor-stats
v2.2.0
Published
CLI to compute contributor and repository statistics from a Git repository (commits, lines added/deleted, frequency, heatmap, bus-factor), with filters and multiple output formats.
Maintainers
Readme
git-contributor-stats
A powerful, fast Node.js CLI and library to analyze Git repository contributions with detailed statistics, charts, and multiple output formats.
📦 Modular & Tree-Shakeable
This package uses subpath exports for optimal bundle sizes. Import only what you need:
git-contributor-stats/stats- Core statisticsgit-contributor-stats/charts- Chart generationgit-contributor-stats/reports- Report generationgit-contributor-stats/output- Console outputgit-contributor-stats/workflow- GitHub Actions workflowSee Technical Docs for architecture details and Quick Start for usage examples.
Overview
Analyze your Git repository to gain insights into contributor activity, code ownership, commit patterns, and project health. Get comprehensive statistics including commits, lines added/deleted, file changes, temporal patterns, bus factor analysis, and beautiful visualizations.
Requirements: Node.js 18+ (ESM-only)
Table of Contents
- Features
- Installation
- Quick Start
- CLI Usage
- Programmatic API
- Identity Management
- Configuration
- Examples
- Output Reference
- Performance Tips
- Documentation
- Contributing
- License
Features
Core Analytics
- Contributor Metrics: Commits, lines added/deleted, net contributions, file changes
- Top Contributors: Ranked by commits, additions, deletions, net changes, or total changes
- File-Level Insights: Top files per contributor, ownership distribution
- Temporal Analysis: Monthly and weekly commit frequency breakdown
- Activity Heatmap: Commit patterns by weekday and hour (7×24 grid)
- Bus Factor: Identify single-owner files and knowledge concentration risks
- Total LOC: Count total lines across tracked files (optional for performance)
Filtering & Grouping
- Branch/Range: Analyze specific branches or commit ranges
- Time-Based: Filter by date (absolute or relative:
90.days,2.weeks, etc.) - Author Patterns: Focus on specific contributors
- Path Filtering: Analyze specific directories or files
- Identity Merging: Consolidate multiple emails/names per contributor
Output & Visualization
- Multiple Formats: Table, JSON, CSV, Markdown, HTML
- Charts: SVG/PNG bar charts (top commits, net contributions) and heatmaps
- Customizable Reports: Control which sections appear in outputs
- Batch Export: Write all reports to a single directory
Developer Experience
- Dual Interface: CLI tool and programmatic Node.js API
- TypeScript Support: Full type definitions included
- GitHub Actions: Built-in workflow generator
- Performance Options: Skip expensive operations when needed
Installation
Global Installation (CLI)
npm install -g git-contributor-statsLocal Project (Programmatic Use)
npm install git-contributor-statsQuick Start
💡 New to this tool? See Quick Start Guide for detailed use cases and examples
CLI - Basic Usage
# Analyze current repository
git-contributor-stats
# Top 10 contributors
git-contributor-stats --top 10
# Last 90 days with JSON output
git-contributor-stats --since 90.days --json
# Generate all reports and charts (most popular!)
git-contributor-stats --out-dir reports --md --html --charts
# Specific folder analysis
git-contributor-stats src/ --top 20Programmatic - Basic Usage
// Import only what you need using subpath exports
import { getContributorStats } from 'git-contributor-stats/stats';
const stats = await getContributorStats({
repo: '.',
since: '90.days',
countLines: false
});
console.log(`Total commits: ${stats.totalCommits}`);
console.log(`Top contributor: ${stats.topContributors[0].name}`);CLI Usage
Command Syntax
git-contributor-stats [options] [paths...]Arguments:
[paths...]- Optional pathspec(s) to limit analysis to certain files/directories
Basic Commands
# Show help
git-contributor-stats --help
# Show version
git-contributor-stats --version
# Analyze current repository (default: table output)
git-contributor-stats
# Analyze specific repository
git-contributor-stats --repo /path/to/repo
# Analyze specific paths only
git-contributor-stats src/ lib/Filtering Options
Repository & Branch
| Option | Description | Example |
|--------|-------------|---------|
| -r, --repo <path> | Path to Git repository | --repo /path/to/repo |
| -b, --branch <name> | Branch or commit range | --branch main or --branch main..feature |
Time-Based Filtering
| Option | Description | Example |
|--------|-------------|---------|
| --since <when> | Only commits after date | --since 2024-01-01 or --since 90.days |
| --until <when> | Only commits before date | --until 2024-12-31 or --until 1.week |
Supported relative time formats:
- Days:
30.days,1.day - Weeks:
2.weeks,1.week - Months:
3.months,1.month - Years:
1.year,2.years
Example:
# Last quarter
git-contributor-stats --since 90.days
# Specific date range
git-contributor-stats --since 2024-01-01 --until 2024-06-30
# Last 2 weeks on main branch
git-contributor-stats -b main --since 2.weeksAuthor & Merge Filtering
| Option | Description | Example |
|--------|-------------|---------|
| -a, --author <pattern> | Filter by author (string/regex) | --author "John" |
| --include-merges | Include merge commits | --include-merges |
Example:
# Contributions from specific author
git-contributor-stats --author "[email protected]"
# Include merge commits (excluded by default)
git-contributor-stats --include-mergesGrouping & Sorting
| Option | Description | Default | Values |
|--------|-------------|---------|--------|
| -g, --group-by <field> | Group contributors by | email | email, name |
| -s, --sort-by <metric> | Sort contributors by | changes | changes, commits, additions, deletions |
| -t, --top <n> | Limit to top N contributors | All | Any number |
Example:
# Group by name instead of email
git-contributor-stats --group-by name
# Sort by commit count, show top 15
git-contributor-stats --sort-by commits --top 15
# Sort by net lines added
git-contributor-stats --sort-by additions --top 10Output Formats
Standard Output (stdout)
| Option | Description | Output |
|--------|-------------|--------|
| -f, --format <kind> | Format for stdout | table, json, csv |
| --json | Comprehensive JSON analysis | Full analysis object |
Example:
# Table output (default)
git-contributor-stats
# JSON to stdout
git-contributor-stats --json
# CSV to stdout
git-contributor-stats --format csv
# Compact table with top 10
git-contributor-stats --format table --top 10File Outputs
| Option | Description |
|--------|-------------|
| --csv <path> | Write CSV report to file |
| --md <path> | Write Markdown report to file |
| --html <path> | Write HTML dashboard to file |
| --out-dir <path> | Directory for all outputs (uses default names) |
Example:
# Individual file outputs
git-contributor-stats --csv stats.csv --md report.md --html dashboard.html
# Use output directory (creates contributors.csv, report.md, report.html)
git-contributor-stats --out-dir reports
# Combine with specific names
git-contributor-stats --out-dir reports --md reports/custom-report.mdCharts & Visualizations
Chart Generation
| Option | Description | Default |
|--------|-------------|---------|
| --charts | Generate charts | Disabled |
| --charts-dir <path> | Directory for charts | ./charts or --out-dir |
| --chart-format <fmt> | Chart format | svg |
Chart formats:
svg- Scalable Vector Graphics (recommended)png- Portable Network Graphicsboth- Generate both SVG and PNG
Generated charts:
top-commits.svg/png- Bar chart of top contributors by commit counttop-net.svg/png- Bar chart of top contributors by net linesheatmap.svg/png- Activity heatmap (weekday × hour)
Example:
# Generate SVG charts in default location
git-contributor-stats --charts
# Generate PNG charts
git-contributor-stats --charts --chart-format png
# Generate both formats in custom directory
git-contributor-stats --charts --charts-dir ./output/charts --chart-format both
# Charts with reports
git-contributor-stats --out-dir reports --md --html --chartsReport Customization
Top Stats Configuration
Control which metrics appear in the "Top Stats" section of reports and stdout:
| Option | Description | Default |
|--------|-------------|---------|
| --top-stats <list> | Comma-separated metrics to show | All metrics |
| --no-top-stats | Omit Top Stats section entirely | Enabled |
Available metrics:
commits- Most commitsadditions- Most lines addeddeletions- Most lines deletednet- Best net contribution (additions - deletions)changes- Most total changes (additions + deletions)
Example:
# Show only commits and net in Top Stats
git-contributor-stats --top-stats commits,net --md report.md
# Omit Top Stats entirely (faster, cleaner output)
git-contributor-stats --no-top-stats --html dashboard.html
# Default: all metrics shown
git-contributor-stats --md report.mdIdentity Management
| Option | Description |
|--------|-------------|
| --alias-file <path> | Path to alias mapping JSON |
| --similarity <0..1> | Name merge similarity threshold (default: 0.85) |
Example:
# Use custom alias file
git-contributor-stats --alias-file config/aliases.json
# Adjust similarity threshold (higher = stricter matching)
git-contributor-stats --similarity 0.9
# Combine with reports
git-contributor-stats --alias-file aliases.json --out-dir reports --md --htmlSee Identity Management section for alias file format.
Performance Options
| Option | Description | Impact |
|--------|-------------|--------|
| --no-count-lines | Skip total LOC counting | Faster analysis |
Example:
# Skip LOC counting for large repos (significant speed improvement)
git-contributor-stats --no-count-lines --json
# Fast report generation
git-contributor-stats --out-dir reports --md --html --no-count-linesAdditional Options
| Option | Description |
|--------|-------------|
| --generate-workflow | Create GitHub Actions workflow file |
| -v, --verbose | Enable verbose logging (stderr) |
Example:
# Generate GitHub Actions workflow
git-contributor-stats --generate-workflow
# Debug mode
git-contributor-stats --verbose --json
# See what git commands are being run
git-contributor-stats -v --since 30.daysProgrammatic API
Use git-contributor-stats as a library in your Node.js/TypeScript projects.
Basic Usage
import { getContributorStats } from 'git-contributor-stats/stats';
// Analyze current repository
const stats = await getContributorStats({
repo: '.',
since: '90.days',
countLines: false
});
console.log(`Total commits: ${stats.totalCommits}`);
console.log(`Contributors: ${Object.keys(stats.contributors).length}`);
console.log(`Top contributor: ${stats.topContributors[0].name}`);API Reference
getContributorStats(options)
Returns a Promise that resolves to a comprehensive analysis object.
Options:
interface ContributorStatsOptions {
// Repository options
repo?: string; // Path to repository (default: '.')
branch?: string; // Branch or range (e.g., 'main..feature')
paths?: string | string[]; // Pathspec(s) to limit analysis
// Filtering options
since?: string; // Date or relative time (e.g., '90.days')
until?: string; // Date or relative time
author?: string; // Author pattern (string/regex)
includeMerges?: boolean; // Include merge commits (default: false)
// Grouping & sorting
groupBy?: 'email' | 'name'; // Group by field (default: 'email')
labelBy?: 'email' | 'name'; // Display label (default: 'name')
sortBy?: 'changes' | 'commits' | 'additions' | 'deletions';
top?: number; // Limit to top N contributors
// Identity management
similarity?: number; // Name merge threshold (default: 0.85)
aliasFile?: string; // Path to alias JSON file
aliasConfig?: AliasConfig; // Inline alias configuration
// Performance
countLines?: boolean; // Count total LOC (default: true)
verbose?: boolean; // Enable verbose logging (default: false)
}Return Value:
interface ContributorStatsResult {
meta: {
generatedAt: string; // ISO timestamp
repo: string; // Repository path
branch: string | null; // Branch name
since: string | null; // Since date/time
until: string | null; // Until date/time
};
totalCommits: number; // Total commit count
totalLines: number; // Total lines of code
contributors: Record<string, ContributorsMapEntry>;
topContributors: TopContributor[];
topStats: {
byCommits: TopContributor | null;
byAdditions: TopContributor | null;
byDeletions: TopContributor | null;
byNet: TopContributor | null;
byChanges: TopContributor | null;
};
commitFrequency: {
monthly: Record<string, number>;
weekly: Record<string, number>;
};
heatmap: number[][]; // 7x24 grid (weekday x hour)
busFactor: {
filesSingleOwner: Array<{
file: string;
owner: string;
changes: number;
}>;
};
basic: {
contributors: TopContributor[];
meta: ContributorsMeta;
groupBy: 'email' | 'name';
};
}Advanced Usage Examples
Analyze Specific Time Period
import { getContributorStats } from 'git-contributor-stats/stats';
const stats = await getContributorStats({
repo: '/path/to/repo',
since: '2024-01-01',
until: '2024-06-30',
branch: 'main'
});
console.log('Q1-Q2 2024 Stats:');
console.log(`- Commits: ${stats.totalCommits}`);
console.log(`- Active contributors: ${stats.topContributors.length}`);Filter by Author and Path
import { getContributorStats } from 'git-contributor-stats/stats';
const stats = await getContributorStats({
repo: '.',
author: '[email protected]',
paths: ['src/', 'lib/'],
since: '30.days'
});
console.log(`Jane's contributions in src/ and lib/ (last 30 days):`);
console.log(`- Commits: ${stats.topContributors[0]?.commits || 0}`);
console.log(`- Files changed: ${Object.keys(stats.topContributors[0]?.files || {}).length}`);Generate Reports Programmatically
import { getContributorStats } from 'git-contributor-stats/stats';
import { generateReports } from 'git-contributor-stats/reports';
const stats = await getContributorStats({
repo: '.',
since: '90.days',
countLines: false
});
// Generate reports
await generateReports(stats, {
outDir: 'reports',
md: 'reports/quarterly-report.md',
html: 'reports/quarterly-report.html',
csv: 'reports/contributors.csv'
});
console.log('Reports generated in ./reports/');Generate Charts Programmatically
import { getContributorStats } from 'git-contributor-stats/stats';
import { generateCharts } from 'git-contributor-stats/charts';
const stats = await getContributorStats({
repo: '.',
since: '90.days'
});
// Generate SVG charts
await generateCharts(stats, {
charts: true,
chartsDir: 'output/charts',
chartFormat: 'svg'
});
// Or PNG charts
await generateCharts(stats, {
charts: true,
chartsDir: 'output/charts',
chartFormat: 'png'
});
// Or both
await generateCharts(stats, {
charts: true,
chartsDir: 'output/charts',
chartFormat: 'both'
});Using Alias Configuration Inline
import { getContributorStats } from 'git-contributor-stats/stats';
const stats = await getContributorStats({
repo: '.',
aliasConfig: {
groups: [
['[email protected]', '[email protected]', 'Jane Doe'],
['[email protected]', '[email protected]']
],
canonical: {
'[email protected]': {
name: 'Jane Doe',
email: '[email protected]'
},
'[email protected]': {
name: 'John Smith',
email: '[email protected]'
}
}
},
similarity: 0.9
});Custom Analysis and Reporting
import { getContributorStats } from 'git-contributor-stats/stats';
const stats = await getContributorStats({
repo: '.',
since: '1.year',
groupBy: 'name',
sortBy: 'commits'
});
// Custom analysis
const topContributor = stats.topContributors[0];
const busFactorFiles = stats.busFactor.filesSingleOwner.length;
const avgCommitsPerMonth = stats.totalCommits / 12;
console.log('Annual Report:');
console.log(`Top contributor: ${topContributor.name}`);
console.log(`- Commits: ${topContributor.commits}`);
console.log(`- Net lines: ${topContributor.net}`);
console.log(`\nRisk Analysis:`);
console.log(`- Single-owner files: ${busFactorFiles}`);
console.log(`- Avg commits/month: ${avgCommitsPerMonth.toFixed(1)}`);
// Access monthly breakdown
const monthlyActivity = stats.commitFrequency.monthly;
console.log('\nMonthly Activity:');
Object.entries(monthlyActivity)
.sort(([a], [b]) => a.localeCompare(b))
.forEach(([month, commits]) => {
console.log(`${month}: ${commits} commits`);
});TypeScript Support
Full TypeScript definitions are included:
import type {
ContributorStatsOptions,
ContributorStatsResult,
TopContributor,
TopStatsSummary,
BusFactorInfo
} from 'git-contributor-stats/stats';
import { getContributorStats } from 'git-contributor-stats/stats';
const options: ContributorStatsOptions = {
repo: '.',
since: '90.days',
countLines: false
};
const stats: ContributorStatsResult = await getContributorStats(options);
// Type-safe access
const topContributor: TopContributor = stats.topContributors[0];
const busFactor: BusFactorInfo = stats.busFactor;Exported Functions
// From 'git-contributor-stats/stats'
export async function getContributorStats(
options?: ContributorStatsOptions
): Promise<ContributorStatsResult>
// From 'git-contributor-stats/reports'
export async function generateReports(
stats: ContributorStatsResult,
options?: ReportOptions
): Promise<void>
// From 'git-contributor-stats/charts'
export async function generateCharts(
stats: ContributorStatsResult,
options?: ChartOptions,
outDir?: string
): Promise<void>
// From 'git-contributor-stats/output'
export function handleStdoutOutput(
stats: ContributorStatsResult,
options?: OutputOptions
): void
// From 'git-contributor-stats/workflow'
export async function generateWorkflow(repo: string): Promise<void>Identity Management
Consolidate multiple emails and names for the same person using alias mapping.
Auto-Detection
The tool automatically looks for .git-contributor-stats-aliases.json in the repository root.
Alias File Location
# Use default file (if exists)
git-contributor-stats
# Use custom file
git-contributor-stats --alias-file config/aliases.jsonAlias File Formats
Format 1: Simple Map
Map aliases to canonical identities:
{
"[email protected]": "[email protected]",
"Jane Doe": "[email protected]",
"[email protected]": "[email protected]",
"J. Smith": "[email protected]"
}Format 2: Extended Configuration
More control with groups and canonical details:
{
"map": {
"[email protected]": "[email protected]",
"[email protected]": "[email protected]"
},
"groups": [
["[email protected]", "[email protected]", "[email protected]"],
["[email protected]", "[email protected]"]
],
"canonical": {
"[email protected]": {
"name": "Jane Doe",
"email": "[email protected]"
},
"[email protected]": {
"name": "John Smith",
"email": "[email protected]"
}
}
}Format 3: Array of Groups
Shorthand for groups:
[
["[email protected]", "[email protected]", "Jane Doe"],
["[email protected]", "[email protected]", "John Smith"],
["[email protected]", "[email protected]", "[email protected]"]
]Regex Patterns
Use regex patterns for flexible matching:
{
"map": {
"/^jane\\.doe@.+$/i": "[email protected]",
"/^(John Smith|J\\.? Smith)$/": "[email protected]"
}
}Pattern format: Strings starting and ending with / are treated as regex patterns.
Similarity Threshold
Control automatic name merging:
# Default threshold (0.85)
git-contributor-stats
# Stricter matching (higher threshold)
git-contributor-stats --similarity 0.95
# More permissive (lower threshold)
git-contributor-stats --similarity 0.75Range: 0.0 (merge everything) to 1.0 (exact match only)
Recommended: 0.80 - 0.90
Configuration
Environment Variables
Currently, the tool uses command-line options and alias files. Environment variables are not used.
Default Behavior
| Setting | Default | Description |
|---------|---------|-------------|
| Repository | Current directory (.) | Can override with --repo |
| Output format | table | Can change with --format |
| Group by | email | Can change with --group-by |
| Sort by | changes | Can change with --sort-by |
| Similarity | 0.85 | Can change with --similarity |
| Count lines | true | Disable with --no-count-lines |
| Include merges | false | Enable with --include-merges |
| Top stats | true | Disable with --no-top-stats |
Examples
Complete Workflow Examples
1. Quarterly Report Generation
# Generate comprehensive quarterly report with all outputs
git-contributor-stats \
--since 90.days \
--out-dir reports/q4-2024 \
--md reports/q4-2024/report.md \
--html reports/q4-2024/dashboard.html \
--csv reports/q4-2024/contributors.csv \
--charts \
--chart-format both \
--no-count-lines2. Team-Specific Analysis
# Analyze backend team contributions in src/backend/
git-contributor-stats \
src/backend/ \
--since 1.year \
--alias-file config/team-aliases.json \
--out-dir reports/backend-team \
--md --html \
--charts \
--top-stats commits,net3. Release Analysis
# Compare two releases
git-contributor-stats \
--branch v1.0.0..v2.0.0 \
--json > v1-to-v2-stats.json
# Analyze specific release period
git-contributor-stats \
--since 2024-01-01 \
--until 2024-03-31 \
--out-dir reports/v2.0 \
--md --html --charts4. Performance-Optimized Analysis
# Fast analysis for large repos
git-contributor-stats \
--no-count-lines \
--since 6.months \
--top 20 \
--format table5. Custom Top Stats
# Only show commits and net contribution
git-contributor-stats \
--top-stats commits,net \
--out-dir reports \
--md reports/simple-report.md6. CI/CD Integration
# Generate GitHub Actions workflow
git-contributor-stats --generate-workflow
# Run in CI (example)
git-contributor-stats \
--since 7.days \
--out-dir artifacts \
--md artifacts/weekly-report.md \
--charts \
--no-count-linesProgrammatic Examples
Monitor Repository Health
import { getContributorStats } from 'git-contributor-stats/stats';
async function checkRepoHealth() {
const stats = await getContributorStats({
repo: '.',
since: '90.days'
});
const activeDevelopers = stats.topContributors.length;
const singleOwnerFiles = stats.busFactor.filesSingleOwner.length;
const totalFiles = Object.keys(
stats.topContributors.reduce((acc, c) => ({ ...acc, ...c.files }), {})
).length;
const busFactorRisk = singleOwnerFiles / totalFiles;
console.log('Repository Health Check:');
console.log(`Active developers (90d): ${activeDevelopers}`);
console.log(`Bus factor risk: ${(busFactorRisk * 100).toFixed(1)}%`);
if (busFactorRisk > 0.3) {
console.warn('⚠️ High bus factor risk - consider knowledge sharing');
}
if (activeDevelopers < 3) {
console.warn('⚠️ Low active developer count');
}
}
import { generateReports } from 'git-contributor-stats/reports';
import { generateCharts } from 'git-contributor-stats/charts';Generate Custom Dashboard
import { getContributorStats } from 'git-contributor-stats/stats';
import { generateReports } from 'git-contributor-stats/reports';
import { generateCharts } from 'git-contributor-stats/charts';
async function generateDashboard() {
const [weekly, monthly, quarterly] = await Promise.all([
getContributorStats({ since: '7.days' }),
getContributorStats({ since: '30.days' }),
getContributorStats({ since: '90.days' })
]);
await generateReports(weekly, {
outDir: 'dashboard/weekly',
md: 'dashboard/weekly/report.md',
html: 'dashboard/weekly/report.html'
});
await generateReports(monthly, {
outDir: 'dashboard/monthly',
md: 'dashboard/monthly/report.md',
html: 'dashboard/monthly/report.html'
});
await generateCharts(monthly, {
charts: true,
chartsDir: 'dashboard/monthly/charts'
});
await generateReports(quarterly, {
outDir: 'dashboard/quarterly',
md: 'dashboard/quarterly/report.md',
html: 'dashboard/quarterly/report.html'
});
await generateCharts(quarterly, {
charts: true,
chartsDir: 'dashboard/quarterly/charts',
chartFormat: 'both'
});
console.log('✓ Multi-period dashboard generated');
}
generateDashboard();Output Reference
Table Output
Top stats:
- Most commits: John Smith <[email protected]> (234)
- Most additions: Jane Doe <[email protected]> (15,432)
- Most deletions: Alice Dev <[email protected]> (8,901)
- Best net contribution: Jane Doe <[email protected]> (12,345)
- Most changes: Jane Doe <[email protected]> (24,333)
┌─────┬────────────────┬─────────┬──────────┬──────────┬─────────┐
│Rank │ Contributor │ Commits │ Additions│ Deletions│ Changes │
├─────┼────────────────┼─────────┼──────────┼──────────┼─────────┤
│ 1 │ Jane Doe │ 156 │ 15,432 │ 3,087 │ 18,519 │
│ 2 │ John Smith │ 234 │ 8,901 │ 4,523 │ 13,424 │
│ 3 │ Alice Dev │ 145 │ 6,234 │ 8,901 │ 15,135 │
└─────┴────────────────┴─────────┴──────────┴──────────┴─────────┘JSON Output
Comprehensive analysis object with all metrics (see API Reference).
CSV Output
Rank,Name,Email,Commits,Additions,Deletions,Net,Changes
1,Jane Doe,[email protected],156,15432,3087,12345,18519
2,John Smith,[email protected],234,8901,4523,4378,13424
3,Alice Dev,[email protected],145,6234,8901,-2667,15135Markdown Report
- Summary statistics
- Top stats (configurable)
- Top contributors table with file details
- Bus factor analysis
- Activity patterns (monthly breakdown, heatmap data)
HTML Dashboard
Interactive HTML report with:
- Styled summary cards
- Sortable contributor table
- Bus factor risk indicators
- Embedded charts (if generated)
- Monthly/weekly activity visualization
Performance Tips
Large Repositories
# Skip LOC counting (significant speedup)
git-contributor-stats --no-count-lines
# Limit time range
git-contributor-stats --since 6.months
# Limit to specific paths
git-contributor-stats src/ --no-count-linesReduce Analysis Scope
# Analyze only recent commits
git-contributor-stats --since 30.days --top 10
# Specific branch only
git-contributor-stats -b main --since 90.days
# Exclude merge commits (default, but explicit)
git-contributor-stats --no-include-mergesOptimize for CI/CD
# Fast CI run
git-contributor-stats \
--since 7.days \
--no-count-lines \
--format json > stats.jsonBenchmarks
Typical performance on a medium-sized repository (10k commits):
| Operation | With --count-lines | With --no-count-lines |
|-----------|---------------------|------------------------|
| Full analysis | ~15-20s | ~3-5s |
| Last 90 days | ~8-12s | ~2-3s |
| Last 30 days | ~5-8s | ~1-2s |
Performance varies based on repository size, file count, and system resources.
Development
Setup
git clone https://github.com/vikkrantxx7/git-contributor-stats.git
cd git-contributor-stats
npm installScripts
# Build the project
npm run build
# Run tests
npm test
# Run linter
npm run biome
# Fix linting issues
npm run biome:fix
# Generate types
npm run build:types
# Development mode (uses source files)
node dist/cli.mjs --help
# Generate sample reports
npm run reportProject Structure
git-contributor-stats/
├── src/
│ ├── features/
│ │ ├── stats.ts # Core statistics (tree-shakeable)
│ │ ├── charts.ts # Chart generation (tree-shakeable)
│ │ ├── reports.ts # Report generation (tree-shakeable)
│ │ ├── output.ts # Console output (tree-shakeable)
│ │ └── workflow.ts # GitHub Actions workflow (tree-shakeable)
│ ├── cli/
│ │ ├── entry.ts # CLI entry point
│ │ ├── index.ts # CLI logic
│ │ └── options.ts # Command-line options
│ ├── analytics/
│ │ ├── aggregator.ts # Data aggregation
│ │ ├── aliases.ts # Identity resolution
│ │ └── analyzer.ts # Core analysis logic
│ ├── charts/
│ │ ├── renderer.ts # Chart rendering (PNG)
│ │ └── svg.ts # SVG generation
│ ├── git/
│ │ ├── parser.ts # Git log parsing
│ │ └── utils.ts # Git operations
│ ├── reports/
│ │ ├── csv.ts # CSV generation
│ │ ├── html.ts # HTML generation
│ │ └── markdown.ts # Markdown generation
│ ├── utils/
│ │ ├── dates.ts # Date parsing
│ │ ├── files.ts # File operations
│ │ └── formatting.ts # Output formatting
│ └── api.ts # TypeScript types
├── dist/ # Built files
│ ├── features/ # Feature modules (separate entry points)
│ └── chunks/ # Shared code chunks
├── tests/ # Test files
├── package.json
├── tsconfig.json
├── vite.config.ts
└── vitest.config.tsgit-contributor-stats/charts- Chart generation with Chart.js (~260KB with charts)git-contributor-stats/reports- Report generation: CSV, Markdown, HTML (~200KB)git-contributor-stats/output- Console output formatting (table, JSON, CSV)git-contributor-stats/workflow- GitHub Actions workflow generator (~5KB)git-contributor-stats/cli- CLI entry point (combines all features)
Bundle Size Comparison:
| Import | Bundle Size | Reduction | |---------|---------|-------------| | Core stats only | ~80KB | 84% smaller | | Stats + Reports | ~200KB | 60% smaller | | Stats + Charts | ~260KB | 48% smaller | | Full features (CLI) | ~400KB | 20% smaller |
Compared to the previous monolithic bundle of ~500KB
See Technical Documentation for architecture details, tree-shaking verification, and migration guide
Testing
# Run all tests
npm test
# Run specific test
npm test -- tests/e2e/api.test.ts
# Watch mode
npm test -- --watch
# Coverage
npm test -- --coverageDocumentation
📚 Complete documentation is available in the docs/ directory:
- Quick Start Guide - Get started in 30 seconds with common use cases
- Quick Reference - Command cheat sheet for quick lookup
- Contributing Guide - How to contribute to this project
- Commit Guidelines - Conventional commits format
- Release Workflow - Version management with changesets
- Technical Documentation - Architecture and internals
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Quick steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and linter (
npm test && npm run lint) - Commit following conventional commits (
git commit -m 'feat: add amazing feature') - Add a changeset (
npx changeset) - Push and open a Pull Request
📝 This project uses Conventional Commits and Changesets for version management.
GitHub Actions Integration
Generate a workflow file:
git-contributor-stats --generate-workflowThis creates .github/workflows/git-contributor-stats.yml:
name: Git Contributor Stats
on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch:
jobs:
stats:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install git-contributor-stats
run: npm install -g git-contributor-stats
- name: Generate reports
run: |
git-contributor-stats \
--since 90.days \
--out-dir reports \
--md reports/report.md \
--html reports/report.html \
--charts \
--no-count-lines
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: contributor-stats
path: reports/Security
🔐 This project publishes packages with NPM provenance enabled, providing cryptographic proof of build authenticity.
For security issues, please see SECURITY.md for our security policy and how to report vulnerabilities responsibly.
License
MIT License - see LICENSE file for details.
Links
Made with ❤️ for better repository insights
