Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@eyecatchup
Last active April 12, 2024 14:50
Show Gist options
  • Save eyecatchup/3fb7ef0c0cbdb72412fc to your computer and use it in GitHub Desktop.
Save eyecatchup/3fb7ef0c0cbdb72412fc to your computer and use it in GitHub Desktop.
Some commands to get git commit log statistics for a repository on the command line.

git commit stats

Commands to get commit statistics for a Git repository from the command line -
using git log, git shortlog and friends.




List repository contributors by author name (sorted by name):

$ git log --format='%aN' | sort -u 

Example output:

Jane Bar
John Foo
Steve Baz



List total commits by author (sorted by commit count):

$ git shortlog -sn

Example output:

136 Jane Bar
 41 John Foo
 17 Steve Baz

Ignore merge commits:

$ git shortlog -sn --no-merges

Example output:

121 Jane Bar
 36 John Foo
 14 Steve Baz

Even though the --no-merges option is not documented for git shortlog, it works exactly as defined for git log.




List file change stats by author:

$ git log --author="Vorname Nachname" --pretty=tformat: --numstat | awk '{inserted+=$1; deleted+=$2; delta+=$1-$2; ratio=deleted/inserted} END {printf "Commit stats:\n- Lines added (total)....  %s\n- Lines deleted (total)..  %s\n- Total lines (delta)....  %s\n- Add./Del. ratio (1:n)..  1 : %s\n", inserted, deleted, delta, ratio }' -

Example output:

Commit stats:
- Lines added (total)....  4625
- Lines deleted (total)..  836
- Total lines (delta)....  3789
- Add./Del. ratio (1:n)..  1 : 0.180757

Include file count:

$ git log --shortstat --author="Vorname Nachname" | grep -E "fil(e|es) changed" | awk '{files+=$1; inserted+=$4; deleted+=$6; delta+=$4-$6; ratio=deleted/inserted} END {printf "Commit stats:\n- Files changed (total)..  %s\n- Lines added (total)....  %s\n- Lines deleted (total)..  %s\n- Total lines (delta)....  %s\n- Add./Del. ratio (1:n)..  1 : %s\n", files, inserted, deleted, delta, ratio }' -

Example output:

Commit stats:
- Files changed (total)..  439
- Lines added (total)....  4625
- Lines deleted (total)..  836
- Total lines (delta)....  3789
- Add./Del. ratio (1:n)..  1 : 0.180757

Ignore merge commits:

Note: Both commands above also count merge commits. But to ignore them, one can simply use the --no-merges option again:

$ git log --author="Vorname Nachname" --pretty=tformat: --numstat --since="1 Jan, 2015" | awk ...
# or
$ git log --shortstat --author="Vorname Nachname" --since="1 Jan, 2015" | grep -E ...

Filter stats by date:

You can filter the output of the above commands, for example, by adding --until or --since or --before:

$ git log --author="Vorname Nachname" --pretty=tformat: --numstat --since="1 Jan, 2015" | awk ...
# or
$ git log --shortstat --author="Vorname Nachname" --since="1 Jan, 2015" | grep -E ...






@stevenirby
Copy link

stevenirby commented May 31, 2017

You can also skip the name bit and pull it from your config.

git log --shortstat --author="$(git config user.name)" | grep -E "fil(e|es) changed" | awk '{files+=$1; inserted+=$4; deleted+=$6; delta+=$4-$6; ratio=deleted/inserted} END {printf "Commit stats:\n- Files changed (total)..  %s\n- Lines added (total)....  %s\n- Lines deleted (total)..  %s\n- Total lines (delta)....  %s\n- Add./Del. ratio (1:n)..  1 : %s\n", files, inserted, deleted, delta, ratio }' -

$(git config user.name)

@Bird87ZA
Copy link

How would I print something like this to a file for a whole git project?

Date; Author; Commit Message; Additions; Deletions; Ratio;

@OtiZ2
Copy link

OtiZ2 commented Mar 5, 2018

If i want add this command as alias, there is problem, could you help me?

st = log --shortstat --author="$(git config user.name)" | grep -E "fil(e|es) changed" | awk '{files+=$1; inserted+=$4; deleted+=$6; delta+=$4-$6; ratio=deleted/inserted} END {printf "Commit stats:\n- Files changed (total).. %s\n- Lines added (total).... %s\n- Lines deleted (total).. %s\n- Total lines (delta).... %s\n- Add./Del. ratio (1:n).. 1 : %s\n", files, inserted, deleted, delta, ratio }'
`
juraj@OtiZ-PC MINGW64 /c/wamp64/www
$ git st
fatal: Bad alias.st string: unclosed quote
juraj@OtiZ-PC MINGW64 /c/wamp64/www
$

`

@glebmtb
Copy link

glebmtb commented Sep 13, 2018

#!/usr/bin/env bash
from="1 Jun, 2018"
to="17 Aug, 2018"
users=$(git shortlog -sn --no-merges --since="$from" --before="$to" | awk '{printf "%s %s\n", $2, $3}')
IFS=$'\n'
echo -e "User name;Files changed;Lines added;Lines deleted;Total lines (delta);Add./Del. ratio (1:n);Commit count"

for userName in $users
do
     result=$(git log --author="$userName" --no-merges --shortstat  --since="$from" --before="$to" | grep -E "fil(e|es) changed" | awk '{files+=$1; inserted+=$4; deleted+=$6; delta+=$4-$6; ratio=deleted/inserted} END {printf "%s;%s;%s;%s;%s", files, inserted, deleted, delta, ratio }' -)
     countCommits=$(git shortlog -sn --no-merges  --since="$from" --before="$to" --author="$userName" | awk '{print $1}')
     if [[ ${result} != ';;;;' ]]
     then
        echo -e "$userName;$result;$countCommits"
     fi
done

sh script for print all users by date

@ifehrim
Copy link

ifehrim commented Sep 30, 2018

its good

@arzzen
Copy link

arzzen commented Sep 17, 2019

hi, i am creator of this cli tool https://github.com/arzzen/git-quick-stats
"Git quick statistics" is a simple and efficient way to access various statistics in git repository.

@tamirs9876
Copy link

tamirs9876 commented Nov 1, 2020

For "List file change stats by author" it's better calc ratio at the end. If first commit has 0 inserted lines it will fail for divide by zero.
Consider the following:

git log --author="Tamir Shlomi" --pretty=tformat: --numstat | awk '{inserted+=$1; deleted+=$2; delta+=$1-$2} END {printf "Commit stats:\n- Lines added (total)....  %s\n- Lines deleted (total)..  %s\n- Total lines (delta)....  %s\n- Add./Del. ratio (1:n)..  1 : %s\n", inserted, deleted, delta, deleted/inserted }'

@kaustubh77
Copy link

kaustubh77 commented Jan 28, 2021

Is there a way to get a list of authors who have contributed to a particular file and also the number of lines each one of them have in the latest version of the file? @arzzen @glebmtb @eyecatchup

@patrickdevivo
Copy link

I wanted to suggest an additional option through a tool called mergestat to also display some of these stats (full disclosure, I'm the creator/maintainer), via a SQL interface.

For example, a SQL query like the following will show commit stats by author, similar to the List file change stats by author section above.

SELECT
    author_name,
    author_email,
    count(*) AS commit_count,
    count(DISTINCT file_path) AS files_changed,
    sum(additions) AS total_additions,
    sum(deletions) AS total_deletions,
    sum(additions - deletions) AS delta,
    round(avg(deletions/additions), 2) AS avg_ratio
FROM commits, stats('', commits.hash)
GROUP BY author_name, author_email
ORDER BY commit_count DESC

It can be amended to filter out merge commits or to limit the date range via WHERE clause conditions:

SELECT
    (...)
FROM commits, stats('', commits.hash)
WHERE
    parents < 2 -- ignore merge commits
    AND author_when > date('now', '-90 days') -- only look at commits made in the past 90 days
GROUP BY author_name, author_email
ORDER BY commit_count DESC
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| AUTHOR_NAME | AUTHOR_EMAIL | COMMIT_COUNT | FILES_CHANGED | TOTAL_ADDITIONS | TOTAL_DELETIONS | DELTA  | AVG_RATIO |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 732          | 264           | 26705           | 17245           | 9460   | 1.2       |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 140          | 84            | 251393          | 6863            | 244530 | 0.3       |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 85           | 32            | 2201            | 676             | 1525   | 2.1       |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 29           | 23            | 2752            | 144             | 2608   | 0.72      |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 26           | 25            | 506             | 12              | 494    | 0.04      |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 15           | 12            | 980             | 17              | 963    | 0.07      |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 5            | 5             | 15              | 15              | 0      | 1         |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 4            | 3             | 378             | 47              | 331    | 0         |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+
| <removed>   | <removed>    | 1            | 1             | 1               | 1               | 0      | 1         |
+-------------+--------------+--------------+---------------+-----------------+-----------------+--------+-----------+

There are some other tables available as well, and since the input is just SQL, it's fairly flexible to tailor a query to meet specifically what you're looking for (break out by file name, filter out certain authors, etc)

@gonsolo
Copy link

gonsolo commented Aug 5, 2022

For "List file change stats by author" it's better calc ratio at the end. If first commit has 0 inserted lines it will fail for divide by zero. Consider the following:

Yes, that's better, otherwise I get a
"awk: cmd. line:1: (FILENAME=- FNR=1) fatal: division by zero attempted"

@scottctr
Copy link

Is there a simple way to get the same results as 'git log stats' but leave out all the comments? I need the lines added and deleted, but not the comments and our repos are old with a lot of commits and some of the comments are absolutely massive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment