diff --git a/Github_repo_auditor/README.md b/Github_repo_auditor/README.md new file mode 100644 index 00000000..f4d01090 --- /dev/null +++ b/Github_repo_auditor/README.md @@ -0,0 +1,31 @@ +# Git Repo Auditor + +A Python script to **analyze and report the status** of all Git repositories within a given directory. + +## 🔍 What It Does + +This script recursively scans a directory for Git repositories and reports: + +- **Uncommitted Changes**: Repos with local changes not yet staged or committed. +- **Ahead of Remote**: Repos that have local commits not yet pushed. +- **Behind Remote**: Repos that are missing commits from the remote. +- **Inactive Repos**: Repos with no commits in the last **30 days**. + +## Features + +- Scans nested folders for `.git` directories. +- Uses `git status` and `git log` to assess health and activity. +- Helps developers **organize, clean, and maintain** their local projects. +- No dependencies except Python 3 and Git. + +## Usage + +```bash +python3 git_repo_auditor.py /path/to/your/projects +``` + +## Screenshots + +![Git Repo Status](git_repo_auditor.png) + + diff --git a/Github_repo_auditor/git_repo_auditor.png b/Github_repo_auditor/git_repo_auditor.png new file mode 100644 index 00000000..7859b975 Binary files /dev/null and b/Github_repo_auditor/git_repo_auditor.png differ diff --git a/Github_repo_auditor/github_repo_auditor.py b/Github_repo_auditor/github_repo_auditor.py new file mode 100644 index 00000000..6577472c --- /dev/null +++ b/Github_repo_auditor/github_repo_auditor.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 + +import os +import subprocess +from pathlib import Path +from datetime import datetime, timedelta + +def is_git_repo(path): + return (path / '.git').exists() + +def run_git_command(repo_path, args): + try: + result = subprocess.run( + ['git'] + args, + cwd=repo_path, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True + ) + return result.stdout.strip() + except Exception as e: + return "" + +def check_repo_status(repo_path): + status = { + 'path': str(repo_path), + 'uncommitted_changes': False, + 'ahead': False, + 'behind': False, + 'inactive': False, + 'last_commit': None, + } + + # Uncommitted changes + changes = run_git_command(repo_path, ['status', '--porcelain']) + if changes: + status['uncommitted_changes'] = True + + # Ahead/Behind + run_git_command(repo_path, ['remote', 'update']) # Update remote tracking + branch_info = run_git_command(repo_path, ['status', '-sb']) + if 'ahead' in branch_info: + status['ahead'] = True + if 'behind' in branch_info: + status['behind'] = True + + # Last commit date + last_commit_date = run_git_command(repo_path, ['log', '-1', '--format=%ci']) + if last_commit_date: + commit_time = datetime.strptime(last_commit_date, '%Y-%m-%d %H:%M:%S %z') + status['last_commit'] = commit_time + if datetime.now(commit_time.tzinfo) - commit_time > timedelta(days=30): + status['inactive'] = True + + return status + +def scan_repos(base_dir): + base = Path(base_dir).expanduser() + for root, dirs, files in os.walk(base): + root_path = Path(root) + if is_git_repo(root_path): + yield check_repo_status(root_path) + dirs[:] = [] # Do not recurse into nested repos + +def print_report(repos): + for repo in repos: + path = repo['path'] + if repo['uncommitted_changes']: + print(f"[!] Uncommitted changes: {path}") + if repo['ahead']: + print(f"[↑] Ahead of origin/main: {path}") + if repo['behind']: + print(f"[↓] Behind origin/main: {path}") + if repo['inactive']: + last = repo['last_commit'].strftime('%Y-%m-%d') + print(f"[-] Inactive >30 days: {path} (Last: {last})") + +if __name__ == '__main__': + import sys + if len(sys.argv) < 2: + print("Usage: python git-repo-cleaner.py ") + sys.exit(1) + + base_dir = sys.argv[1] + print(f"📁 Scanning Git repos in: {base_dir}\n") + results = list(scan_repos(base_dir)) + print_report(results) diff --git a/README.md b/README.md index 1e95db7f..40eec2ef 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,7 @@ So far, the following projects have been integrated to this repo: |[Zip password cracker](zip_password_cracker)|[umar abdullahi](https://github.com/umarbrowser)| |[Task Scheduler](Task-Scheduler)|[heysagnik](https://github.com/heysagnik)| |[PDF Password Decypter](PDF_Password_Decrypter)|[parthasdey2304](https://github.com/parthasdey2304)| +|[Github repo auditor](Github_repo_auditor)|[av4nth1ka](https://github.com/av4nth1ka)| ## How to use: - Clone/Download the directory and navigate to each folder. Or...