Created
January 27, 2025 16:02
-
-
Save kartben/a18380a4b807f411a0aac9c1ab3060e6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import subprocess | |
import csv | |
from collections import defaultdict | |
from datetime import datetime | |
def get_contributor_commits(): | |
try: | |
# Get all commits with commit date and author, sorted by oldest first | |
git_log = subprocess.check_output( | |
['git', 'log', '--format=%cI###%aN', '--reverse', '--use-mailmap', '--mailmap'], | |
universal_newlines=True | |
) | |
except subprocess.CalledProcessError: | |
print("Error: Failed to get git log. Are you in a git repository?") | |
return None | |
# Dictionary to store monthly stats and author counts | |
monthly_stats = defaultdict(lambda: defaultdict(int)) | |
all_time_author_commits = defaultdict(int) # Track total commits per author | |
current_month = None | |
# Process each commit chronologically | |
for line in git_log.strip().split('\n'): | |
date_str, email = line.split('###') | |
date = datetime.fromisoformat(date_str) | |
month_key = f"{date.year}-{date.month:02d}" | |
# When we move to a new month, calculate stats for all authors | |
if month_key != current_month: | |
if current_month is not None: | |
# Calculate stats based on cumulative commits for all authors | |
monthly_stats[current_month] = defaultdict(int) | |
for author, commit_count in all_time_author_commits.items(): | |
if commit_count == 1: | |
monthly_stats[current_month]['1'] += 1 | |
elif 2 <= commit_count < 5: | |
monthly_stats[current_month]['2-5'] += 1 | |
elif 5 <= commit_count < 20: | |
monthly_stats[current_month]['5+'] += 1 | |
elif 20 <= commit_count < 100: | |
monthly_stats[current_month]['20+'] += 1 | |
elif commit_count >= 100: | |
monthly_stats[current_month]['100+'] += 1 | |
print(f"Completed month {current_month}: " | |
f"1 commit: {monthly_stats[current_month]['1']}, " | |
f"2-5 commits: {monthly_stats[current_month]['2-5']}, " | |
f"5+ commits: {monthly_stats[current_month]['5+']}, " | |
f"20+ commits: {monthly_stats[current_month]['20+']}, " | |
f"100+ commits: {monthly_stats[current_month]['100+']}") | |
current_month = month_key | |
# Simply update the author's total commit count | |
all_time_author_commits[email] += 1 | |
# Calculate stats for the final month | |
if current_month: | |
monthly_stats[current_month] = defaultdict(int) | |
for author, commit_count in all_time_author_commits.items(): | |
if commit_count == 1: | |
monthly_stats[current_month]['1'] += 1 | |
elif 2 <= commit_count < 5: | |
monthly_stats[current_month]['2-5'] += 1 | |
elif 5 <= commit_count < 20: | |
monthly_stats[current_month]['5+'] += 1 | |
elif 20 <= commit_count < 100: | |
monthly_stats[current_month]['20+'] += 1 | |
elif commit_count >= 100: | |
monthly_stats[current_month]['100+'] += 1 | |
print(f"Completed month {current_month}: " | |
f"1 commit: {monthly_stats[current_month]['1']}, " | |
f"2-5 commits: {monthly_stats[current_month]['2-5']}, " | |
f"5+ commits: {monthly_stats[current_month]['5+']}, " | |
f"20+ commits: {monthly_stats[current_month]['20+']}, " | |
f"100+ commits: {monthly_stats[current_month]['100+']}") | |
return monthly_stats | |
def write_csv(stats): | |
# Sort months chronologically | |
months = sorted(stats.keys()) | |
with open('contributor_stats.csv', 'w', newline='') as f: | |
writer = csv.writer(f) | |
# Write header | |
writer.writerow(['Month', '1 commit', '2-5 commits', '5+ commits', '20+ commits', '100+ commits']) | |
# Write data for each month | |
for month in months: | |
# Convert YYYY-MM to YYYY-MM-01 for Excel compatibility | |
year, month_num = month.split('-') | |
excel_date = f"{year}-{month_num}-01" | |
writer.writerow([ | |
excel_date, | |
stats[month]['1'], | |
stats[month]['2-5'], | |
stats[month]['5+'], | |
stats[month]['20+'], | |
stats[month]['100+'] | |
]) | |
def main(): | |
print("Analyzing git repository...") | |
stats = get_contributor_commits() | |
write_csv(stats) | |
print("Statistics have been written to contributor_stats.csv") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment