How to Use git log Formats Graphs and Filters Step by Step
Use git log formats, graphs and filters: oneline graph views, custom pretty formats, date and author filters, branch ranges, and a one-line alias.

The default git log prints a page of text per commit, which is a poor way to understand a repository. A few options turn it into a map or a report, and the filters answer questions about people, time and files. It pairs with blame and the pickaxe for tracing changes. Examples use Git 2.47.
The graph view
git log --oneline --graph --decorate --all -n 8* 8f2d1c4 (HEAD -> main, origin/main) Fix cache expiry
| * 3c9e7a1 (feature/lazy) Lazy-load settings
|/
* b1f7a92 Add retry logic
* a0c4e11 (tag: v2.3.0) Release 2.3.0
Each * is a commit and the lines show how branches split and merge. --decorate labels branches and tags, --all includes every ref instead of only the current branch. -n 8 keeps the output short.
Custom formats
git log --pretty=format:'%h %ad %an %s' --date=short -n 38f2d1c4 2026-11-02 Ada Lovelace Fix cache expiry
b1f7a92 2026-10-29 Grace Hopper Add retry logic
a0c4e11 2026-10-20 Ada Lovelace Release 2.3.0
Placeholders include %h short hash, %an author name, %ae author email, %ad author date, %s subject and %d ref names. Use --pretty=format:'%H' for full hashes in a script, and --format=%x00 style separators when parsing.
Filters
git log --since="2 weeks ago" --author="Ada" --oneline
git log --grep="fix" -i --no-merges --oneline
git log --stat -n 2 -- src/cache.py
git log main..feature --oneline
git log main...feature --left-right --onelineTime filters accept natural phrases. --grep searches commit messages, and -i makes it case-insensitive. The -- before a path marks the end of options so that a file name cannot be mistaken for a branch. main..feature lists commits on feature that main lacks, which is what a pull request would contain. The triple-dot form with --left-right marks which side each commit is on.
Make it a command
git config --global alias.lg "log --oneline --graph --decorate --all"
git lg -n 10Aliases keep the long form out of your fingers. You can add the format with colors: %C(yellow)%h%C(reset) %s.
Where this does not apply
For a GUI feel, tig and editors do the same with interactive selection. Very large repositories make --all --graph slow, so limit by count or date. Log shows commits, not content: to see what changed use git diff or git show. For searching which commit changed a string, use -S from the previous post.
Two more habits are worth having. Set log.date iso or short in your config so every command prints dates in a consistent form, and use git log --oneline --decorate -n 20 as the standard first look at an unfamiliar repository. Combined with a path filter, it answers "who has been working on this file lately?" in one line.
How the graph is drawn
The --graph option draws ASCII lines in the left margin showing where branches split and merge, with each commit marked by a star. The shape only makes sense when commits are ordered so parents appear after children, which is the default order, and adding --all includes every branch and tag so you see the whole picture and not just the checked-out branch. --oneline reduces each commit to a short hash and subject, which is the form that fits on a screen. Add --decorate to show branch and tag names beside the commits, and note that current versions turn decoration on automatically when output goes to a terminal and not when it is piped. The combination of graph, all, decorate and oneline is the one people alias, and it is a good picture of how branches relate in a repository with several long-lived lines.
The graph gets confusing for repositories with many merges, since the lines weave. Use --first-parent to follow only the main line, so merge commits appear as single steps and feature branch detail drops away. That view reads like a release history.
Format placeholders and when to use them
The --pretty=format: option builds output from placeholders. %h is the abbreviated hash, %an the author name, %ar the relative date, %s the subject, %d the decorations and %C codes add color. Use the tformat variant when the output feeds other tools, because it ends every entry with a newline, while format separates entries and leaves the last without one, which causes odd results when you pipe into while read. Choose a separator that does not occur in commit subjects, for example a tab or the unit separator character, so you can split fields reliably. Subjects can hold almost anything, including the pipe and the comma, so a format built on commas breaks on the first commit that has one.
Plain machine output has to avoid color and pagers. Pass --no-pager before the command name and avoid the %C placeholders, and the result is stable text for scripts and reports.
Filtering to the commits you want
Filters narrow the list before formatting. --author matches a regular expression against the author, --grep against the message, --since and --until take dates in many human forms, and a path after a double dash limits the history to those files. Ranges express relations: main..feature lists commits on feature that are not on main, and three dots show the symmetric difference, commits on either side but not both. --no-merges removes merge commits from the list and --merges shows only them. Combine filters with care, because the date filters work on the commit date, not the author date, and rebased commits can have a commit date far from when the work was written.
For counting, git shortlog -sn summarizes commits per author, and git rev-list --count gives a plain number for a range, which fits release notes and scripts.
Turning the useful views into aliases
A command you type once a day should be short. Put the graph view in an alias with git config --global alias.lg followed by the full set of options, and use it from then on as git lg. Make a second alias for a one-line log of your own recent commits with --author and --since, which is handy at a stand-up meeting or when writing a weekly summary. Keep each alias to a single idea so you can remember it, and store the definitions in your dotfiles so they move with you. Aliases that start with an exclamation mark run in the shell, which allows pipelines and arguments, at the price of being less portable between systems.
Know the cost on large repositories. Drawing a graph of all branches in a history with hundreds of thousands of commits takes noticeable time. Limit the count with -n or a date, and let the pager do the scrolling, since Git stops reading as soon as the pager closes.
Two settings improve the output without any alias: log.date chooses how dates are shown, and log.abbrevCommit shortens hashes. Date format options such as iso and relative make logs readable, while the short format helps in reports where only the day matters.
The placeholders are listed in pretty formats and the range syntax in gitrevisions.


