Script to check your git status across all repos

I recently realized “whoa, I have a lot of repos here” and wasn’t confident everything has been pushed up. I have a plethora of side projects, along with loads of client repos, way too many to manually go through and check.

I went ahead and created a Python script, well, ChatGPT created it for me. It iterates through and outputs a nice list view of all my repos grouped by their commit and push status!

Now I get to go through the 27 repos, committing and pushing. This is a good reminder for me to commit and push!

If you’re a serial side project developer, I hope this little script helps!

Here’s the script!

import os
import subprocess


def get_git_status(repo_path):
    try:
        # Get current branch
        branch = subprocess.check_output(
            ['git', '-C', repo_path, 'rev-parse', '--abbrev-ref', 'HEAD'],
            stderr=subprocess.STDOUT
        ).strip().decode('utf-8')

        # Get git status
        status = subprocess.check_output(
            ['git', '-C', repo_path, 'status', '--short'],
            stderr=subprocess.STDOUT
        ).strip().decode('utf-8')

        # Check if there are changes not committed
        if status:
            commit_status = "Changes not committed"
        else:
            commit_status = "All changes committed"

        # Check if there are changes not pushed
        status_push = subprocess.check_output(
            ['git', '-C', repo_path, 'status', '-sb'],
            stderr=subprocess.STDOUT
        ).strip().decode('utf-8')

        if 'ahead' in status_push:
            push_status = "Changes not pushed"
        else:
            push_status = "All changes pushed"

        return branch, commit_status, push_status
    except subprocess.CalledProcessError:
        return None, None, None


def iterate_git_repos(base_path):
    result = []
    for root, dirs, _ in os.walk(base_path):
        for dir_name in dirs:
            repo_path = os.path.join(root, dir_name)
            if os.path.isdir(os.path.join(repo_path, '.git')):
                branch, commit_status, push_status = get_git_status(repo_path)
                if branch:
                    result.append({
                        'Folder': repo_path,
                        'Branch': branch,
                        'Commit Status': commit_status,
                        'Push Status': push_status
                    })
        # Prevent os.walk from traversing subdirectories of directories that have .git
        dirs[:] = [d for d in dirs if not os.path.isdir(os.path.join(root, d, '.git'))]
    return result


def main():
    base_path = '/Users/david.lozzi/git'  # Replace with your base directory
    repos_status = iterate_git_repos(base_path)

    # Step 1: Create a dictionary for grouping
    status_groups = {}

    # Step 2: Populate the dictionary with groups
    for repo in repos_status:
        key = (repo['Commit Status'], repo['Push Status'])
        if key not in status_groups:
            status_groups[key] = []
        status_groups[key].append({'Folder': repo['Folder'], 'Branch': repo['Branch']})

    # Step 3: Display each group
    for status, repos in status_groups.items():
        commit_status, push_status = status
        print(f"{len(repos)} Commit: {commit_status} | Push: {push_status}")
        for repo in repos:
            print(f"  Folder: {repo['Folder']} | Branch: {repo['Branch']}")
        print('---')

if __name__ == "__main__":
    main()

One thought on “Script to check your git status across all repos

Add yours

Leave a Reply

Blog at WordPress.com.

Up ↑