Gitのリポジトリにて、ファイル毎の大まかなコミット数を手軽にカウントできないか試してみたところ、一応は下記コマンド(カウント数の多い順で出力する場合)で実現できました。
ただし、リネームによる変更前後のファイル名の組み合わせもカウント対象となります。
ファイル毎のコミット数カウント
git whatchanged --oneline | sed '/^[^:]/d' | cut -f 2-3 | sort | uniq -c | sort -r
更にコミットメッセージをカウント対象としても良いのなら、次のように簡略化できます。
ファイル毎のコミット数カウント簡易版
git whatchanged --oneline | cut -f 2-3 | sort | uniq -c | sort -r
処理内容
まず、git whatchanged
コマンドでコミットとそのコミットで変更したファイルの情報が出力され、--oneline
オプションを指定する事でコミットの情報部分が 1行になります。
出力内容から本件で必要な部分に着目すると、次のような特徴が見られます。
- 先頭文字が
:
で始まる行に変更のあったファイル名が記載される - ファイル名はタブ(
\t
)で区切られる
例えば、実際の出力結果はこのようになります。1
git whatchanged 出力結果例
$ git whatchanged --oneline
38aa697 (HEAD -> main) step5
:100644 100644 1483170 ed634ec M a.txt
:000000 100644 0000000 4bcfe98 A d.txt
157dbbc step4
:100644 100644 c1f7537 1483170 M a.txt
:100644 000000 3410062 0000000 D c.txt
:100644 100644 a510a94 6178079 M sub/b1.txt
04d0c8e step3
:100644 100644 a510a94 a510a94 R100 b.txt sub/b1.txt
6350ca5 step2
:100644 100644 7898192 c1f7537 M a.txt
:100644 100644 6178079 a510a94 M b.txt
:000000 100644 0000000 3410062 A c.txt
d6c1f16 step1
:000000 100644 0000000 7898192 A a.txt
:000000 100644 0000000 6178079 A b.txt
そこで、このような出力を下記の手順で処理するのが前述のコマンドです。
- 先頭文字が
:
以外の行を削除 - タブで区切った 2つ目と 3つ目の要素を取得2
- ソートして同一行をカウント
- カウント数の多い順にソート
出力例
実際の出力結果はこのようになります。
出力例1
$ git whatchanged --oneline | sed '/^[^:]/d' | cut -f 2-3 | sort | uniq -c | sort -r
4 a.txt
2 c.txt
2 b.txt
1 sub/b1.txt
1 d.txt
1 b.txt sub/b1.txt
簡易版だとこうなります。
出力例2
$ git whatchanged --oneline | cut -f 2-3 | sort | uniq -c | sort -r
4 a.txt
2 c.txt
2 b.txt
1 sub/b1.txt
1 d6c1f16 step1
1 d.txt
1 b.txt sub/b1.txt
1 6350ca5 step2
1 38aa697 step5
1 157dbbc step4
1 04d0c8e step3
最後に、https://github.com/git/git
へ適用してみるとこのようになりました。
出力例3
$ git clone https://github.com/git/git
$ cd git
$ git whatchanged --oneline | cut -f 2-3 | sort | uniq -c | sort -r | head
2166 Makefile
1471 cache.h
1132 diff.c
956 refs.c
912 Documentation/config.txt
822 contrib/completion/git-completion.bash
811 GIT-VERSION-GEN
740 sha1_file.c
714 revision.c
705 gitweb/gitweb.perl