どのように私は非難(またはいくつかのより適切な関数、および/またはシェルコマンドと組み合わせて)を「悪用」して、各コミッターから発信された(コードの)行数が現在リポジトリーにあるかについての統計を提供できますか?
出力例:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
どのように私は非難(またはいくつかのより適切な関数、および/またはシェルコマンドと組み合わせて)を「悪用」して、各コミッターから発信された(コードの)行数が現在リポジトリーにあるかについての統計を提供できますか?
出力例:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
回答:
git ls-tree -r -z --name-only HEAD -- */*.c | xargs -0 -n1 git blame \
--line-porcelain HEAD |grep "^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 | xargs -0 -n1 git blame \
--line-porcelain HEAD |grep "^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
次に、「author」の発生について出力をフィルタリングし、リストをソートして、重複する行を次のようにカウントします。
grep "^author "|sort|uniq -c|sort -nr
他の回答は、実際には空白のみを含む行を除外します。
grep -Pzo "author [^\n]*\n([^\n]*\n){10}[\w]*[^\w]"|grep "author "
上記のコマンドは、空白以外の文字を少なくとも1つ含む行の作者を出力します。また\w*[^\w#]
、最初の空白以外の文字がaではない行を除外する一致を使用することもできます#
(多くのスクリプト言語のコメント)。
echo "a\nb\nc"|xargs -n1 cmd
に拡張されますcmd a; cmd b; cmd d
git ls-tree --name-only -r HEAD | grep -E '\.(cc|h|m|hpp|c)$' | xargs -n1 git blame --line-porcelain | grep "^author "|sort|uniq -c|sort -nr
役に立つかもしれないgit-fameと呼ばれる宝石を書きました。
インストールと使用法:
$ gem install git_fame
$ cd /path/to/gitdir
$ git fame
出力:
Statistics based on master
Active files: 21
Active lines: 967
Total commits: 109
Note: Files matching MIME type image, binary has been ignored
+----------------+-----+---------+-------+---------------------+
| name | loc | commits | files | distribution (%) |
+----------------+-----+---------+-------+---------------------+
| Linus Oleander | 914 | 106 | 21 | 94.5 / 97.2 / 100.0 |
| f1yegor | 47 | 2 | 7 | 4.9 / 1.8 / 33.3 |
| David Selassie | 6 | 1 | 2 | 0.6 / 0.9 / 9.5 |
+----------------+-----+---------+-------+---------------------+
git ls-tree -r HEAD|sed -re 's/^.{53}//'|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'|while read filename; do git blame -w "$filename"; done|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'|sort|uniq -c
ステップバイステップの説明:
バージョン管理下にあるすべてのファイルを一覧表示します
git ls-tree -r HEAD|sed -re 's/^.{53}//'
リストをテキストファイルのみに切り詰める
|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'
Gitは空白の変更を無視してすべてのテキストファイルを非難します
|while read filename; do git blame -w "$filename"; done
著者名を引き出します
|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'
著者のリストをソートし、uniqに連続して繰り返される行の数をカウントさせる
|sort|uniq -c
出力例:
1334 Maneater
1924 Another guy
37195 Brian Ruby
1482 Anna Lambda
sed
バージョンを持っているようですが、私のものは-r
フラグを理解しておらず、正規表現に問題があります(余剰を削除しても、括弧のバランスが取れていないというメッセージがあり(
ます)。
sudo brew install gnu-sed
それを解決しました。魅力的な作品!
port install gsed
MacPortsユーザーの場合。
sudo brew install gnu-sed
(うまくいった)しましたが、それでもsedが-rを認識しないエラーが発生します。:(
git ls-tree -r HEAD|gsed -re 's/^.{53}//'|while read filename; do file "$filename"; done|grep -E ': .*text'|gsed -r -e 's/: .*//'|while read filename; do git blame -w "$filename"; done|gsed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'|sort|uniq -c
git summary
git-extrasパッケージによって提供されるものがまさに必要なものです。git-extras-git-summaryでドキュメントをチェックアウトしてください:
git summary --line
次のような出力が得られます。
project : TestProject
lines : 13397
authors :
8927 John Doe 66.6%
4447 Jane Smith 33.2%
23 Not Committed Yet 0.2%
Erikのソリューションは素晴らしかったですが、発音区別符号(LC_*
環境変数が表面的には正しく設定されているにもかかわらず)と、実際に日付が含まれているコード行から漏れるノイズに問題がありました。私のsed-fuは貧弱なので、ルビが含まれたこのフランケンシュタインのスニペットになりましたが、200,000以上のLOCで問題なく動作し、結果をソートします。
git ls-tree -r HEAD | gsed -re 's/^.{53}//' | \
while read filename; do file "$filename"; done | \
grep -E ': .*text' | gsed -r -e 's/: .*//' | \
while read filename; do git blame "$filename"; done | \
ruby -ne 'puts $1.strip if $_ =~ /^\w{8} \((.*?)\s*\d{4}-\d{2}-\d{2}/' | \
sort | uniq -c | sort -rg
また、gsed
代わりにsed
、それはバイナリの自作インストールであるため、システムsedをそのままにしておくことに注意してください。
@Alexの回答からの主要なスニペットは、実際に非難行を集約する操作を実行します。私は、ファイルのセットではなく、単一のファイルを操作するためにそれを切り詰めました。
git blame --line-porcelain path/to/file.txt | grep "^author " | sort | uniq -c | sort -nr
私はこれをここに投稿します。なぜなら、私はこの回答に頻繁に戻り、投稿を再度読み、例を再消化して、課税対象とする価値がある部分を抽出するためです。また、私のユースケースでは十分に一般的でもありません。その範囲はCプロジェクト全体です。
私はファイルごとの統計を一覧表示したいのですが、xargsの可読性が低く、使用/記憶が難しいのではfor
なく、bash イテレータを使用して達成しました。xargs xargs
の利点/欠点は、他の場所で説明する必要があります。
以下は、各ファイルの結果を個別に表示する実用的なスニペットです。
for file in $(git ls-files); do \
echo $file; \
git blame --line-porcelain $file \
| grep "^author " | sort | uniq -c | sort -nr; \
echo; \
done
そして私がテストしたところ、bashシェルでこのstrightを実行するとctrl + c安全です。これをbashスクリプト内に配置する必要がある場合、ユーザーがforループを中断できるようにするには、SIGINTとSIGTERMをトラップする必要があります。
http://gitstats.sourceforge.net/から入手できるgitstatsコマンドを確認してください。
すべてのテキストファイル(バイナリファイルを除く、バージョン管理されたファイルも含む)の非難された行を数えるこのソリューションがあります。
IFS=$'\n'
for file in $(git ls-files); do
git blame `git symbolic-ref --short HEAD` --line-porcelain "$file" | \
grep "^author " | \
grep -v "Binary file (standard input) matches" | \
grep -v "Not Committed Yet" | \
cut -d " " -f 2-
done | \
sort | \
uniq -c | \
sort -nr
私はPowershell のトップ回答を採用しました:
(git ls-tree -rz --name-only HEAD).Split(0x00) | where {$_ -Match '.*\.py'} |%{git blame -w --line-porcelain HEAD $_} | Select-String -Pattern '^author ' | Group-Object | Select-Object -Property Count, Name | Sort-Object -Property Count -Descending
スイッチで実行git blame
するかどうかはオプションですが、-w
空白の変更を無視するために追加しました。
BashソリューションはWSL2の下で実行されていましたが、私のマシンのパフォーマンスはPowershellに有利でした(同じリポジトリの場合は〜50秒から〜65秒)。
@nilbusと@Alexを組み合わせた独自のスクリプトを作成
#!/bin/sh
for f in $(git ls-tree -r --name-only HEAD --);
do
j=$(file "$f" | grep -E ': .*text'| sed -r -e 's/: .*//');
if [ "$f" != "$j" ]; then
continue;
fi
git blame -w --line-porcelain HEAD "$f" | grep "^author " | sed 's/author //'`enter code here`
done | sort | uniq -c | sort -nr
enter code here
問題が原因でした...これは正しく動作しますか?