How can I calculate the number of lines changed between two commits in Git?
Asked Answered
T

17

1129

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.

Terryn answered 27/3, 2010 at 4:2 Comment(0)
S
1558

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)

Scorpius answered 27/3, 2010 at 4:14 Comment(11)
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.Subjoin
@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.Scorpius
git diff --shortstat <commit1> <commit2> was the one I wanted.Showmanship
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:00Spoliation
Does these numbers include lines deleted as a result of deleting a file?Falster
You can filter the file types by inserting -- *.m *.h *.java before the | awk part. I found this handy for only counting actual code file changes.Calle
@Karl: Yes it does. If a file was deleted with 300 lines, then it will show 300 lines removed.Bega
@Jefromi what is the difference between git diff --stat <commit-ish> <commit-ish> and git log --stat <commit-ish> <commit-ish>? I get that the first one is giving the difference between the range of the 2 commits, but what the other does?Photocopier
@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 #23304049Scorpius
Get number of lines for changed and not committed files: git diff --statMeneses
git diff --shortstat HEAD~1 HEAD did what I needed, thank you @ShowmanshipBriefcase
F
396
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
Forelli answered 23/12, 2016 at 21:17 Comment(6)
Cool! but.. be aware that this only works with unstaged changesGollin
If you've staged changes with git add, make sure to do git diff --shortstat --cachedJetport
2463 files changed, 39745 insertions(+), 21383 deletions(-) I've actually deleted around 5k to 10k in the last month. It's nearly all I've been doing apart from moving things around. Something is wrong. It doesn't include removed files or something?Ganda
@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(-).Iz
shortstats doesn't show the number of lines, but the number of characters!Stambaugh
@Stambaugh According to the docs, --shortstat shows lines, not characters: git-scm.com/docs/git-diff#Documentation/…Timotheus
T
263

For the lazy, use git log --stat.

Tankersley answered 26/10, 2014 at 21:59 Comment(2)
I found this useful, added a -10 to show the previous ten commits.Endarch
When you are finished viewing commit history, type Q to return to the terminal.Cormophyte
M
60
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.

Myelencephalon answered 27/3, 2010 at 4:14 Comment(5)
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.)Scorpius
The output of this is nothing for me.Terryn
@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.Scorpius
or if uncommited git diff --stat HEADBlondell
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.Grandeur
I
45

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.

Incompatible answered 9/7, 2021 at 10:37 Comment(0)
S
27

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.

Slosberg answered 21/5, 2020 at 23:8 Comment(3)
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>".Waylonwayman
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(-)\"}' #"Linearity
If you name the script git-summary and it's in your path, you can call it as git summary without the alias.Aglet
M
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(-)

Misguided answered 29/12, 2021 at 13:19 Comment(0)
S
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(-)
Slovak answered 27/3, 2010 at 4:21 Comment(7)
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).Terryn
This happened to me too. The two commits were in the wrong order, swapping them around fixed it.Leisure
Updated the commit order and clarified what the two SHAs represent. Thanks for catching it :)Slovak
The --shortstat flag is awesome, it works with git diff though (not git log).Macilroy
How to summarize them?Ricardoricca
Is there way to get a total for all commits?Backstitch
The first commit in the command must be the oldest one, and the second one must be the newest commit in order for the command to show the correct output. I've also just used git log HEAD~10..HEAD --oneline --shortstat --author="Mike Surname" and got the correct output, and it seems a little simpler to use, it will scan the last 10 commits in this case and output the summary for the commits where the author is the one you mention.Shive
R
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
Rossman answered 17/3, 2017 at 7:58 Comment(0)
F
11
git log --numstat 

just gives you only the numbers

Feltner answered 8/2, 2019 at 5:34 Comment(0)
M
7

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

git diff --shortstat HEAD
Malarkey answered 15/5, 2023 at 10:4 Comment(0)
W
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
Weatherboarding answered 3/8, 2020 at 16:9 Comment(0)
B
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

Beget answered 16/11, 2018 at 13:29 Comment(1)
This gives "'tail' is not recognized as an internal or external command, operable program or batch file."Kurtz
D
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

Dunlap answered 31/1, 2023 at 23:33 Comment(0)
O
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.

Oarfish answered 29/9, 2022 at 1:25 Comment(0)
A
1

This command will compare local files with remote files

git diff --stat
Ahlgren answered 17/1, 2023 at 7:59 Comment(0)
D
-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.

Dynah answered 20/8, 2020 at 8:58 Comment(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.Dynah

© 2022 - 2024 — McMap. All rights reserved.