git log is one of the most powerful and yet most underused inspection tools in Git. While many developers use it only to view basic commit history, it can be turned into a highly flexible data-extraction and data-generation tool. With the right flags and formatting options, git log becomes not just a history viewer, but an element of data pipeline for debugging, analytics and automation.
Below are several advanced usage patterns that go well beyond the default experience.
Structured output with --pretty=format:
One of the most powerful features is using --pretty=format: to control exactly how commit data is printed. This is especially useful when you want to process git log output further with some scripts. Instead of nice-looking and human-readable logs, you can output records that are easy to parse:
git log --pretty=format:"%H|%an|%ad|%s" --date=iso
This produces pipe-separated fields:
-
%H- full commit hash -
%an- author name -
%ad- author date -
%s- commit subject -
--date=iso- converts dates from Fri May 22 16:08:53 2025 to 2025-05-22 16:08:53 +0200
Now, you can easily parse it with scripts like:
import subprocess
output = subprocess.check_output([
"git", "log",
"--pretty=format:%H|%an|%ad|%s",
"--date=iso"
]).decode()
for line in output.splitlines():
commit_hash, author, date, message = line.split("|", 3)
Time-based and path-based history analysis
git log becomes significantly more powerful when you treat history like a queryable dataset:
git log --since="2025-01-01" --until="2025-12-31"
You can also use relative times:
git log --since="2 weeks ago"
Or narrow it down to a single file to inspect how that file evolved:
git log --since="2 weeks ago" -- path/to/file
A useful flag here may be also the --follow flag which tracks renames. If your boundaries are not dates, but certain hashes, you can use them as well:
git log hashA..hashB
What can be of course combined with other flags:
git log hashA..hashB --oneline -- path/to/file
Exporting logs to specific file formats
A less obvious, but powerful use case is treating git log as an export mechanism capable of handling multiple file formats. For example, you can format the git log output as if was a JSON file element and then with jq you can combine it into a valid JSON file:
git log --pretty=format:'{"hash":"%H","author":"%an","date":"%ad","msg":"%s"}' -20 | jq -s '.' > history.json
I used jq -s here to read multiple JSON objects and wrap them into a list, so I end up with a list of dictionaries where each dictionary represents a single commit properties.
AI is powerful. Snippets are instant.
Stop prompting for the same patterns repeatedly. Get almost 100 free VS Code snippets for C++, Python, CMake and Bazel from piko::snippets GitHub repository.
Visualizing history as a graph
git log --graph --oneline --decorate --all
This shows:
- branching structure (
--graph) - compact commits (
--oneline) - branch/tag labels (
--decorate) - all references (
--all)
Extracting commit statistics for analytics
Another advanced pattern is using git log to compute repository-level insights. For example, if you need to map the author to the number of commits, call:
git log --pretty=format:"%an" | sort | uniq -c | sort -nr
The output can always be limited by providing the amount of past commits that are supposed to be analyzed:
git log --pretty=format:"%an" -20 | sort | uniq -c | sort -nr
Final combo
Let's now construct a final combo command which:
- extracts assymetricaly changes between
hashAandhashB - filters out changes older than 2 weeks
- keeps easily-parsable date formats
- formats commit properties into a JSON objects
- builds a valid JSON list of dictionaries
- saves it into a JSON file
git log hashA..hashB --since="2 weeks ago" --date=iso --pretty=format:'{"hash":"%H","author":"%an","date":"%ad","msg":"%s"}' | jq -s '.' > history.json
Top comments (0)