5

Is there a command to get just total number of lines that are changed in current git repo. I want to take count considering both staged and unstaged files.

This is the closest I could get

$ git diff --cached --shortstat
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git diff --shortstat
 1 file changed, 1 insertion(+)

But I have to execute two commands and then parse (quite error prone, you never know all cases) result to find number of lines that have changed.

If not a git command, a bash/zsh function would also do.

UPDATE:

So the idea was to track total uncommitted lines (showing approximate level of dirtiness of a git working directory) on my ZSH prompt, Something like:

[~/dotfiles] (master) ✗ [192]
$ ...

So thanks to @arco444's answer, which I slightly modified, I now have following, just if someone wants to achieve the same

function git_change_count {
    local IS_INSIDE_REPO=$(git rev-parse --is-inside-work-tree 2>/dev/null)
    if [[ $IS_INSIDE_REPO == "true" ]]; then
        { git diff --cached --numstat; git diff --numstat; } | awk '{ a+=($1+$2) } END {print a}'
    fi
}

I am adding the lines that were added and deleted lines, instead of getting their diff. Which essentially means edited lines shows up as 2 but doing so covers the scenario when two different lines were added and deleted and because of subtraction we get 0 as result.

kdabir
  • 9,623
  • 3
  • 43
  • 45
  • Those two commands will double-count lines that have changed in both locations. This seems like a strange thing to want to do to me. What's the ultimate goal here? – Etan Reisner Nov 05 '15 at 13:15
  • @EtanReisner The idea is capture 'dirtiness' of given git working directory. It does not have to be precise. I'm okay if a line, that is staged is counted twice if it is changed again in unstaged version. – kdabir Nov 06 '15 at 05:49
  • @kunal I like this, how did you add the function to show in the prompt top line? – Ziv Nov 17 '19 at 16:53
  • @Ziv just call the function in the prompt variable like `PROMPT='....$(git_change_count)...'`. New lines in `PROMPT` string are preserved and so you get new line on prompt. – kdabir Nov 18 '19 at 17:33

2 Answers2

10

How about:

{ git diff --cached --numstat; git diff --numstat; } | awk '{ a+=($1-$2) } END {print a}'

The --numstat flag gives you:

#added #deleted #filename

You need to run it for both staged and unstaged files, then pipe to awk to do the arithmetic. It will return a sum of added and deleted lines, so you will get a negative result if more lines were removed than added.

arco444
  • 22,002
  • 12
  • 63
  • 67
3

Try this:

git diff --numstat |  cut -d$'\t' -f 1 | paste -sd+ - | bc

Here the git diff --numstat provides the number of additions and substractions for each file (separated by tabs). The cut command splits the fields by tabs, selecting the first field (additions). The paste command creates an addition from the column of numbers and the bc command performs the sum. The above is for additions. You can do subtraction by replacing the -f 1 with -f 2. If you want additions and subtractions, try:

git diff --numstat |  cut -d$'\t' -f 1,2 | tr '\t' '+' | paste -sd+ -  | bc

which just uses tr to insert addition signs on every row before using paste

houtanb
  • 3,852
  • 20
  • 21