git log: View and Filter Your Commit History

- git log
- git log -- path
- Loglune audit
git log is the Git command that shows the commit history of a repository. With no arguments, git log lists the commits reachable from your current commit (HEAD) in reverse chronological order, and prints each commit’s hash, author, date, and message. Options change how much it shows: -10 limits the output to the last 10 commits, --oneline prints one line per commit, -p adds each commit’s diff, and filters such as --author, --since, --grep, -S, and -- <path> narrow the history to the commits you are looking for.
This guide is for developers who need to find a commit: who changed a file, when a bug came in, or what a branch added. It explains the output, then the options that show, filter, and format commits. Recovering commits that no branch points to belongs to git reflog and is not covered here.
The same questions come up for production changes that never went through a commit, such as a feature flag edit. The last section of this guide reads a flag’s change history the way you read git log, with output Loglune recorded on October 6, 2026.
What git log shows
git log shows the commit logs: the commits reachable by following the parent links from the commits you name. When you name no commit, git log starts from HEAD, so you see the history of the branch you have checked out. A commit you made on another branch does not appear until you name that branch, as in git log feature, or add --all to include every branch.
The default output has one entry per commit. Each entry starts with the full commit hash, then the author, the date, and the indented commit message.
$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date: Mon Mar 17 21:52:11 2008 -0700
Change version number
The most recent commit comes first. To list the oldest commit first, add --reverse.
How to read and exit git log output
Each field in the default git log output answers one question about a commit. commit is the 40-character hash that identifies the commit, which other commands such as git show and git revert take. Author is the person who originally wrote the change, with an email address, and Date is the author date, when the change was written. The message follows: the subject line, then the body if the commit has one.
Git separates the author, the person who originally wrote the work, from the committer, the person who last applied it. The two differ when someone applies another person’s patch or rewrites a commit. --pretty=fuller prints both.
git log opens long output in a pager. Git uses the Less terminal pager. Press Space for the next page, / to search, and q to quit and return to the shell. To print without a pager, run git --no-pager log.
Show the last 10 commits
-<n> limits git log to the last n commits, so git log -10 shows the last 10. The long forms -n 10 and --max-count=10 do the same.
git log –oneline
git log --oneline prints each commit on one line: the abbreviated hash and the subject. It is shorthand for --pretty=oneline --abbrev-commit. It is the usual first command when you need a commit hash for git show, git revert, or git bisect.
git log –graph for branches and merges
--graph draws an ASCII graph of the branch and merge history next to the log. Combine it with --oneline to keep the graph readable, --all to include every branch instead of only HEAD, and --decorate to print branch and tag names next to the commits they point to.
git log --oneline --graph --all --decorate
In the result with a merge, |\ opens the merged branch and |/ closes it. The excerpt below is shortened to 5 commits.
* 5e3ee11 Merge branch 'master' of https://github.com/dustin/grit.git
|\
| * 420eac9 Add method for getting the current branch
* | 30e367c Timeout code and tests
|/
* d6016bc Require time for xmlschema
Show what changed in each commit
git log can print the change each commit made, not only its metadata. -p (--patch) adds the full diff the commit introduced. --stat adds the changed files with added and removed line counts and a summary line, and --shortstat adds only that summary line. --name-only adds the names of the changed files, and --name-status adds them with A, M, or D for added, modified, or deleted.
git log -p -2 shows the last 2 commits with their diffs, which is a quick way to review what a colleague just pushed.
Filter the commit history
A real repository has thousands of commits, so most uses of git log narrow the list. Filters combine, and a commit has to match all of them.
By date
--since (or --after) and --until (or --before) take absolute dates such as "2026-09-01" and relative ones such as 2.weeks, as in git log --since=2.weeks or git log --since="2026-09-01" --until="2026-10-01".
By author or committer
--author keeps commits whose author name or email matches the pattern, as in git log --author="alice@example.com". --committer does the same for the committer.
By commit message
--grep keeps commits whose message contains the pattern, as in git log --grep="checkout" -i, where -i ignores case. Several --author and --grep patterns match any of them, and --all-match requires every --grep pattern.
By code content
-S keeps commits that changed the number of occurrences of a string, which is called the pickaxe option. Use it to find the commit that added or removed a function call. -G keeps commits whose diff has added or removed lines matching a regular expression, so it also finds commits that only moved the string.
git log -S "isCheckoutV2Enabled" --oneline
git log -G "checkout-v2" --oneline
By file or directory
A path after -- limits git log to the commits that changed that file or directory. The -- separates paths from options and branch names.
git log -- src/checkout/
git log --follow -- src/checkout/cart.ts
--follow continues the history of a file beyond renames and works only for a single file. To trace a range of lines or one function inside a file, use -L, for example git log -L :applyDiscount:src/checkout/cart.ts.
By branch or range
main..feature lists the commits on feature that are not on main, which is what a pull request from feature would add. It is shorthand for ^main feature. --no-merges hides merge commits, and --first-parent follows only the first parent at each merge, which gives the history of main as a list of merged changes.
git log main..feature --oneline
git log --first-parent main --oneline
Format git log output
--pretty=format: prints only the fields you name. An explicit format does not change between Git versions, so scripts that parse git log should use one.
git log --pretty=format:"%h %an %ad %s" --date=short
| Placeholder | Output |
|---|---|
%H / %h |
Commit hash, full and abbreviated |
%an / %ae |
Author name and email |
%ad / %ar |
Author date, in the --date format or relative |
%cn / %cd |
Committer name and date |
%s |
Subject |
%d |
Branch and tag names, like --decorate |
--date=short prints dates as 2026-10-06, --date=iso adds the time and time zone, and --date=relative prints values such as “2 weeks ago”.
git history and commit history
git history and commit history usually mean the same thing as git log: the list of commits behind a branch. git log reads it from the terminal. gitk opens a graphical view of the same history, and a Reddit thread in the git log results suggests gitk <branch name> or gitk <file name> for browsing it. git log lists many commits, and git show <hash> prints one commit in full with its metadata and diff. git log -p -1 and git show HEAD print the same latest commit with its diff.
The commit history records changes that went through Git. A change made outside Git, such as a configuration edit in a dashboard, a feature flag rollout, or a targeting rule change, leaves no commit, and git log, git log -S, and git log -- <path> cannot find it.
Viewing the change history of feature flags
When a bug starts and git log shows no commit around that time, the change often lives in a feature flag. The questions are the same ones git log answers for code: what changed, who changed it, when, and which release shipped it. A flag tool needs a log with the same fields.
Loglune keeps that log. Every flag edit is appended as a change event with a seq number, the actor, the time, and the flag’s state before and after. The audit log lists those events, and each event carries publishedIn, the version that first published it, or null while the edit is still in the draft. Passing a flag key narrows the list to that flag’s changes, which plays the role of git log -- <path>.
| Question | git log | Loglune audit |
|---|---|---|
| Who changed it | --author, %an |
actor |
| When | --since, %ad |
at |
| What changed | -p |
before and after |
| Only one item | git log -- <path> |
flagKey |
| Which release shipped it | --decorate with tags |
publishedIn |
Two differences matter when you read it. git log prints the newest commit first, and the Loglune audit lists events in seq order, oldest first. git history can be rewritten with an amend, a rebase, or a force push, and Loglune rejects updates and deletions of change events and links each row into a hash chain, so the audit ends with a verification result.
What the output looks like
We ran the shipped control route on a local test database on October 6, 2026, with editorial example flags and 2 example actors. alice@example.com created checkout-v2 and promo-banner with default off and published version 1. bob@example.com added a rule that serves on to the beta plan and published version 2. alice@example.com switched promo-banner to on, bob@example.com switched checkout-v2 to default on with no rules, and bob@example.com published version 3. alice@example.com then added a rule that serves off to the enterprise plan without publishing.
The audit narrowed to checkout-v2 returned status 200 with 4 of the 6 events, the ones that changed that flag.
| seq | at | actor | op | change | publishedIn |
|---|---|---|---|---|---|
| 1 | 2026-10-06T09:01:00.000Z | alice@example.com | create | default off, no rules |
1 |
| 3 | 2026-10-06T09:04:00.000Z | bob@example.com | update | added rule beta-users: plan in beta gets on |
2 |
| 5 | 2026-10-06T09:07:00.000Z | bob@example.com | update | default off to on, rule removed |
3 |
| 6 | 2026-10-06T09:09:00.000Z | alice@example.com | update | added rule enterprise-off: plan in enterprise gets off |
null |
Each event holds the full flag definition before and after. This is seq 5’s before and after, the equivalent of the diff that git log -p prints, with the variations omitted.
"before": {
"key": "checkout-v2",
"defaultVariationId": "off",
"rules": [
{
"id": "beta-users",
"clauses": [{ "attribute": "plan", "op": "in", "values": ["beta"] }],
"variationId": "on"
}
]
},
"after": {
"key": "checkout-v2",
"defaultVariationId": "on",
"rules": []
}
Publishing version 3 had already flagged that change. The publish response compared version 3 with version 2 and returned "kind": "defaultFlip", "flagKey": "checkout-v2", "before": "off", "after": "on", "severity": "high", along with the same finding for promo-banner.
The audit response ended with the verification of the hash chain over all 6 events.
"chain": {
"verified": true,
"count": 6,
"legacy": 0,
"brokenAtSeq": null,
"head": {
"seq": 6,
"hash": "b9a75d37b076c6f875b2cb3385fcf64932d864bf4ab76b365bf7dbf0f2ba56c6"
},
"anchor": "absent"
}
Read like git log, the table answers the incident questions directly. If enterprise customers report that checkout changed, seq 5 by bob@example.com at 09:07 UTC, shipped in version 3, switched every customer to on, and seq 6, the rule that would exclude enterprise, is still unpublished. To find which change flipped one customer’s result, see git bisect, and to undo one change with a new edit, see git revert.
Reading history before you change it
Start with git log --oneline to get your bearings, add -p or --stat when you need the change itself, and narrow the commit history with --since, --author, --grep, -S, and -- <path> until only the commits you care about remain. The hash you find there is the input to git show, git revert, git reset, and git bisect. When the change you are chasing was a feature flag edit rather than a commit, Loglune’s audit gives you the same log for flags: who changed which flag, when, from what to what, and which version shipped it.
Read your feature flag changes the way you read git log
Loglune records every flag edit as a change event with a seq number, the actor, the time, and the flag's state before and after the edit. Its audit lists those events with the version that first published each one, narrows to a single flag the way git log narrows to one file, and returns a verification result for the history's hash chain. The audit log is part of the Team Standard plan.