A CLI for generating public contribution history from private Git repositories.
Project description
Git Logger
The Git Logger CLI is a tool for creating a public contribution history from private Git repositories. It allows you to export commit metadata from private repositories and generate empty commits in another repository, preserving the original authored dates and enabling you to create a transparent contribution history.
Table of Contents
- Git Logger CLI
- Table of Contents
- Features
- Installation
- Commands
- Hiding Private Information
- Replace vs Append
- JSON Commit File
- Troubleshooting
Features
- Export commits from one repository, many repositories, or glob-matched repository folders.
- Filter exported commits by author name, author email, commit message, date range, and
HEADversus all refs. - Write a portable JSON commits file that records the original sources and export filters.
- Generate empty commits that preserve authored dates for contribution history.
- Customize generated commit messages with a format string.
- Hide author names and/or emails from generated Git metadata.
- Append only new generated commits by default.
- Replace the generated branch when you want the branch to exactly match the current commits file.
- Create a backup branch before modifying an existing target branch.
- Optionally push the generated branch after generation.
Installation
- Make sure
pipis installed on your system. - Run the following command:
pip install gitlogger-cli
[!TIP] See here for more details on installing packages.
Commands
Git Logger has two main commands: export and generate.
gitlogger
Usage
gitlogger [-h] {export|generate} ...
gitlogger export
Exports commit metadata from one or more Git repositories into a JSON commits file.
Usage
gitlogger export -s <source> [options]
Arguments
| Argument | Required | Default | Description |
|---|---|---|---|
-s, --source <path-or-glob> |
Yes | None | Source Git repository path or glob pattern. Can be repeated. |
-o, --output <file> |
No | commits.json |
JSON commits file to write. |
-n, --name <name> |
No | Repository folder name | Override the exported source name. Only valid when --source resolves to one repository. |
-a, --author <regex> |
No | None | Case-insensitive regex filter for author name. |
-e, --email <regex> |
No | None | Case-insensitive regex filter for author email. |
-m, --message <regex> |
No | None | Case-insensitive regex filter for the full commit message. |
-S, --since <date> |
No | None | Only include commits after this Git date expression. |
-U, --until <date> |
No | None | Only include commits before this Git date expression. |
--all-refs |
No | false |
Export commits reachable from all refs instead of only HEAD. |
Examples
Export a single repository:
gitlogger export -s "C:\src\private-repo" -o ".\gitlogger-commits.json"
Export every Git repository in a folder:
gitlogger export -s "C:\src\private\*" -o ".\gitlogger-commits.json"
Export multiple specific sources:
gitlogger export -s "C:\src\private-app" -s "C:\src\private-library" -o ".\gitlogger-commits.json"
Export only commits from your email:
gitlogger export -s "C:\src\private\*" -e "you@example.com"
Export only commits from a specific date range:
gitlogger export -s "C:\src\private\*" -S "2025-01-01" -U "2025-12-31"
Export commits whose messages match certain work types:
gitlogger export -s "C:\src\private\*" -m "feature|fix|refactor|test"
Export commits from all branches and refs:
gitlogger export -s "C:\src\private\*" --all-refs
Override the source name for one repository:
gitlogger export -s "C:\src\private-client-project" --name "Client Project"
gitlogger generate
Generates empty commits in a target repository from a JSON commits file.
[!NOTE] Before modifying an existing branch, gitlogger creates a backup branch providing a recovery point if the generated commits are incorrect or if the branch is replaced unintentionally.
Usage
gitlogger generate [options]
Arguments
| Argument | Required | Default | Description |
|---|---|---|---|
-r, --repo <path> |
No | . |
Target Git repository to update. |
-i, --input <file> |
No | commits.json |
JSON commits file to read. |
-b, --branch <branch> |
No | Current branch | Target branch to update. |
--remote <name> |
No | origin |
Remote used when --push is set. |
-c, --committer-email <email> |
No | Source author email | Override the committer email. This can help GitHub attribute commits to the correct account. |
-p, --push |
No | false |
Push to the remote repository immediately after generating commits. |
--replace |
No | false |
Replace the target branch instead of appending new generated commits. |
-x, --exclude <author-email> |
No | None | Generated Git metadata to omit. Available values are author and email. Can accept multiple values and can be repeated. |
-f, --format <format> |
No | {source} | {subject}\n\n{message} |
Format string for generated commit messages. |
Examples
Generate into the current repository and current branch:
gitlogger generate -i ".\gitlogger-commits.json"
Generate into a specific repository and branch:
gitlogger generate -r "C:\src\public-history" -i ".\gitlogger-commits.json" -b "main"
Append new commits only:
gitlogger generate -r "C:\src\public-history" -i ".\gitlogger-commits.json" -b "main"
Replace the branch from the input file:
gitlogger generate -r "C:\src\public-history" -i ".\gitlogger-commits.json" -b "main" --replace
Push after generating:
gitlogger generate -r "C:\src\public-history" -i ".\gitlogger-commits.json" -b "main" --push
Use a specific committer email:
gitlogger generate -i ".\gitlogger-commits.json" -c "you@example.com"
Commit Message Format
The default generated commit message format is:
{source} | {subject}
{message}
Available fields:
| Field | Description |
|---|---|
{source} |
Exported source name. Usually the repository folder name, unless overridden with --name. |
{sourcePath} |
Full path to the source repository. Usually private; avoid in public output. |
{hash} |
Full original source commit hash. |
{hash12} |
First 12 characters of the original source commit hash. |
{authoredAt} |
Original authored timestamp. |
{subject} |
Original commit subject line. |
{message} |
Original commit body, excluding the subject line. Empty when no body exists. |
{author} |
Original author name, unless excluded with --exclude author. |
{email} |
Original author email, unless excluded with --exclude email. |
Format Examples
Show source and subject:
gitlogger generate -i ".\gitlogger-commits.json" --format "{source} | {subject}"
Show only the original subject:
gitlogger generate -i ".\gitlogger-commits.json" --format "{subject}"
Show a short source hash for traceability:
gitlogger generate -i ".\gitlogger-commits.json" --format "{subject} [{hash12}]"
Show author and subject:
gitlogger generate -i ".\gitlogger-commits.json" --format "{author}: {subject}"
Avoid exposing local source paths:
gitlogger generate -i ".\gitlogger-commits.json" --format "{sourcePath} | {subject}"
This is usually not recommended for public branches because it can reveal local folder names, usernames, company names, client names, or internal project paths.
Multi-line Formats
--format is interpreted after your shell parses it. gitlogger does not convert the characters \n into a newline by itself.
PowerShell:
gitlogger generate -i ".\gitlogger-commits.json" --format "{source} | {subject}`n`n{message}"
Bash:
gitlogger generate -i "./gitlogger-commits.json" --format $'{source} | {subject}\n\n{message}'
Hiding Private Information
There are two main tools for privacy during generation:
--excludecontrols generated Git metadata.--formatcontrols generated commit message text.
Use both when you want clean public commits.
Hide author metadata by replacing it with a generic fallback.
gitlogger generate -i ".\gitlogger-commits.json" --exclude author
Hide email metadata by replacing it with a generic fallback.
gitlogger generate -i ".\gitlogger-commits.json" --exclude email
Avoid Leaking Data Through --format
{author}, email, {source}, {sourcePath}, {hash}, and {message} may reveal information depending on your source history.
For the safest public output, avoid these fields unless you have reviewed them:
{sourcePath}
{email}
{author}
{message}
{hash}
A safer public format is:
gitlogger generate --exclude author email --format "{subject}"
--replace vs Append
By default, gitlogger appends only missing commits. This means it keeps existing generated commits and skips any exported commits already present on the branch.
Use the default append behavior when:
- You already generated a branch before.
- You exported more recent commits and only want to add the new ones.
- You do not want to rewrite public history.
- You are running gitlogger as part of a regular update process.
Example:
gitlogger export -s "C:\src\private\*" -o ".\gitlogger-commits.json" -e "you@example.com"
gitlogger generate -r "C:\src\public-history" -i ".\gitlogger-commits.json" -b "main"
Use --replace when:
- You changed the
--formatand want every generated commit message rebuilt. - You changed
--excludeand want old exposed metadata removed. - You changed export filters and want deleted commits removed from the generated branch.
- You want the target branch to exactly match the current commits file.
- You are intentionally rebuilding a generated branch before publishing it.
Example:
gitlogger generate -r "C:\src\public-history" -i ".\gitlogger-commits.json" -b "main" -x author email -f "{subject}" --replace
If the branch already exists, gitlogger creates a backup branch before replacing it.
JSON Commit File
The commits file contains the exported data used by generate.
Example:
{
"$schema": "gitlogger.schema.json",
"generated_at": "2026-05-20T00:00:00+00:00",
"filters": {
"source": ["C:\\src\\private\\*"],
"name": null,
"author": null,
"email": "you@example.com",
"message": null,
"since": "2025-01-01",
"until": null,
"all_refs": false
},
"commits": [
{
"id": "stable-dedupe-id",
"source": "private-repo",
"sourcePath": "C:\\src\\private\\private-repo",
"hash": "0123456789abcdef0123456789abcdef01234567",
"authored_at": "2026-05-20T12:34:56+00:00",
"author_name": "Your Name",
"author_email": "you@example.com",
"subject": "Original private commit subject",
"message": "Optional commit body after the first line."
}
],
"sources": [
{
"name": "private-repo",
"path": "C:\\src\\private\\private-repo"
}
]
}
[!IMPORTANT] The JSON file is not automatically sanitized. It records the exported source metadata so generation can be customized later. Do not commit the JSON file to a public repository unless you have reviewed it and are comfortable exposing its contents.
Troubleshooting
No Git repositories matched --source.
The path or glob did not resolve to any Git repositories. Check that the folders exist and contain .git directories.
--name can only be used when --source resolves to one repository.
--name gives one source name to one repository. If your source glob resolves to multiple repositories, remove --name or export that repository separately.
Could not determine current branch. Pass --branch explicitly.
The target repository is probably in detached HEAD state or has no current branch. Pass --branch explicitly:
gitlogger generate -b "main"
Unknown message format field
The format string contains a field gitlogger does not recognize. Use only these fields:
{source}, {sourcePath}, {subject}, {message}, {hash}, {hash12}, {author}, {email}, {authoredAt}
Generated commits still reveal private information
Check both Git metadata and commit message formatting.
Use:
gitlogger generate --replace --exclude author email --format "{subject}"
Then review:
git log --format=fuller
--push pushed to the wrong place
--push uses --remote, which defaults to origin, and pushes the target branch ref. Use --remote and --branch explicitly when publishing:
gitlogger generate -r "C:\src\public-history" -b "main" --remote "origin" --push
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gitlogger_cli-0.0.1.tar.gz.
File metadata
- Download URL: gitlogger_cli-0.0.1.tar.gz
- Upload date:
- Size: 16.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4d71c13e71a372c80c792770cb0674d744ffda2da1728ca839936dd7fb2df36
|
|
| MD5 |
b1fedf0663a6a762a0ce2edce6d7b6ca
|
|
| BLAKE2b-256 |
f5e89037e156af3f77a2f93d6e544e025e37b640956651c9d5a19f2fb18e54d5
|
Provenance
The following attestation bundles were made for gitlogger_cli-0.0.1.tar.gz:
Publisher:
cicd.yml on TechnoBro03/GitLogger
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gitlogger_cli-0.0.1.tar.gz -
Subject digest:
d4d71c13e71a372c80c792770cb0674d744ffda2da1728ca839936dd7fb2df36 - Sigstore transparency entry: 1594730337
- Sigstore integration time:
-
Permalink:
TechnoBro03/GitLogger@fd59dfd498b59f0a766a0f60688ceb93ef27e95b -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/TechnoBro03
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cicd.yml@fd59dfd498b59f0a766a0f60688ceb93ef27e95b -
Trigger Event:
push
-
Statement type:
File details
Details for the file gitlogger_cli-0.0.1-py3-none-any.whl.
File metadata
- Download URL: gitlogger_cli-0.0.1-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b47dc1f7050558620f699123b05c10e7a49f23c986edf39b605981e27b7fd5a4
|
|
| MD5 |
02cb7a6d15ada7c0aa10889ec360776b
|
|
| BLAKE2b-256 |
7ddded67a89cf4ab5c61fe90de494583bcf6b4dd91173b37c4c301542cbc13e2
|
Provenance
The following attestation bundles were made for gitlogger_cli-0.0.1-py3-none-any.whl:
Publisher:
cicd.yml on TechnoBro03/GitLogger
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gitlogger_cli-0.0.1-py3-none-any.whl -
Subject digest:
b47dc1f7050558620f699123b05c10e7a49f23c986edf39b605981e27b7fd5a4 - Sigstore transparency entry: 1594730394
- Sigstore integration time:
-
Permalink:
TechnoBro03/GitLogger@fd59dfd498b59f0a766a0f60688ceb93ef27e95b -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/TechnoBro03
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cicd.yml@fd59dfd498b59f0a766a0f60688ceb93ef27e95b -
Trigger Event:
push
-
Statement type: