1143

Is there any easy way to calculate the number of lines changed between two commits in Git?

I know I can do a git diff, and count the lines, but this seems tedious. I'd also like to know how I can do this, including only my own commits in the line counts.

0

17 Answers 17

1571

You want the --stat option of git diff, or if you're looking to parse this in a script, the --numstat option.

git diff --stat <commit-ish> <commit-ish>

--stat produces the human-readable output you're used to seeing after merges; --numstat produces a nice table layout that scripts can easily interpret.

I somehow missed that you were looking to do this on multiple commits at the same time - that's a task for git log. Ron DeVera touches on this, but you can actually do a lot more than what he mentions. Since git log internally calls the diff machinery in order to print requested information, you can give it any of the diff stat options - not just --shortstat. What you likely want to use is:

git log --author="Your name" --stat <commit1>..<commit2>

but you can use --numstat or --shortstat as well. git log can also select commits in a variety other ways - have a look at the documentation. You might be interested in things like --since (rather than specifying commit ranges, just select commits since last week) and --no-merges (merge commits don't actually introduce changes), as well as the pretty output options (--pretty=oneline, short, medium, full...).

Here's a one-liner to get total changes instead of per-commit changes from git log (change the commit selection options as desired - this is commits by you, from commit1 to commit2):

git log --numstat --pretty="%H" --author="Your Name" commit1..commit2 | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'

(you have to let git log print some identifying information about the commit; I arbitrarily chose the hash, then used awk to only pick out the lines with three fields, which are the ones with the stat information)

11
  • 9
    This does not answer to the original question about "changed lines". One line change is calculated as both inserted and deleted line. Calculating number of changed lines needs more work than described here. Commented Jan 26, 2012 at 9:52
  • 19
    @VilleLaitila: This is as close as you can get without an absurd amount of effort, and it was good enough for the OP and 15 others. (How do you define when a changed line becomes an added line and a deleted line? By edit distance between the - and + line, as a fraction of line length?) We all know that changes get doubled; we can just call that a useful metric of amount of change, and move on with our lives.
    – Cascabel
    Commented Jan 26, 2012 at 14:23
  • 323
    git diff --shortstat <commit1> <commit2> was the one I wanted.
    – Kim
    Commented Oct 24, 2012 at 9:20
  • 14
    For reference, the date format for --since and --until is something like: yesterday, 1 month 2 weeks 3 days 1 hour 1 second ago, or 1979-02-26 18:30:00 Commented Apr 1, 2013 at 8:01
  • 5
    @Bryson Yes, that's why that line says <commit-ish> - it works with anything that represents a commit, including literal commits, branches, tags, and refs in general. See also stackoverflow.com/questions/23303549/…
    – Cascabel
    Commented Mar 3, 2017 at 21:35
404
git diff --shortstat

gives you just the number of lines changed and added. This only works with unstaged changes. To compare against a branch:

git diff --shortstat some-branch
6
  • 6
    Cool! but.. be aware that this only works with unstaged changes
    – TomCobo
    Commented Nov 16, 2018 at 12:02
  • 22
    If you've staged changes with git add, make sure to do git diff --shortstat --cached
    – TomNash
    Commented Jul 31, 2019 at 20:12
  • 2
    @jgmjgm, try using git merge-base as part of your command. You probably just have a newer master branch than what your feature_branch was originally based on, is all, so you need to do git diff against the old base upon which your feature branch was based. That can be found with git merge-base, like this: sample command: git diff --shortstat $(git merge-base HEAD master) HEAD. Sample output: 13 files changed, 955 insertions(+), 3 deletions(-). Good. That's correct. This: git diff --shortstat master, however, shows: 1643 files changed, 114890 insertions(+), 16943 deletions(-). Commented Aug 24, 2020 at 23:36
  • 2
    shortstats doesn't show the number of lines, but the number of characters!
    – JHBonarius
    Commented Feb 21, 2021 at 9:39
  • 4
    @JHBonarius According to the docs, --shortstat shows lines, not characters: git-scm.com/docs/git-diff#Documentation/… Commented Apr 15, 2022 at 13:47
265
+500

For the lazy, use git log --stat.

2
  • 23
    I found this useful, added a -10 to show the previous ten commits. Commented Aug 26, 2016 at 22:39
  • 8
    When you are finished viewing commit history, type Q to return to the terminal.
    – Stevoisiak
    Commented May 18, 2018 at 14:31
61
git diff --stat commit1 commit2

EDIT: You have to specify the commits as well (without parameters it compares the working directory against the index). E.g.

git diff --stat HEAD^ HEAD

to compare the parent of HEAD with HEAD.

5
  • 1
    There's never really any need to use diff-index - the diff frontend can handle everything; the case of diff-index is covered by the --cached/--staged, I believe. (And there's no way to use diff-index to compare two arbitrary commits as the OP asked.)
    – Cascabel
    Commented Mar 27, 2010 at 4:17
  • The output of this is nothing for me.
    – Mike
    Commented Mar 27, 2010 at 4:47
  • @Mike: Did you leave off a carat? Was your most recent commit a merge commit? If git says there's no diff, it's because there's no diff.
    – Cascabel
    Commented Mar 27, 2010 at 6:46
  • 10
    or if uncommited git diff --stat HEAD Commented Mar 23, 2016 at 16:47
  • 1
    Also, you can compare further back than just the parent by using HEAD~n, where n is how far you want to go back. git diff --stat HEAD~5 HEAD will show combined stats for the last 5 commits relative to HEAD. Commented Jul 9, 2019 at 20:48
47

Short statistics about the last commit :

git diff --shortstat HEAD~1 HEAD

In my case, this gives me the following information:

 254 files changed, 37 insertions(+), 10773 deletions(-)

Insertions and deletions are affected lines.

28

I just solved this problem for myself, so I'll share what I came up with. Here's the end result:

> git summary --since=yesterday
total: 114 file changes, 13800 insertions(+) 638 deletions(-)

The underlying command looks like this:

git log --numstat --format="" "$@" | awk '{files += 1}{ins += $1}{del += $2} END{print "total: "files" files, "ins" insertions(+) "del" deletions(-)"}'

Note the $@ in the log command to pass on your arguments such as --author="Brian" or --since=yesterday.

Escaping the awk to put it into a git alias was messy, so instead, I put it into an executable script on my path (~/bin/git-stat-sum), then used the script in the alias in my .gitconfig:

[alias]
    summary = !git-stat-sum \"$@\"

And it works really well. One last thing to note is that file changes is the number of changes to files, not the number of unique files changed. That's what I was looking for, but it may not be what you expect.

Here's another example or two

git summary --author=brian
git summary master..dev
# combine them as you like
git summary --author=brian master..dev
git summary --all

Really, you should be able to replace any git log command with git summary.

3
  • 2
    It should be the accepted answer as it is the only one that actually answer it : make a sum to show the total lines changed. Other responses show total for each line or each commit but do not summarize them. You should just improve it by replacing "$@" with "<commit1>..<commit2>".
    – bN_
    Commented Nov 3, 2020 at 9:26
  • 2
    Here is the command escaped for use in a git alias summary = "!git log --numstat --format=\"\" \"$@\" | awk '{files += 1}{ins += $1}{del += $2} END{print \"total: \"files\" files, \"ins\" insertions(+) \"del\" deletions(-)\"}' #" Commented Apr 6, 2021 at 9:11
  • 2
    If you name the script git-summary and it's in your path, you can call it as git summary without the alias.
    – idbrii
    Commented Oct 6, 2021 at 17:01
21

Good one to summarize the year

git diff --shortstat <first commit number of the year> HEAD

get results 270 files changed, 19175 insertions(+), 1979 deletions(-)

20

Assuming that you want to compare all of your commits between abcd123 (the first commit) and wxyz789 (the last commit), inclusive:

git log wxyz789^..abcd123 --oneline --shortstat --author="Mike Surname"

This gives succinct output like:

abcd123 Made things better
 3 files changed, 14 insertions(+), 159 deletions(-)
wxyz789 Made things more betterer
 26 files changed, 53 insertions(+), 58 deletions(-)
7
  • 1
    The output of this is nothing for me (I've made commits and verified --author is correct by using it with git log and no other arguments).
    – Mike
    Commented Mar 27, 2010 at 4:46
  • This happened to me too. The two commits were in the wrong order, swapping them around fixed it. Commented Jan 8, 2013 at 1:04
  • 1
    Updated the commit order and clarified what the two SHAs represent. Thanks for catching it :)
    – Ron DeVera
    Commented Mar 5, 2014 at 6:01
  • 3
    The --shortstat flag is awesome, it works with git diff though (not git log).
    – lucke84
    Commented May 13, 2015 at 15:38
  • How to summarize them? Commented Jan 31, 2017 at 9:30
19

Another way to get all change log in a specified period of time

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10"

Output:

2637cc736 Revert changed code
 1 file changed, 5 insertions(+), 5 deletions(-)
ba8d29402 Fix review
 2 files changed, 4 insertions(+), 11 deletions(-)

With a long output content, you can export to file for more readable

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10" > /mnt/MyChangeLog.txt
11
git log --numstat 

just gives you only the numbers

10

to get quickly how many files have been changed and lines added, just run.

git diff --shortstat HEAD
5

If you want to see the changes including the # of lines that changed between your branch and another branch,

git diff the_other_branch_name --stat
3

Though all above answers are correct, below one is handy to use if you need count of last many commits

below one is to get count of last 5 commits

git diff $(git log -5 --pretty=format:"%h" | tail -1) --shortstat

to get count of last 10 commits

git diff $(git log -10 --pretty=format:"%h" | tail -1) --shortstat

generic - change N with count of last many commits you need

git diff $(git log -N --pretty=format:"%h" | tail -1) --shortstat

to get count of all commits since start

git diff $(git log --pretty=format:"%h" | tail -1) --shortstat

1
  • This gives "'tail' is not recognized as an internal or external command, operable program or batch file." Commented Nov 29, 2019 at 20:40
2

I wanted to have the insertions and deletions go into the sum, in case someone else needs the same here goes:

# get the log      filter useless parts      calculate the sum    and print it
git log --numstat | grep -vE '^[^0-9]' | awk '{sum += $1 + $2} END {print sum}'

This is not as versatile as some of the other solutions (for example the one undefined posted), but gives just a bare number, which was nice for my use case

1

git diff --stat will double-count modified lines. If this is a problem for you, you can do this instead:

git diff | diffstat -Cm

This will give you the same output, except that it will [try to] differentiate between added+deleted lines and modified lines.

1

This command will compare local files with remote files

git diff --stat
-1

If you want to check the number of insertions, deletions & commits, between two branches or commits.

using commit id's:

git log <commit-id>..<commit-id> --numstat --pretty="%H" --author="<author-name>" | awk 'NF==3 {added+=$1; deleted+=$2} NF==1 {commit++} END {printf("total lines added: +%d\ntotal lines deleted: -%d\ntotal commits: %d\n", added, deleted, commit)}'

using branches:

git log <parent-branch>..<child-branch> --numstat --pretty="%H" --author="<author-name>" | awk 'NF==3 {added+=$1; deleted+=$2} NF==1 {commit++} END {printf("total lines added: +%d\ntotal lines deleted: -%d\ntotal commits: %d\n", added, deleted, commit)}'

Example:

using commit id's:

git log c9344e0be05b8038c244a4e9a531a199b961699c..947d05662b3b418cfaaa576d1e9585912a4e52dc --numstat --pretty="%H" --author="Krishna Chaitanya Surapaneni" | awk 'NF==3 {added+=$1; deleted+=$2} NF==1 {commit++} END {printf("total lines added: +%d\ntotal lines deleted: -%d\ntotal commits: %d\n", added, deleted, commit)}'

output:-

total lines added: +91
total lines deleted: -3
total commits: 7

using branches:

git log main..v3.2.0 --numstat --pretty="%H" --author="Krishna Chaitanya Surapaneni" | awk 'NF==3 {added+=$1; deleted+=$2} NF==1 {commit++} END {printf("total lines added: +%d\ntotal lines deleted: -%d\ntotal commits: %d\n", added, deleted, commit)}'

output:-

total lines added: +23
total lines deleted: -3
total commits: 2

This repo -> https://github.com/kcsurapaneni/food-delivery-backend/tree/main has been used for the example.

1
  • @4n70wa be more specific. It's working for me, may be you missed to replace the <author-name>. You can always share an example by taking any of the open source project, so that I can cross check your claim. Commented Nov 26, 2023 at 16:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.