Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Counting All Git Commits from All Authors and More with Git Shortlog

blog/cards/counting-all-git-commits-from-all-authors-and-more-with-git-shortlog.jpg

This could be handy to see how many people committed to a repo or find out who the recent contributers are.

Quick Jump: A Couple of Git Shortlog Commands | Demo Video

Lately I’ve been wanting to find out the answers to the following questions and statements:

  • Who has ever committed to this repo and how many commits do they have?
  • Show me a time sorted list of every commit made by a specific developer
  • Who are the most active developers in the last 90 days?

The last question is to get a rough idea of how much it would cost to use Snyk because their pricing is related to the number of unique committers in the last 90 days.

The first 2 questions could be useful to help understand how a project started and became what it currently is. Just seeing a list of committers with dates next to their name can give you a feel for a project at a glance.

For example, if there’s a lot of different devs committing to a project very often you could say it’s a fast moving project and the odds of bugs being introduced into the system is higher than a project that only has 1 committer in a project that hasn’t been updated in 3 months.

This data could help you explore an organization’s code base if you’re new and you want to see who to contact about a specific application. You could also use some of this data for general risk assessment around commits. There’s lots of possibilities!

A Couple of Git Shortlog Commands

I’ve run the commands below against this repo https://github.com/nickjj/docker-rails-example, it happens to be an open source repo I maintain with a good example to demonstrate a specific flag.

If you clone the above repo the values you see may differ than what’s below since it’s a project I’m actively working on.

A List of Commits for Everyone on the Current Branch

$ git shortlog

Nick Janetakis (152):
      Initial commit
      Release 0.1.0
      Rephrase million opinions sentence
      Make version sentence fit on 1 line
      Rephrase database.yml bullet point
      # [I purposely omit the rest of the output for brevity]

This is already pretty useful, we can see exactly how many commits someone has and a list of their commits. This will run against your currently checked out branch, such as main.

It will sort commits from oldest (top) to newest (bottom).

A List of Commits for Everyone on All Branches

$ git shortlog --all

Nick Janetakis (153):
      Initial commit
      Release 0.1.0
      Rephrase million opinions sentence
      Make version sentence fit on 1 line
      Rephrase database.yml bullet point
      # [I purposely omit the rest of the output for brevity]

snyk-bot (6):
      fix: upgrade postcss from 8.2.15 to 8.3.6
      fix: upgrade autoprefixer from 10.2.5 to 10.3.4
      fix: upgrade css-loader from 5.2.4 to 5.2.7
      fix: upgrade css-minimizer-webpack-plugin from 3.0.0 to 3.0.2
      fix: upgrade mini-css-extract-plugin from 1.6.0 to 1.6.2
      fix: Gemfile to reduce vulnerabilities

The --all flag will show commits on all branches, not just the checked out branch. In my repo’s case I tried using Snyk for a bit and didn’t merge all of its PRs but instead used GitHub’s “close multiple PRs” feature which closed the PRs but left the branches there.

There’s really a branch for each of those commits which is why this output is showing snyk-bot even though that user doesn’t have any commits on my main branch.

A List of Non-merge and Merge Commits for Everyone

$ git shortlog --all --no-merges

Nick Janetakis (151):
      Initial commit
      Release 0.1.0
      Rephrase million opinions sentence
      Make version sentence fit on 1 line
      Rephrase database.yml bullet point
      # [I purposely omit the rest of the output for brevity]

snyk-bot (6):
      fix: upgrade postcss from 8.2.15 to 8.3.6
      fix: upgrade autoprefixer from 10.2.5 to 10.3.4
      fix: upgrade css-loader from 5.2.4 to 5.2.7
      fix: upgrade css-minimizer-webpack-plugin from 3.0.0 to 3.0.2
      fix: upgrade mini-css-extract-plugin from 1.6.0 to 1.6.2
      fix: Gemfile to reduce vulnerabilities

There’s 2 less commits here than the previous one for myself because --no-merges will avoid counting merge commits. Most of the time I commit straight to the main branch.

However there were 2 commits that I did in a PR because I wasn’t very confident in them so I made pull requests first to avoid potentially breaking the main branch.

Here’s a quick way to find only those merge commits:

$ git shortlog --all --merges

Nick Janetakis (2):
      Merge pull request #7 from nickjj/feature-remove-ci-cache
      Merge pull request #29 from nickjj/feature-rails-7-esbuild

Needless to say upgrading from Rails 6 with Webpacker to Rails 7 and esbuild was a big change! We’ll see how to show details like the git commit hash next to the commit in a bit by the way.

Also, if you avoid putting --no-merges or --merges then it will include both types.

A Grouped up List of Committers with How Often They Commit

$ git shortlog --all --summary

   153  Nick Janetakis
     6  snyk-bot

If you only want the counts, the --summary flag will help you out here. While I’m not showing it here, you can combine this flag with the others if you want to filter down or see different commit information.

If you’re only interested in the count and not the author you can use the rev-log command instead of shortlog. I have another post about that here.

Filtering Commits Down to a Specific Author

$ git shortlog --all --author "Nick Janetakis"

Nick Janetakis (153):
      Initial commit
      Release 0.1.0
      Rephrase million opinions sentence
      Make version sentence fit on 1 line
      Rephrase database.yml bullet point
      # [I purposely omit the rest of the output for brevity]

This is handy if you’re only interested in 1 specific author. You can also use the --author flag multiple times if you want to see more than 1 specific author at a time.

Show Commits since a Specific Date

These can be handy to find out who is actively working on a project.

Using an exact date
# Using "2022-07-01", "Jul 1 2022" and more also work as date formats
$ git shortlog --all --since "July 1st 2022"

Nick Janetakis (9):
      Update Postgres and Redis
      Update back-end dependencies
      Update front-end dependencies
      Update Rails to 7.0.3.1
      Update Postgres to 14.5
      # [I purposely omit the rest of the output for brevity]
Relative to X time ago
# You can replace "days" with "weeks", "months" and "years" too
$ git shortlog --all --since "90 days"

Nick Janetakis (12):
      Update Postgres and Redis
      Update back-end dependencies
      Update front-end dependencies
      Update Postgres and Redis
      Update back-end dependencies
      # [I purposely omit the rest of the output for brevity]
A specific range

There’s a --before flag for commits older than a specific date too. You can combine them to create a range like --since "April 1st 2022" --before "May 1st 2022".

Customizing the Output to Get More Commit Details

$ git shortlog --all --since "1 year" --format="format:%cs %h %s"

Nick Janetakis (68):
      2021-08-21 b1a1c47 Update Ruby dependencies
      2021-08-22 47d7b4f Update Ruby and Node base images
      2021-08-22 c1b2c4c Update Redis version
      2021-10-10 c3ebf56 Update Redis to 6.2.6
      2021-10-10 b95da6e Update Postgres to 14.0
      # [I purposely omit the rest of the output for brevity]

This starts to get quite useful. There’s a bunch of different formatting options. Git labels them as “pretty formats” and it’s in their docs.

In the above case:

  • %h is the short git hash (%H will show the full hash with 40 chars)
  • %cs is the short date (%cI will show the time too as 2021-08-21T06:53:01-04:00)
  • %s shows the subject of the commit message

This isn’t an exhaustive list of everything git shortlog can do but it covers a decent combination of flags to answer a few common questions. You can run git shortlog --help to see every flag and what they do.

Visualizations with GitHub and GitLab

If you’re using GitHub you can see a graphical representation of committers, such as https://github.com/pallets/flask/graphs/contributors. From here you can kind of eyeball the graphs of the top committers to see who is actively working on a project the most.

GitLab has something similar with https://gitlab.com/gitlab-org/gitlab/-/graphs/master.

Even with both of these pages existing I still find myself using git shortlog on the command line to find out more specific information.

Demo Video

Timestamps

  • 0:24 – This can be useful for a few use cases
  • 1:50 – Running git shortlog to see info about all committers in a branch
  • 2:17 – The all flag runs it against all branches
  • 3:11 – Showing only non-merge commits
  • 3:37 – Showing only merge commits (typically PRs)
  • 4:15 – Only showing the commit author and count with a summary
  • 4:58 – Filtering the output by author
  • 5:17 – Filtering by date using the before and since flags
  • 8:03 – Showing a custom format with the date, git hash and commit message
  • 9:34 – Visualizing contributor stats on GitHub and GitLab
  • 10:19 – I still use the command line for quickly finding these stats

What are your favorite git shortlog command combos? Let me know below!

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments