Pre-push review
Run git log origin/main..HEAD before pushing or opening a pull request to see exactly which local commits will go out.
Git · Command
git log shows commit history. It lists the commits you can reach from the starting points you give, newest first, and you can filter, order and format that list.
Last updated
Git starts from the revisions you name, or HEAD if you name none, and follows parent links back through history. Anything reachable from a revision marked with ^ (or placed after --not) is taken out of the result. The A..B form means ^A B, and A...B returns commits on either side but not both. Limiting options such as path filters, dates, authors and message patterns narrow that set. Ordering and formatting options then control how it prints. git log accepts git rev-list options for choosing commits and git diff options for showing each commit's changes.
git log [<options>] [<revision-range>] [[--] <path>…]| Name | Type | Description |
|---|---|---|
<options> | flags | Options for limiting, simplifying, ordering and formatting commits, taken from rev-list, plus diff options that control how each commit's changes are shown. |
<revision-range> | revision range | Shows only commits in this range, for example origin..HEAD. If you leave it out, it defaults to HEAD, which is all history leading to the current commit. |
[--] <path>… | pathspec | Keeps only the commits needed to explain how the matching files reached their current state. Put -- in front when a path could be confused with an option or a revision. |
Prints the selected commits to standard output, newest first by default, in the chosen pretty format (medium by default). Diff output can be added with options such as -p or --stat.
git log -n 3 --reverse reverses the 3 newest commits; it does not show the 3 oldest.#!/usr/bin/env bash
set -euo pipefail
# Commits on my branch that are not on origin/main, compact view
git log --oneline --no-merges origin/main..HEAD
# Same range, with per-file stats, only commits by me in the last 2 weeks
git log --stat --author="$(git config user.name)" --since="2 weeks ago" origin/main..HEAD
# History of one file, following renames, custom format
git log --follow --format='%h %ad %an %s' --date=short -- src/app.ts
# How a function evolved over time
git log -L :handleRequest:src/server.ts
# Mainline-only overview as a graph
git log --first-parent --graph --oneline -20The script uses ranges, author and date filters, rename-following path history, function tracing with -L and a first-parent graph to show the most common ways to filter and format git log output.
Run git log origin/main..HEAD before pushing or opening a pull request to see exactly which local commits will go out.
Use --follow on one file, or -L on a function, to find when and why a piece of code changed, even if it was renamed.
List the non-merge commits between two tags in a custom --format to draft a changelog.
Use git log -g to walk the reflog and find commits that no branch points to anymore after a reset or rebase.
A..B is shorthand for ^A B: it shows commits reachable from B but not from A, which is what B has that A doesn't. A...B is the symmetric difference: commits reachable from either side but not from both. That is the same as listing A and B and excluding their merge base(s).
Follow-up: How can you tell which side each commit in A...B came from? Add --left-right to mark commits with < or >, or use --left-only/--right-only to show one side; --cherry-pick also hides commits whose patch already exists on the other side.
By default git log simplifies history. When a merge is TREESAME to one of its parents for that path, Git follows only that parent and never looks at the other side. Commits that only existed on that other side drop out. --full-history follows every parent, and --simplify-merges or --show-pulls cut that output down to the merges that actually matter.
Follow-up: What does --simplify-merges cost? Before it can print a single result it must walk the entire commit history, which makes it slow on very large repositories.
Use git log --oneline --author=<pattern> --since='1 week ago' --grep=fix. Each extra limiting option narrows the result further. --author and --grep take regular expressions, and -i makes them case-insensitive.
Follow-up: If you pass two --grep patterns, does a commit need to match both? No. A match on any one pattern is enough by default; add --all-match to require all of them, or --invert-grep to keep commits that do not match.
git-rev-listgit-showgit-diffgit-shortloggit-refloggit-blamegitrevisionsgit-notes