1. ホーム
  2. ギット

[解決済み】Git Blame コミットの統計情報

2022-04-12 07:27:44

質問

blame(またはもっと適切な機能、および/またはシェルコマンドとの組み合わせ)を悪用して、各コミッターから現在リポジトリにどれだけの行(のコード)があるか統計を取るにはどうしたらよいでしょうか?

出力例です。

Committer 1: 8046 Lines
Committer 2: 4378 Lines

解決方法は?

更新情報

git ls-tree -r -z --name-only HEAD -- */*.c  | sed 's/^/.\//' | xargs -0 -n1 git blame \
--line-porcelain HEAD |grep -ae "^author "|sort|uniq -c|sort -nr

途中、いくつか更新しました。

便宜上、これを独立したコマンドにすることもできます。

#!/bin/bash

# save as i.e.: git-authors and set the executable flag
git ls-tree -r -z --name-only HEAD -- $1 | sed 's/^/.\//' | xargs -0 -n1 git blame \
 --line-porcelain HEAD |grep -ae "^author "|sort|uniq -c|sort -nr

これをパスのどこかに保存するか、パスを変更して次のように使用します。

  • git authors '*/*.c' # look for all files recursively ending in .c
  • git authors '*/*.[ch]' # look for all files recursively ending in .c or .h
  • git authors 'Makefile' # just count lines of authors in the Makefile

オリジナル回答

この回答は適切なものですが、非常に時間がかかります。

$ git ls-tree --name-only -z -r HEAD|egrep -z -Z -E '\.(cc|h|cpp|hpp|c|txt)$' \
  |xargs -0 -n1 git blame --line-porcelain|grep "^author "|sort|uniq -c|sort -nr

は、ほぼ瞬時です。

現在追跡しているファイルの一覧を取得するには

git ls-tree --name-only -r HEAD

このソリューションでは file を使用してファイルタイプを決定し、パフォーマンス上の理由から希望する拡張子にマッチするように grep を使用します。すべてのファイルを含める場合は、この行を削除してください。

grep -E '\.(cc|h|cpp|hpp|c)$' # for C/C++ files
grep -E '\.py$'               # for Python files

ファイルにスペースが含まれている場合、使用できるシェルに悪い影響を与えます。

git ls-tree -z --name-only -r HEAD | egrep -Z -z '\.py'|xargs -0 ... # passes newlines as '\0'

xargs を使ってコマンドを呼び出したり、引数を分散させたりすることができます。複数のファイルを処理できるようにするコマンドは -n1 . この場合 git blame --line-porcelain で、呼び出しごとにちょうど1つの引数を使用します。

xargs -n1 git blame --line-porcelain

次に、quot;author の出現をフィルタリングして、リストをソートし、重複する行を数えることにします。

grep "^author "|sort|uniq -c|sort -nr

備考

他の回答では、実際に空白文字だけを含む行をフィルタリングしています。

grep -Pzo "author [^\n]*\n([^\n]*\n){10}[\w]*[^\w]"|grep "author "

上記のコマンドは、少なくとも1つの非空白文字を含む行の作者を表示します。また、match \w*[^\w#] でない行を除外することもできます。 # (多くのスクリプト言語でのコメント)。