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=isoThis 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/fileA 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..hashBWhat can be of course combined with other flags:
git log hashA..hashB --oneline -- path/to/fileExporting 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.jsonI 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 --allThis 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 -nrThe 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 -nrFinal 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.jsonRead also:
- git log tricks you really should know
- Surprisingly necessary explanation of Python venv
- When AI gets C++ bitmask enums almost right
- 10 VS Code snippets essential for every C++ engineer
- Storing your ATTiny program in…EEPROM?
- Bug of the week #12
- Sharing variable between bash scripts
- A 40-line LLM-based bash command executor in Python
- GTest and short-circuit evaluation in C++
- AI is powerful. Snippets are instant.
- From AUTOSAR to S-Core: the first C++ pub/sub implementation
- How to write Arduino Uno code with Python?
- Combining Bazel with Docker
- Running commands with timeout on Linux
- Running Python unit tests with CMake
- Thirdparty dependencies with FetchContent
- Bug of the week #11
- Combining CMake with Docker
- How to search the internet from Linux terminal?
- Folding expressions in C++
- How to derive from an enum in Python?
- Bug of the week #10
- Trying ROS2: client/server within a single container
- Make C++ a better place #4: Go as an alternative
- How to convert hex to dec in Linux terminal?
- Setting up a Python project with CMake
- Separating builds for different configs with Bazel
- Trying ROS2: pub/sub within a single container
- Bug of the week #9
- UDP multicasting with Python
- Destruction order vs thread safety in C++
- Let’s review some code: C++ #2
- Make C++ a better place #3: D as an alternative
- Registering callback using std::function in C++
- Bug of the week #8
- TCP client/server with Python
- Simple menus in Bash scripts with select
- Calling member function on a nullptr in C++
- Bug of the week #7
- Python lru_cache explained
- How to dockerize a Python application?
- Make C++ a better place #2: CppFront as an alternative
- Parameters combinations in GoogleTest
- Data transfer with curl
- Python reduce explained
- Bug of the week #6
- Custom literals in C++
- Linux and hash command
- 5 Python good practices which make life easier
- Let’s review some code: Python #1
- Make C++ a better place #1: What does better mean
- Enums vs enum class in C++
- Bug of the week #5
- UDP client/server with Python
- Hard links in Linux
- Functions calling order in unit tests in C++
- Bug of the week #4
- Yield in Python – state machines, coroutines and more
- Copy files from another branch with Git
- Make C++ a better place #0: Introduction









