각 커미터에서 시작된 저장소에 현재 얼마나 많은 행 (코드)이 있는지 통계를 제공하기 위해 어떻게 비난 (또는 더 적합한 기능 및 / 또는 쉘 명령과 함께)을 "남용"할 수 있습니까?
출력 예 :
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 "
위의 명령은 공백이 아닌 문자를 하나 이상 포함하는 행 작성자를 인쇄합니다. 또한 \w*[^\w#]
공백이 아닌 첫 문자가 아닌 행을 제외시키는 match 를 사용할 수도 있습니다 #
(많은 스크립팅 언어의 주석).
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
깃발을 이해하지 못하고 정규 표현식에 문제가 있습니다 (여분을 제거 할 때도 불균형 한 parens에 대해 불평합니다 (
).
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
또한 바이너리 brewbrew 설치이기 때문에 시스템 sed를 그대로두기 때문에 gsed
대신에 유의하십시오 sed
.
다음은 @Alex의 답변에서 실제로 비난 라인을 집계하는 작업을 수행하는 기본 스 니펫입니다. 파일 세트가 아닌 단일 파일 에서 작동하도록 줄 였습니다.
git blame --line-porcelain path/to/file.txt | grep "^author " | sort | uniq -c | sort -nr
나는이 답변에 자주 돌아와서 게시물을 다시 읽고 예제를 다시 소화하여 과세 대상 부분을 추출하기 때문에 여기에 게시합니다. 또한 내 유스 케이스에 대해 일반적인 것이 아닙니다. 그 범위는 전체 C 프로젝트입니다.
떠들썩한로를 통해 achived 파일 당 목록 통계에 같은 I for
반복자 대신 xargs
내가 사용 / 암기, 장점 / 단점에 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 을 트랩 해야 할 수도 있습니다 .
git blame -w -M -C -C --line-porcelain path/to/file.txt | grep -I '^author ' | sort | uniq -ic | sort -nr
내가 찾고 있던 통계를 더 정확하게 묘사하는 git blame
여기에 약간의 조정이 있음을 발견했습니다 . 특히, -M 및 -C -C 옵션 (이 두 가지는 C입니다). -M은 파일 내에서의 이동을 감지하고 -C -C는 다른 파일에서 복사 된 행을 감지합니다. doc here 참조 하십시오 . 완전성을 위해 -w는 공백을 무시합니다.
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 대 ~ 65s)을 선호했습니다.
@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
가 발생했습니다 ....이 제대로 작동합니까?