Skip to content
masterclass Buddy

Git · Command

git shortlog

git shortlog condenses commit history into a list grouped by contributor, with each person's commit subjects under their name. It is meant for release notes and contributor statistics.

Last updated

How it works

git shortlog walks history like git log and accepts the same options for choosing commits, such as revision ranges, paths, dates and --no-merges. Instead of printing every commit in full, it puts commits into buckets and prints each bucket's header followed by its commit subjects. By default the buckets are authors, sorted alphabetically. You can bucket by committer, by a trailer such as Reviewed-by, or by any git log format string. You can also replace the subjects with counts. It can read git log output from a pipe instead of a repository, and it applies .mailmap so that one person's different identities are merged into one.

Syntax

git shortlog [<options>] [<revision-range>] [[--] <path>…]
git log --pretty=short | git shortlog [<options>]

Parameters

NameTypeDescription
-n, --numberedflagSorts groups by how many commits they have instead of alphabetically.
-s, --summaryflagPrints only a commit count for each group and leaves out the subjects.
-e, --emailflagAdds each author's email address to the output.
--format[=<format>]stringDescribes each commit with a git log pretty-format string instead of its subject.
--date=<format>stringSets how dates are formatted. Most useful together with --group=format:<format>.
--group=<type>author | committer | trailer:<field> | format:<format>Sets what commits are grouped by. The default is author, and you can pass it more than once.
-c, --committerflagShort form of --group=committer.
-w[<width>[,<indent1>[,<indent2>]]]integersWraps and indents the output lines. A width of 0 indents the lines without wrapping them.
<revision-range>revision rangeLimits the summary to commits in this range, for example origin..HEAD. Defaults to HEAD.
[--] <path>...pathsLimits the summary to commits that explain how the matching files came to be.

Returns

Text on standard output: one header per group (with a commit count) followed by indented commit descriptions, or only counts and names when -s is used.

Key points

  • -n changes the order so that the most active contributors come first. Without it, groups are listed alphabetically by name.
  • -s turns the output into a compact table of commit counts. Combined with -n and -e (-sne), it gives a ranked list of contributors.
  • Besides authors, you can group commits by committer, by a commit-message trailer (matched without regard to case), or by any git log format string.
  • If you pass --group more than once, a commit counts toward every matching group. Within one commit, each distinct value is counted only once.
  • shortlog removes the "[PATCH]" prefix from commit subjects, which keeps the output clean for projects that apply emailed patches.
  • With -w and no values, lines wrap at 76 columns. The first line of each entry is indented 6 spaces and continuation lines 9 spaces.
  • A revision range such as v1.0..v2.0 limits the summary to the commits between two releases, which is how you build per-release notes.

Common mistakes

  • In CI jobs, hooks or other scripts where stdin is not a terminal, running plain git shortlog reads from stdin instead of the repository and may print nothing. Pass an explicit revision such as HEAD.
  • When grouping by trailer, commits without that trailer are left out of the totals entirely. This makes the totals unreliable as a count of all work.
  • A commit with several trailers of the same kind, such as multiple Signed-off-by lines, can be counted in several groups. Totals across groups can therefore be larger than the number of commits.
  • When you pipe log text into shortlog outside a repository, it looks for .mailmap only in the current directory. Run it in the wrong directory and identities will not be merged.

Example: Contributor stats and release notes

#!/usr/bin/env bash
set -euo pipefail

# Ranked contributor counts with emails for the whole history
git shortlog -sne HEAD

# Release notes: commit subjects per author between two tags, skipping merges
git shortlog --no-merges v1.0..v2.0

# Who has been reviewing? Count Reviewed-by trailers
git shortlog -ns --group=trailer:reviewed-by HEAD

# Credit authors and co-authors together
git shortlog -ns --group=author --group=trailer:co-authored-by HEAD

# Commits per year, grouped by a date format
git shortlog -s --date=format:%Y --group=format:%ad HEAD

# Summarize piped log output from a topic branch
git log main..feature | git shortlog

Each command passes an explicit revision (or reads from a pipe) so it behaves the same in scripts and in a terminal, and together they show counting, release notes, trailer grouping, multi-grouping and date grouping.

When to use it

Writing release announcements

A maintainer runs shortlog over the range between the previous and new tags. This produces a by-author list of changes to paste into the announcement.

Recognizing code reviewers

A team that adds Reviewed-by trailers groups history by that trailer to see who does the most reviewing.

Checking what a topic branch contains

Before merging, a developer pipes the log of commits not yet on main into shortlog to see a summary of the branch's changes and who wrote them.

Activity over time

Grouping by a formatted author date gives a count of commits per year or per month for project health reports.

Interview questions

QHow would you get a ranked list of everyone who contributed to a repository, with commit counts and email addresses?

Run git shortlog -sne HEAD. -s replaces the commit subjects with a count, -n sorts by that count instead of by name, and -e adds email addresses. Including HEAD explicitly avoids the stdin behavior when running in a script.

Follow-up: The same person appears twice under different emails. How do you merge them? Add a .mailmap file that maps the old identities to one canonical name and email; shortlog applies the mailmap when it groups commits.

QWhy might git shortlog print nothing in a CI pipeline when it works fine in your terminal?

When no revisions are given and stdin is not a terminal, or there is no current branch (as with a detached HEAD in many CI checkouts), shortlog summarizes log text read from stdin instead of the repository. In CI stdin is usually empty or redirected, so there is nothing to summarize. Passing a revision such as HEAD or a tag range fixes it.

Follow-up: How can you deliberately use the stdin mode? Pipe git log output into it, for example git log main..feature | git shortlog; outside a repository it then looks for .mailmap in the current directory.

QHow can shortlog credit co-authors as well as commit authors?

Pass --group more than once, for example --group=author --group=trailer:co-authored-by. Each commit then counts under its author and under each distinct Co-authored-by value. The trailer name is matched without regard to case, and trailer values that look like 'Name <email>' are parsed as identities and passed through the mailmap.

Follow-up: Why can the counts add up to more than the total number of commits? A single commit is counted once in every group it matches, such as its author and each of its co-authors, so totals across groups overlap.

  • git log
  • git blame
  • gitmailmap
  • git interpret-trailers
  • gitrevisions
  • git describe

Source: Git - git-shortlog Documentation. Checked 2026-11-02.