Filtering, Formatting, Understanding
Anyone who only uses git log with its default output is giving up one of the most powerful diagnostic tools in daily development work. With targeted filters by author, date and content, with custom pretty formats for scripts, and with pickaxe search, any line of code can be traced back to its origin without manually scanning the history.
Table of Contents
- 1. Why git log Is More Than a History Viewer
- 2. Basic Formats: --oneline, --graph and --stat
- 3. Filtering by Author, Date and Branch
- 4. Content Search with --grep and Pickaxe -S/-G
- 5. Custom Pretty Formats for Scripts and Changelogs
- 6. Tracking a Line or a Bug: -L and bisect
- 7. Merge Commits, --first-parent and Graph Readability
- 8. git log in Aliases, Hooks and CI Pipelines
- 9. git log Flags Compared
- 10. Summary
- 11. FAQ
1. Why git log Is More Than a History Viewer
Most developers know git log only as an output of commit hashes, authors and commit messages in the default view, a long list that gets closed with q after the first couple of screens without much thought. Yet git log is not a plain history viewer, it is a full query interface over the entire repository: every commit, every change to every file, and every line of code can be filtered, searched and exported into machine-readable formats on demand.
The real value of git log shows up the moment a bug appears in production and the question in the room is: who changed this line, when, and why? Without targeted filtering by author, date or content, the only option left is tediously scrolling through hundreds of commits by hand. With the right git log flags, that search becomes a matter of seconds, whether it is about attributing authorship, narrowing down a time window, or running a content-based pickaxe search for a specific code fragment.
2. Basic Formats: --oneline, --graph and --stat
git log --oneline reduces every commit to a single line with an abbreviated hash and commit message, ideal for a quick overview of recent changes, but unsuitable when branch structure matters. With --graph, Git draws an ASCII representation of the commit history including merges and parallel branches directly in the terminal output. The combination git log --oneline --graph --decorate --all additionally shows branch and tag names at every relevant commit, giving an instant picture of where branches diverge and where they merge back together.
For an overview of the actual size of a change, git log --stat lists the files touched per commit along with a compact bar-chart-style line statistic. This is particularly useful in code reviews, to estimate before reading the full diff whether a commit is small and focused or mixes several unrelated changes. Anyone who wants to see the full diffs inline adds -p or --patch, combined with --stat this produces a complete picture of every single change.
# Compact one-line overview of recent commits
git log --oneline -10
a3f9c21 fix: correct tax calculation for EU B2B customers
7b2e814 feat: add customer group price rule import
c91d4a0 refactor: extract PriceCalculator into service class
# Visual graph across all branches, with names and tags
git log --oneline --graph --decorate --all
* a3f9c21 (HEAD -> main, origin/main) fix: correct tax calculation
| * 9c2f110 (feature/price-import) feat: WIP price import
|/
* 7b2e814 feat: add customer group price rule import
# Per-commit stats: files touched and line changes
git log --stat -3
commit a3f9c21c8e2b4f1a9d0e3c7b5a6f8d2e1c9b0a3f
Author: Jane Developer <jane@mironsoft.de>
Date: Mon Jul 6 09:12:03 2026 +0200
fix: correct tax calculation for EU B2B customers
app/code/Mironsoft/Tax/Model/Calculator.php | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
3. Filtering by Author, Date and Branch
The filter --author="Name" searches the author metadata of every commit using a substring or regex match, making it the fastest way to isolate every change made by a specific person, for example before a team handover or when splitting up responsibilities during an audit. Important: --author filters by the commit author, not the committer, which matters when a rebase or a cherry-pick was performed by a different developer. A separate flag, --committer, exists for committer filtering.
Narrowing down by time is done through --since and --until, which also accept relative and natural-language expressions such as "2 weeks ago" or "2026-01-01". Combined with --author, this creates a precise query like "all commits by author X in the last three months". The search can additionally be limited to specific branches: git log branch-a..branch-b shows only commits that exist in branch-b but not in branch-a, the standard way to see, before a merge, which changes will actually land.
# Commits by a specific author within a date range
git log --author="Jane" --since="2026-01-01" --until="2026-03-31" --oneline
# Natural-language relative dates work too
git log --author="Jane" --since="3 months ago" --oneline
# Commits present in feature branch but not yet in main
git log main..feature/price-import --oneline
7b2e814 feat: add customer group price rule import
c91d4a0 refactor: extract PriceCalculator into service class
# Combine author, branch range and path filter
git log --author="Jane" main..feature/price-import -- app/code/Mironsoft/Tax
4. Content Search with --grep and Pickaxe -S/-G
--grep searches exclusively through commit messages for a pattern and is ideal when commits are consistently written with ticket numbers or conventions like "fix:". Multiple --grep options are combined with OR by default, --all-match forces an AND combination instead. The pickaxe search with -S "string" works completely differently: it finds commits where the number of occurrences of an exact string in the diff changed, that is, exactly the commits where a line of code was added or removed, regardless of the commit message.
-G "regex" is the regex-based sibling of -S: it searches for commits whose diff contains a line matching the regular expression, regardless of whether the occurrence count changes. For finding when a bug was introduced, -S is usually more precise because it pinpoints the exact moment a specific function, variable or line of code first appears or disappears. With --pickaxe-regex, -S can additionally be combined with a regular expression instead of an exact string.
# Search commit messages for a ticket reference
git log --grep="MAGENTO-4821" --oneline
# Pickaxe: find commits where an exact string was added or removed
git log -S "applyTaxToShippingAddress" --oneline
f1a02de fix: disable shipping tax for digital-only carts
7b2e814 feat: add customer group price rule import
# Show the actual diff for the introducing commit
git log -S "applyTaxToShippingAddress" -p -- app/code/Mironsoft/Tax/Model/Calculator.php
# -G matches any diff line against a regex, regardless of occurrence count
git log -G "function calculate[A-Za-z]*Tax\(" --oneline
5. Custom Pretty Formats for Scripts and Changelogs
--pretty=format:'...' replaces the default output with a freely defined pattern of placeholders: %h for the abbreviated hash, %an for the author name, %ad for the date, %s for the commit message, and %d for branch and tag references. A format like '%h|%an|%ad|%s' with a pipe as delimiter produces one line per commit that can be trivially parsed in Bash, PHP or any other script with a single delimiter, without any fragile parsing of multi-line free-text output.
For recurring queries, a Git alias pays off: git config --global alias.lg with an elaborate format makes that output available with a single command, git lg. For automated changelog generation, --pretty=format combined with a range since the last tag works well: git log $(git describe --tags --abbrev=0)..HEAD --pretty=format:'- %s' directly produces a Markdown-ready list of every commit since the last release.
# Custom pretty format for scripting: pipe-delimited, one line per commit
git log --pretty=format:'%h|%an|%ad|%s' --date=short -5
a3f9c21|Jane Developer|2026-07-06|fix: correct tax calculation for EU B2B customers
7b2e814|Jane Developer|2026-07-02|feat: add customer group price rule import
# Colored one-liner as a reusable alias
git config --global alias.lg "log --graph --pretty=format:'%C(yellow)%h%Creset %s %C(dim)(%an, %ar)%Creset'"
git lg -5
# Changelog since the last tag, ready for Markdown
git log "$(git describe --tags --abbrev=0)"..HEAD --pretty=format:'- %s (%h)'
6. Tracking a Line or a Bug: -L and bisect
git log -L start,end:file shows the complete change history of a range of lines, not the whole file, every commit that touched those specific lines appears with the matching diff excerpt. Even more precise is git log -L :functionname:file, which tells Git to determine the line range automatically based on the function boundaries and to keep following it correctly even when the function moves within the file. This is the direct way to find out exactly when a specific method was last changed and who is responsible for the current implementation.
To find the exact commit that introduced a bug, these tools are combined with git bisect. git bisect start marks the search range between a known good and a known bad commit, then git bisect bad/good halves the remaining number of commits at every step. With git bisect run ./test.sh, a test script automates the entire process end to end, in a repository with a thousand commits, the binary search needs on average only ten steps instead of a linear review.
# Full history of a specific function, following renames
git log -L :calculateShippingTax:app/code/Mironsoft/Tax/Model/Calculator.php
# History of a fixed line range
git log -L 40,60:app/code/Mironsoft/Tax/Model/Calculator.php
# Binary search for the commit that introduced a regression
git bisect start
git bisect bad HEAD
git bisect good v2.4.1
# Automate the search with a test script (exit 0 = good, 1 = bad)
git bisect run bin/phpunit --filter=TaxCalculatorTest
# Git narrows a 1000-commit history to roughly 10 steps
git bisect reset
7. Merge Commits, --first-parent and Graph Readability
A graph with --graph --all in an active repository with many feature branches quickly becomes unreadable, because every merge commit adds more lines and crossings. --first-parent reduces the output to the main path of every merge and hides the detail commits of the feature branches, which usually matches exactly the question "what was merged into main and when", without dragging along the internal history of every single branch.
--no-merges removes merge commits entirely from the output and is useful when only the actual content changes matter, for example in a pickaxe search that would otherwise be cluttered by empty or content-irrelevant merge commits. Conversely, --merges shows only merge commits, useful for auditing a team's merge strategy or checking how often work happened directly on main instead of through pull requests. The three flags are mutually exclusive and should be chosen deliberately depending on the question at hand.
8. git log in Aliases, Hooks and CI Pipelines
In deployment and release scripts, git log is the standard source for automatically generated release notes. A CI job can run git log previous_tag..new_tag --pretty=format:'%s' after every tag and build a structured changelog file from it, provided the commit messages follow a convention such as Conventional Commits so features, fixes and breaking changes can be separated automatically. Important in scripts: git --no-pager log prevents Git from waiting for a pager in a non-interactive environment and blocking the script.
For daily team digests, a cron job with git log --all --since="1 day ago" --pretty=format:'%an: %s' works well, sent out by email or Slack webhook. In commit hooks, git log -1 --pretty=%B can be used to re-read the latest commit message for validations such as ticket number checks. Across all of these automations, one rule applies: git log exit codes are typically 0 even when the output is empty, scripts must explicitly check for empty output rather than relying on the exit code.
9. git log Flags Compared
The same question can often be answered in git log through several different approaches, with clear differences in speed, precision and suitability for automation. The following overview compares the most common cases directly.
| Task | Unreliable / Inefficient | Recommended git log Pattern | Benefit |
|---|---|---|---|
| Find an author's commits | git log | grep "Author:" |
git log --author="Name" |
Searches metadata directly, supports regex |
| Find when a bug was introduced | Manually scrolling through history | git log -S "string" --oneline |
Finds the exact commit of the change |
| Line history of a function | git log -p file (full diff) |
git log -L :function:file |
Only relevant lines, follows moves |
| Generate a changelog | Copying/formatting history by hand | git log --pretty=format:'%h|%s' |
Machine-readable, scriptable |
| Graph with many branches | git log --graph --all |
git log --graph --first-parent |
Readable main path without detail noise |
In practice, these patterns are often combined: -S for finding a code change, --author for narrowing down to a team, --pretty=format for machine-readable output in a script. Once these flags are known individually, they can be freely combined depending on the situation, instead of scrolling through the history manually for every new question.
Mironsoft
Git workflows, code reviews and deployment processes for Magento and PHP teams
Ready to clean up your Git workflow and codebase?
We analyze your Git history, set up clean branching and release processes, and automate changelog generation as well as code review workflows for your Magento and Hyvä project.
Git Workflow Audit
Review branching strategy, commit conventions and merge practices across the team
CI Automation
Automate changelog generation and release notes directly from git log
Bug Diagnosis
Trace regressions back to their origin quickly with git bisect and pickaxe search
10. Summary
The most important git log patterns always solve the same underlying problem: turning a linear list of commits into targeted answers to concrete questions. --oneline --graph --decorate delivers a quick visual overview of branches and merges. --author and --since narrow the search down to a person and a time window. -S and -G find commits based on actual code changes rather than commit messages. --pretty=format makes the output machine-readable for scripts and CI pipelines.
The biggest leverage comes from combining these flags rather than using them in isolation: a bug can usually be narrowed down fastest with -S "suspicious code" --author="team member" --since="3 months ago", before git log -L or git bisect deliver the exact line or the exact commit. Anyone who masters these tools spends significantly less time scrolling through history manually and finds answers in seconds instead of minutes.
Using git log Effectively, The Essentials at a Glance
Basic Formats
--oneline --graph --decorate for a quick visual overview of branches and merges.
Filtering
--author, --since/--until and branch ranges (a..b) narrow the search precisely.
Content Search
-S for exact string changes, -G for regex matches, --grep for commit messages.
Scripting
--pretty=format with placeholders (%h %an %ad %s) for machine-readable output in CI and changelogs.