A powerful macOS shell script that exports all your Git commits from the current work week (Monday β Friday) from multiple repositories into a neat text file.
Perfect for writing weekly reports, standups, or just keeping track of what you've done across all your projects. β¨
- β Multiple repositories support with flexible configuration
- β Configurable branches per repository
- β Optional base path for relative repository paths
- β Multiple email addresses support for filtering commits
- β Configurable commit detail level (title only or full)
- β Filters commits by your Git email (configurable or auto-detected)
- ποΈ Includes commits only from Monday to Friday of the current week
- π Adds the date and time before each commit
- π§Ή Flattens multi-line commit messages into a single clean line
- π Organizes output by repository and branch
- π Separate file per repository in organized folder structure
- πΎ Saves reports to
reports/<date>/with individual.txtfiles
Example output structure:
reports/
βββ 2025-11-08/
βββ frontend-app.txt
βββ backend-api.txt
βββ mobile-app.txt
Example file content (frontend-app.txt):
# Weekly Commits Report
Repository: frontend-app
Period: 2025-11-03 to 2025-11-07
Author: you@example.com
Generated: Fri Nov 8 10:21:38 CET 2025
## Branch: main (3 commits)
04-11-2025 10:42 | feat: implement handling of decreased rates
05-11-2025 09:13 | refactor: remove unused prop
06-11-2025 14:28 | test: add new test data for rate decrease
## Branch: develop (2 commits)
07-11-2025 11:02 | fix: pick location state correctly
08-11-2025 09:30 | feat: add new API endpoint for user preferences
---
Total commits: 5-
Make script executable:
chmod +x extract-weekly-commits.sh
-
Setup configuration:
# Edit repos.conf with your repositories # The file contains detailed comments and examples
-
Run the script:
./extract-weekly-commits.sh
-
Find your reports in
reports/<date>/
Create a repos.conf file with your repositories:
# Optional: Set base path for relative repository paths
BASE_PATH=/Users/username/projects
# User email(s) to filter commits (optional, fallback to git config)
# Use comma-separated list for multiple emails
USER_EMAIL=you@example.com
# USER_EMAIL=work@company.com,personal@gmail.com
# Commit detail level: "title" (subject only) or "full" (subject + body)
COMMIT_DETAIL=title
# Format: repo_path:branch1,branch2,branch3
# Lines starting with # are ignored
# Example with relative paths (when BASE_PATH is set above):
frontend-app:main,develop
backend-api:main,staging,feature/new-api
mobile-app:main
# Example with absolute paths:
/Users/username/projects/legacy-project:main
/Users/username/work/client-site:main,develop./extract-weekly-commits.shYour commit reports will be saved to:
reports/<YYYY-MM-DD>/
βββ repo1.txt
βββ repo2.txt
βββ repo3.txt
Each repository gets its own detailed report file with:
- π Repository metadata and generation info
- πΏ Commits organized by branch
- π Total commit count summary
# repos.conf
BASE_PATH=/Users/username/projects
frontend:main,develop
backend:main
mobile-app:main,feature/redesign# repos.conf
/Users/username/work/project1:main
/Users/username/personal/hobby-project:main,experimental
../other-project:main# repos.conf
BASE_PATH=/Users/username/projects
main-project:main,develop,staging,feature/new-ui
api-service:main,v2-development
docs:main- macOS (uses
date -vsyntax) - Git repositories with configured
user.email:git config user.email "you@example.com" - Configuration file
repos.confwith your repository definitions
Set a common base directory for relative repository paths:
BASE_PATH=/Users/username/projectsConfigure which email addresses to use for filtering commits. If not specified, falls back to your git configuration:
Single email:
USER_EMAIL=you@example.comMultiple emails (comma-separated):
USER_EMAIL=work@company.com,personal@gmail.comThe script will search for commits from all specified email addresses and merge the results. This is useful when you use different email addresses for work and personal projects.
GitHub Hidden Email Addresses
GitHub uses the format: <number>+<username>@users.noreply.github.com
How to find your GitHub hidden email:
- Go to GitHub Settings β Emails
- Look for the email address in the format:
123456789+yourusername@users.noreply.github.com - Use this email address in your configuration:
# Example with GitHub hidden email
USER_EMAIL=123456789+yourusername@users.noreply.github.com
# Or combine with your real email
USER_EMAIL=you@example.com,123456789+yourusername@users.noreply.github.comTo check which email Git is currently using:
git config user.emailIf this shows a GitHub noreply address, make sure to use that same address in your USER_EMAIL configuration to properly filter your commits.
Control how much information is extracted from each commit:
-
COMMIT_DETAIL=title: Only commit subject/title (clean, concise)04-11-2025 10:42 | feat: implement new feature 05-11-2025 09:13 | fix: resolve bug in authentication -
COMMIT_DETAIL=full: Subject + body (complete information)04-11-2025 10:42 | feat: implement new feature Add user authentication system with JWT tokens and role-based access control 05-11-2025 09:13 | fix: resolve bug in authentication Fixed issue where expired tokens were not properly handled
Want to include weekends too? The script currently calculates Monday-Friday of the current week using complex conditional logic. To include weekends, you need to modify the date calculation logic around lines 50-66 in the script:
Current logic (Monday-Friday):
DAYS_TO_FRIDAY=$((5 - DAY_OF_WEEK))Change to (Monday-Sunday):
DAYS_TO_FRIDAY=$((7 - DAY_OF_WEEK))You'll also need to update the weekend handling logic in the else block that currently handles Saturday/Sunday by finding Friday of the current week.
If no branches are specified in repos.conf, the script defaults to main.
If you see: β οΈ No repositories found to process in repos.conf
- Create the configuration file:
# Create repos.conf with your repositories echo "# Add your repositories here" > repos.conf echo "# Format: repo_path:branch1,branch2" >> repos.conf
- Edit
repos.confand add your repository entries - Ensure proper format:
repo_path:branch1,branch2
If you see: β οΈ Git user.email not set
Set your Git email globally:
git config --global user.email "your.email@example.com"Check that:
- Repository paths are correct (absolute or relative to BASE_PATH)
- You have read access to the repositories
- Repositories are valid Git repositories
- Ensure branch names are correct (case sensitive)
- Verify branches exist:
git branch -a - Check if you're on the right remote
weekly-commits-export/
βββ extract-weekly-commits.sh # Main script
βββ repos.conf # Your configuration file
βββ reports/
βββ YYYY-MM-DD/
βββ repository1.txt # Individual repository reports
βββ repository2.txt
βββ repository3.txt
- Missing repositories are reported but don't stop the script
- Non-existent branches are skipped with a warning
- Invalid git repositories are skipped
- Empty repositories (no commits) don't create output files
The project includes a comprehensive test suite using bats (Bash Automated Testing System).
# Run all tests (automatically installs bats if needed)
./tests/run_tests.sh
# Run specific test suites
bats tests/test_extract_commits.bats # Core functionality tests
bats tests/test_integration.bats # Integration scenarios
bats tests/test_performance.bats # Performance tests (manual enable)
# Run with verbose output
bats -t tests/The test suite covers:
- β Configuration file parsing
- β Git repository validation
- β Branch existence checks
- β Commit extraction and counting
- β Multi-repository processing
- β Error handling scenarios
- β Report file generation
- β Integration workflows
- β Edge cases (empty repos, complex branching)
Tests are located in tests/ directory:
test_extract_commits.bats- Core functionalitytest_integration.bats- End-to-end scenariostest_performance.bats- Performance benchmarkshelpers/test_helpers.bash- Shared test utilities
Example test:
@test "description of what you're testing" {
# Setup test data
setup_test_repo "my_repo"
# Run the script
run bash extract-weekly-commits.sh
# Assert results
[ "$status" -eq 0 ]
[[ "$output" =~ "expected string" ]]
}πͺΆ Powerful. Flexible. Perfect for weekly reports.