Programing

힘내 비난 : 통계

crosscheck 2020. 5. 15. 20:58
반응형

힘내 비난 : 통계


각 커미터에서 시작된 저장소에 현재 몇 줄의 코드가 있는지 통계를 제공하기 위해 어떻게 비난 (또는 더 적합한 기능 및 / 또는 쉘 명령과 함께)을 "남용"할 수 있습니까?

출력 예 :

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 "

위의 명령은 공백이 아닌 문자를 하나 이상 포함하는 행 작성자를 인쇄합니다. 또한 \w*[^\w#]공백이 아닌 첫 문자가 아닌 행을 제외시키는 match 사용할 수도 있습니다 #(많은 스크립팅 언어의 주석).


유용한 git-fame 이라는 보석을 썼습니다 .

설치 및 사용법 :

  1. $ gem install git_fame
  2. $ cd /path/to/gitdir
  3. $ 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

Step by step explanation:

List all the files under version control

git ls-tree -r HEAD|sed -re 's/^.{53}//'

Prune the list down to only text files

|while read filename; do file "$filename"; done|grep -E ': .*text'|sed -r -e 's/: .*//'

Git blame all the text files, ignoring whitespace changes

|while read filename; do git blame -w "$filename"; done

Pull out the author names

|sed -r -e 's/.*\((.*)[0-9]{4}-[0-9]{2}-[0-9]{2} .*/\1/' -e 's/ +$//'

Sort the list of authors, and have uniq count the number of consecutively repeating lines

|sort|uniq -c

Example output:

   1334 Maneater
   1924 Another guy
  37195 Brian Ruby
   1482 Anna Lambda

git summary provided by the git-extras package is exactly what you need. Checkout the documentation at git-extras - git-summary:

git summary --line

Gives output that looks like this:

project  : TestProject
lines    : 13397
authors  :
8927 John Doe            66.6%
4447 Jane Smith          33.2%
  23 Not Committed Yet   0.2%

Erik's solution was awesome, but I had some problems with diacritics (despite my LC_* environment variables being set ostensibly correctly) and noise leaking through on lines of code that actually had dates in them. My sed-fu is poor, so I ended up with this frankenstein snippet with ruby in it, but it works for me flawlessly on 200,000+ LOC, and it sorts the results:

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

Also note gsed instead of sed because that's the binary homebrew installs, leaving the system sed intact.


Check out the gitstats command available from http://gitstats.sourceforge.net/


git shortlog -sn

This will show a list of commits per author.


Here is the primary snippet from @Alex 's answer that actually does the operation of aggregating the blame lines. I've cut it down to operate on a single file rather than a set of files.

git blame --line-porcelain path/to/file.txt | grep  "^author " | sort | uniq -c | sort -nr

I post this here because I come back to this answer often and re-reading the post and re-digesting the examples to extract the portion I value it is taxing. Nor is it generic enough for my use case; its scope is for a whole C project.


I like to list stats per file, achived via with a bash for iterator instead of xargs as I find xargs less readable and hard to use/memorize, The advantage/disadvantages xargs vs for should be discussed elsewhere.

Here is a practical snippet that will show results for each file individually:

for file in $(git ls-files); do \
    echo $file; \
    git blame --line-porcelain $file \
        | grep  "^author " | sort | uniq -c | sort -nr; \
    echo; \
done

And I tested, running this stright in a bash shell is ctrl+c safe, if you need to put this inside a bash script you might need to Trap on SIGINT and SIGTERM if you want the user to be able to break your for loop.


I have this solution that counts the blamed lines in all text files (excluding the binary files, even the versioned ones):

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

Made my own script which is a combination of @nilbus and @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

참고URL : https://stackoverflow.com/questions/4589731/git-blame-statistics

반응형