How can I calculate the number of lines changed between two commits in Git?
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 c开发者_开发百科ommits in the line counts.
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)
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
For the lazy, use git log --stat
.
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
.
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.
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
.
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(-)
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
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(-)
git log --numstat
just gives you only the numbers
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
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
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.
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)}'
精彩评论