Is there a way of having git show lines added, lines changed and lines removed?
GitGit Problem Overview
"git diff --stat" and "git log --stat" show output like:
$ git diff -C --stat HEAD c9af3e6136e8aec1f79368c2a6164e56bf7a7e07
app/controllers/application_controller.rb | 34 +++-------------------------
1 files changed, 4 insertions(+), 30 deletions(-)
But what really happened in that commit was that 4 lines were changed and 26 lines were deleted which is different than adding 4 lines and deleting 30.
Is there any way of getting the delta LOCs (26 in this case)? I don't really care about differentiating between lines added or removed.
Git Solutions
Solution 1 - Git
You can use:
git diff --numstat
to get numerical diff information.
As far as separating modification from an add and remove pair, --word-diff
might help. You could try something like this:
MOD_PATTERN='^.+(\[-|\{\+).*$' \
ADD_PATTERN='^\{\+.*\+\}$' \
REM_PATTERN='^\[-.*-\]$' \
git diff --word-diff --unified=0 | sed -nr \
-e "s/$MOD_PATTERN/modified/p" \
-e "s/$ADD_PATTERN/added/p" \
-e "s/$REM_PATTERN/removed/p" \
| sort | uniq -c
It's a little long-winded so you may want to parse it in your own script instead.
Solution 2 - Git
-
If you want to know the lines added/changed/deleted by a commit with id
commit-id
, you could usegit show commit-id --stat
or
git diff commit-id-before commit-id --stat
-
If you wat to know the lines added/changed/deleted by a range commits, you could use
git diff commit-id1 commit-id2 --stat
-
If you want to know the lines added/changed/deleted by each commit, you could use
git log --stat
Solution 3 - Git
You could use diffstat
to show the number of modified lines. For example:
git diff HEAD c9af3e6136e8 | diffstat -Cm
The -C
option is for getting colorized output; the -m
option is for showing the number of modified lines. Sample output:
app/controllers/application_controller.rb | 30 -------------------!!!
1 files changed, 0 insertions(+), 26 deletions(-), 4 modifications(!)
Note that the number of lines in each category (insertions, deletions, modifications) is only approximate, as man diffstat
says:
> -m merge insert/delete counts from each "chunk" of the patch file to approximate a count of the modified lines.
diffstat
has a missing feature when compared to git diff --stat
: diffstat
is incapable of showing file moves/renames (e.g. app/{a.rb => b.rb}
), unlike git diff --stat
which is capable of showing this information by using the -M
(--find-renames
) option or by setting diff.renames
in the git configuration file (refer to man git-config
).
Solution 4 - Git
If all of your files are staged for commit, to see the --numstat
go like this:
git diff --numstat --cached
example output
32 32 project.pbxproj
> --numstat
[...] shows number of added and deleted lines
Solution 5 - Git
git uses "unified" diff, which only has added and deleted lines, as the diff format. You have to do something external to get a diff that shows add, delete, and change information.
https://wiki.postgresql.org/wiki/Working_with_Git#Context_diffs_with_Git gives links to a script that allows running regular old "diff" - and from that you can generate a "context" diff output. Context diff does show added, removed, and changed lines, which should allow you to get the data you want.