gitでnumstatを利用して総追加行数、総削除行数を取得するワンライナー
上期も終わり開発中のgitリポジトリの情報を採取して遊んでいました。Qiitaでコミット数や総追加行数、総削除行数を取得するワンライナーについての投稿があり活用させて頂いています。ありがたい...!
リンク先のワンライナーでコミット数は正確に計れるのですが、総追加行数と総削除行数がなにかおかしい。なぜか総追加行数が非常に多く計算されていました。
というわけで原因を調べてみました。
原因1. 1ファイルのみの変更の時にgrepがスルーされる
1ファイルのみの変更の場合、以下のような出力になります。
$ git log --shortstat --oneline --no-merges f86f749 Insert open graph meta tag contents when adding a link item refs #29 1 file changed, 67 insertions(+), 33 deletions(-)
grep filesやるとどうやらひっかからないみたいです。
原因2. gitのshortstatでinsertionsやdeletionsが省略されていた
どうも--shortstat
オプションを使用する場合、insertionsやdeletionsが0の場合に省略されるようです。
commit 4083c7554d996e1ee0199c9ab44d9352a14e1d3e Author: 私 Date: Fri Aug 22 08:10:12 2014 +0900 Set item description's default value refs #34 1 file changed, 6 insertions(+)
なのでどうやらQiitaに投稿されていらっしゃるお方のワンライナーでは、insertionsが0(省略される)、deletionsがあった場合にもinsertionsとしてカウントされるようです。畜生shortstat。
numstatを使うとうまくいくらしい
というわけでどうすれば上手くいくのか調べると、--numstat
オプションを使うといいという情報がでてきました。
例:git log --numstat
Author: 私 Date: Fri Sep 26 02:06:03 2014 +0900 Remove duplicate gem refs #11 0 1 Gemfile
1番目の数値が追加行数、2番目の数値が削除行数です。0のときも省略されず出力されているのが確認できます。
numstatを使ったワンライナー
stackoverflowにnumstatを使用したワンライナーがありました。
$ git log --numstat --pretty="%H" | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'
How can I calculate the number of lines changed between two commits in git? - Stack Overflow
試しにgithubで開発している自分のレポジトリでやってみると...
$ git log --numstat --pretty="%H" | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}' +6339, -380
合ってる!勝利!
コミッターや期間を指定したい場合は--author
、--since
、--until
オプションを使えばokですね。
ワンライナー解説
awkについて全く知らない私なので有識者にワンライナーの解説をして頂きました。
$ git log --numstat --pretty="%H" | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}' よかろう。 NFはフィールドの数を示す定数だ。 なので、NF==3のときだけ、波括弧内が実行される awkの変数には $ をつけないので、 plus, minus はそれぞれ変数名。 $1, $2は1番目、2番目のフィールドをそれぞれ指す。 ちなみに、$3で3番目、$NFで最終フィールドなどということもできる。 これでnumstatしたときに出てくる、 1 3 foo/bar.c みたいな行を拾ってそれぞれ加えていくわけ。 続く、ENDは入力が尽きたあと(つまり最後)に条件が成立して、printfを実行する。 printfはC言語とかとだいたい同じだから、整形して出力するだけだな。
わかりやすすぎわろた。ありがとうございます有識者の方!お金絶対返します!