programing

Git 저장소에서 특정 작성자가 변경한 총 줄 수를 계산하는 방법은 무엇입니까?

showcode 2023. 5. 20. 11:03
반응형

Git 저장소에서 특정 작성자가 변경한 총 줄 수를 계산하는 방법은 무엇입니까?

Git 저장소에서 특정 작성자가 변경한 행을 셀 수 있는 명령어가 있습니까?Github이 그들의 영향 그래프에 대해 이렇게 하는 것처럼 커밋의 수를 셀 수 있는 방법이 있어야 한다는 것을 알고 있습니다.

작성자에 대한 몇 가지 통계를 제공합니다. 필요에 따라 수정하십시오.

용사를 합니다.Gawk:

git log --author="_Your_Name_Here_" --pretty=tformat: --numstat \
| gawk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }' -

용사를 합니다.AwkMac OSX 파일:

git log --author="_Your_Name_Here_" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

용사를 합니다.count-linesgit-transmit-timeout:

간히만기를 만듭니다.count-lines별칭(시스템당 한 번), 예:

git config --global alias.count-lines "! git log --author=\"\$1\" --pretty=tformat: --numstat | awk '{ add += \$1; subs += \$2; loc += \$1 - \$2 } END { printf \"added lines: %s, removed lines: %s, total lines: %s\n\", add, subs, loc }' #"

나중에 다음과 같이 매번 사용합니다.

git count-lines email@example.com

Windows의 경우 Git-Bash를 다음에 추가한 후 작동합니다.PATH(환경 보호).
Linux의 경우, 대체 가능awk와어는지로 gawk.
MacOS의 경우 변경 없이 작동합니다.

기존 스크립트 사용

github에는 매끄럽고 bash를 종속성으로 사용하는 새로운 패키지가 있습니다(Linux에서 테스트됨).스크립트보다는 직접 사용하기에 더 적합합니다.

git-quick-stats(git-quick-stats)입니다.

알았다.git-quick-stats폴더에 추가하고 경로에 폴더를 추가합니다.

mkdir ~/source
cd ~/source
git clone git@github.com:arzzen/git-quick-stats.git
mkdir ~/bin
ln -s ~/source/git-quick-stats/git-quick-stats ~/bin/git-quick-stats
chmod +x ~/bin/git-quick-stats
export PATH=${PATH}:~/bin

용도:

git-quick-stats

여기에 이미지 설명 입력

다음 명령어의 출력은 스크립트로 전송하여 합계를 합산하는 것이 상당히 쉬울 것입니다.

git log --author="<authorname>" --oneline --shortstat

현재 HEAD의 모든 커밋에 대한 통계를 제공합니다..git log.

스크립트로 전달하는 경우, "한 줄" 형식도 빈 로그 형식으로 제거할 수 있으며, Jakub Narębski가 언급했듯이,--numstat또 다른 대안입니다.이것은 줄 단위 통계가 아닌 파일 단위 통계를 생성하지만 구문 분석이 훨씬 쉽습니다.

git log --author="<authorname>" --pretty=tformat: --numstat

코드베이스에 있는 모든 사용자의 통계를 보고 싶은 사람이 있을 경우, 최근 제 동료 몇 명이 다음과 같은 끔찍한 단일 라이너를 고안했습니다.

git log --shortstat --pretty="%cE" | sed 's/\(.*\)@.*/\1/' | grep -v "^$" | awk 'BEGIN { line=""; } !/^ / { if (line=="" || !match(line, $0)) {line = $0 "," line }} /^ / { print line " # " $0; line=""}' | sort | sed -E 's/# //;s/ files? changed,//;s/([0-9]+) ([0-9]+ deletion)/\1 0 insertions\(+\), \2/;s/\(\+\)$/\(\+\), 0 deletions\(-\)/;s/insertions?\(\+\), //;s/ deletions?\(-\)//' | awk 'BEGIN {name=""; files=0; insertions=0; deletions=0;} {if ($1 != name && name != "") { print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net"; files=0; insertions=0; deletions=0; name=$1; } name=$1; files+=$2; insertions+=$3; deletions+=$4} END {print name ": " files " files changed, " insertions " insertions(+), " deletions " deletions(-), " insertions-deletions " net";}'

(약 10-15,000개의 커밋이 있는 우리의 레포를 처리하는 데 몇 분이 걸립니다.)

가슴이 두근거리는

https://github.com/oleander/git-fame-rb

이 도구는 커밋 및 수정된 파일 수를 포함하여 모든 작성자의 수를 한 번에 가져올 수 있는 좋은 도구입니다.

sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame

파이썬 버전은 https://github.com/casperdcl/git-fame 에도 있습니다(@fracz에서 언급됨).

sudo apt-get install python-pip python-dev build-essential 
pip install --user git-fame
cd /path/to/gitdir && git fame

샘플 출력:

Total number of files: 2,053
Total number of lines: 63,132
Total number of commits: 4,330

+------------------------+--------+---------+-------+--------------------+
| name                   | loc    | commits | files | percent            |
+------------------------+--------+---------+-------+--------------------+
| Johan Sørensen         | 22,272 | 1,814   | 414   | 35.3 / 41.9 / 20.2 |
| Marius Mathiesen       | 10,387 | 502     | 229   | 16.5 / 11.6 / 11.2 |
| Jesper Josefsson       | 9,689  | 519     | 191   | 15.3 / 12.0 / 9.3  |
| Ole Martin Kristiansen | 6,632  | 24      | 60    | 10.5 / 0.6 / 2.9   |
| Linus Oleander         | 5,769  | 705     | 277   | 9.1 / 16.3 / 13.5  |
| Fabio Akita            | 2,122  | 24      | 60    | 3.4 / 0.6 / 2.9    |
| August Lilleaas        | 1,572  | 123     | 63    | 2.5 / 2.8 / 3.1    |
| David A. Cuadrado      | 731    | 111     | 35    | 1.2 / 2.6 / 1.7    |
| Jonas Ängeslevä        | 705    | 148     | 51    | 1.1 / 3.4 / 2.5    |
| Diego Algorta          | 650    | 6       | 5     | 1.0 / 0.1 / 0.2    |
| Arash Rouhani          | 629    | 95      | 31    | 1.0 / 2.2 / 1.5    |
| Sofia Larsson          | 595    | 70      | 77    | 0.9 / 1.6 / 3.8    |
| Tor Arne Vestbø        | 527    | 51      | 97    | 0.8 / 1.2 / 4.7    |
| spontus                | 339    | 18      | 42    | 0.5 / 0.4 / 2.0    |
| Pontus                 | 225    | 49      | 34    | 0.4 / 1.1 / 1.7    |
+------------------------+--------+---------+-------+--------------------+

그러나 Jared가 코멘트에서 언급했듯이, 매우 큰 저장소에서 이 작업을 수행하는 데는 몇 시간이 걸릴 것입니다.하지만 그것이 그렇게 많은 Git 데이터를 처리해야 한다는 것을 고려할 때, 그것이 개선될 수 있을지 확신할 수 없습니다.

다음은 현재 코드 기반에 있는 행 수가 가장 많은 사람을 확인하는 데 유용하다는 것을 알게 되었습니다.

git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n

다른 답변은 커밋에서 변경된 행에 대부분 초점을 맞췄지만 커밋이 살아남지 못하고 덮어쓰게 되면 그냥 버려졌을 수도 있습니다.위의 주문은 또한 한 번에 하나씩이 아닌 줄별로 모든 커미터를 정렬합니다.파일 이동과 파일 간의 줄 이동을 고려한 더 나은 숫자를 얻기 위해 gitbrack(-C -M)에 몇 가지 옵션을 추가할 수 있지만, 그렇게 하면 명령이 훨씬 더 오래 실행될 수 있습니다.

또한 모든 커밋에서 변경된 행을 찾는 경우 다음과 같은 작은 스크립트가 유용합니다.

http://git-wt-commit.rubyforge.org/ #git-rank 유통업체

지정된 분기에서 지정된 작성자(또는 모든 작성자)의 커밋 를 계산하려면 git-shortlog를 사용할 수 있습니다. 특히 해당 항목을 참조하십시오.--numbered그리고.--summary옵션(예: git 저장소에서 실행하는 경우):

$ git shortlog v1.6.4 --numbered --summary
  6904  Junio C Hamano
  1320  Shawn O. Pearce
  1065  Linus Torvalds
    692  Johannes Schindelin
    443  Eric Wong

Alex Gerty3000의 답변을 본 후, 저는 한 줄을 줄이려고 노력했습니다.

기본적으로 git log numstat을 사용하고 변경된 파일 를 추적하지 않습니다.

Mac OS X에서 Git 버전 2.1.0:

git log --format='%aN' | sort -u | while read name; do echo -en "$name\t"; git log --author="$name" --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done

예:

Jared Burrows   added lines: 6826, removed lines: 2825, total lines: 4001

셸 원라이너를 사용하는 AaronM의 Answer는 좋지만 실제로 사용자 이름과 날짜 사이에 공백의 양이 다를 경우 공백이 사용자 이름을 손상시키는 다른 버그가 있습니다.손상된 사용자 이름은 사용자 수에 대해 여러 행을 제공하므로 사용자가 직접 요약해야 합니다.

이 작은 변화가 저에게 문제를 해결해 주었습니다.

git ls-files -z | xargs -0n1 git blame -w --show-email | perl -n -e '/^.*?\((.*?)\s+[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n

이름부터 날짜까지 모든 공백을 사용하는 +after \s를 확인합니다.

사실 다른 사람을 돕는 것만큼 나 자신의 기억을 위해 이 대답을 추가하는 것은 적어도 이것이 내가 그 주제를 검색하는 두 번째이기 때문입니다 :)

  • 2019-01-23 편집 추가--show-emailgit blame -w일부 사람들은 다른 것을 사용하기 때문에 대신 이메일에 집계합니다.Name서로 다른 컴퓨터에 있는 형식, 그리고 때때로 같은 이름을 가진 두 명의 사람이 같은 깃에서 작업합니다.

여기 모든 저자에 대한 통계를 생성하는 짧은 한 줄기가 있습니다.https://stackoverflow.com/a/20414465/1102119 있는 Dan의 솔루션보다 훨씬 빠릅니다(내 솔루션은 O(NM) 대신 O(N) 시간 복잡성이 있습니다. 여기서 N은 커밋 수, M은 작성자 수입니다).

git log --no-merges --pretty=format:%an --numstat | awk '/./ && !author { author = $0; next } author { ins[author] += $1; del[author] += $2 } /^$/ { author = ""; next } END { for (a in ins) { printf "%10d %10d %10d %s\n", ins[a] - del[a], ins[a], del[a], a } }' | sort -rn

@mmrobins @AaronM @ErikZ @James Mishra는 모두 공통적으로 문제가 있는 변형을 제공했습니다: 그들은 git에게 동일한 라인의 저장소의 라인 콘텐츠를 포함하여 스크립트 사용을 의도하지 않은 혼합 정보를 생성하도록 요청한 다음 혼란을 regexp와 일치시킵니다.

이 문제는 일부 행이 UTF-8 텍스트가 아닌 경우와 일부 행이 정규식과 일치하는 경우에도 발생합니다(여기서 발생).

여기 이러한 문제가 없는 수정된 라인이 있습니다.별도의 라인에서 데이터를 깨끗하게 출력하기 위해 Git를 요청하므로 원하는 항목을 쉽게 필터링할 수 있습니다.

git ls-files -z | xargs -0n1 git blame -w --line-porcelain | grep -a "^author " | sort -f | uniq -c | sort -n

작성자 메일, 커미터 등과 같은 다른 문자열을 검색할 수 있습니다.

아마도 먼저 할 것입니다.export LC_ALL=C)로 표시됩니다.bash처리를 강제로 바이트 수준 처리를 강제로 수행합니다(이는 UTF-8 기반 로케일에서 grep 속도를 엄청나게 높이는 경우도 발생합니다).

중간에 루비가 있는 솔루션이 제공되었습니다. 펄은 기본적으로 조금 더 많이 사용할 수 있습니다. 여기서는 작성자별 현재 줄에 펄을 사용하는 대안입니다.

git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n

당신은 누가 했는지를 사용할 수 있습니다 (https://www.npmjs.com/package/whodid) .

$ npm install whodid -g
$ cd your-project-dir

그리고.

$ whodid author --include-merge=false --path=./ --valid-threshold=1000 --since=1.week

아니면 그냥 타입.

$ whodid

그러면 다음과 같은 결과를 볼 수 있습니다.

Contribution state
=====================================================
 score  | author
-----------------------------------------------------
 3059   | someguy <someguy@tensorflow.org>
 585    | somelady <somelady@tensorflow.org>
 212    | niceguy <nice@google.com>
 173    | coolguy <coolgay@google.com>
=====================================================

찰스 베일리의 대답 외에도, 당신은 다음과 같이 덧붙이는 것이 좋을 것입니다.-C명령에 대한 매개 변수입니다.그렇지 않으면 파일 내용이 수정되지 않았더라도 파일 이름은 추가 및 제거 횟수(파일에 줄이 있는 수만큼)로 계산됩니다.

예를 들어, 여기에 프로젝트 중 하나에서 이동 중인 많은 파일이 포함된 커밋이 있습니다.git log --oneline --shortstat명령:

9052459 Reorganized project structure
 43 files changed, 1049 insertions(+), 1000 deletions(-)

그리고 여기서 동일한 커밋을 사용합니다.git log --oneline --shortstat -C파일 복사본 및 이름 바꾸기를 검색하는 명령:

9052459 Reorganized project structure
 27 files changed, 134 insertions(+), 85 deletions(-)

제 생각에 후자는 한 사람이 프로젝트에 얼마나 많은 영향을 미쳤는지에 대한 보다 현실적인 견해를 제공합니다. 파일 이름을 바꾸는 것은 처음부터 파일을 쓰는 것보다 훨씬 작은 작업이기 때문입니다.

다음은 지정된 로그 쿼리에 대한 사용자별 영향을 요약하는 빠른 루비 스크립트입니다.

예를 들어 루비니우스의 경우:

Brian Ford: 4410668
Evan Phoenix: 1906343
Ryan Davis: 855674
Shane Becker: 242904
Alexander Kellett: 167600
Eric Hodel: 132986
Dirkjan Bussink: 113756
...

대본:

#!/usr/bin/env ruby

impact = Hash.new(0)

IO.popen("git log --pretty=format:\"%an\" --shortstat #{ARGV.join(' ')}") do |f|
  prev_line = ''
  while line = f.gets
    changes = /(\d+) insertions.*(\d+) deletions/.match(line)

    if changes
      impact[prev_line] += changes[1].to_i + changes[2].to_i
    end

    prev_line = line # Names are on a line of their own, just before the stats
  end
end

impact.sort_by { |a,i| -i }.each do |author, impact|
  puts "#{author.strip}: #{impact}"
end

이것이 가장 좋은 방법이며 모든 사용자의 총 커밋 수에 대한 명확한 그림을 제공합니다.

git shortlog -s -n

여기 당신의 삶을 더 편하게 해주는 훌륭한 레포가 있습니다.

git-quick-stats

양주가 설치된 Mac에서

brew install git-quick-stats

달려.

git-quick-stats

나열된 번호를 입력하고 Enter 키를 눌러 이 목록에서 원하는 옵션을 선택하십시오.

 Generate:
    1) Contribution stats (by author)
    2) Contribution stats (by author) on a specific branch
    3) Git changelogs (last 10 days)
    4) Git changelogs by author
    5) My daily status
    6) Save git log output in JSON format

 List:
    7) Branch tree view (last 10)
    8) All branches (sorted by most recent commit)
    9) All contributors (sorted by name)
   10) Git commits per author
   11) Git commits per date
   12) Git commits per month
   13) Git commits per weekday
   14) Git commits per hour
   15) Git commits by author per hour

 Suggest:
   16) Code reviewers (based on git history)

위의 짧은 답변을 수정하여 제공했지만, 제 요구에 충분하지 않았습니다.저는 최종 코드에서 커밋된 행과 행을 모두 분류할 수 있어야 했습니다.저는 또한 파일별로 분류하기를 원했습니다.이 코드는 반복되지 않으며, 단일 디렉터리에 대한 결과만 반환하지만, 다른 사용자가 더 멀리 가기를 원할 경우에는 시작이 좋습니다.파일을 복사하여 붙여넣고 실행 파일로 만들거나 Perl로 실행합니다.

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $dir = shift;

die "Please provide a directory name to check\n"
    unless $dir;

chdir $dir
    or die "Failed to enter the specified directory '$dir': $!\n";

if ( ! open(GIT_LS,'-|','git ls-files') ) {
    die "Failed to process 'git ls-files': $!\n";
}
my %stats;
while (my $file = <GIT_LS>) {
    chomp $file;
    if ( ! open(GIT_LOG,'-|',"git log --numstat $file") ) {
        die "Failed to process 'git log --numstat $file': $!\n";
    }
    my $author;
    while (my $log_line = <GIT_LOG>) {
        if ( $log_line =~ m{^Author:\s*([^<]*?)\s*<([^>]*)>} ) {
            $author = lc($1);
        }
        elsif ( $log_line =~ m{^(\d+)\s+(\d+)\s+(.*)} ) {
            my $added = $1;
            my $removed = $2;
            my $file = $3;
            $stats{total}{by_author}{$author}{added}        += $added;
            $stats{total}{by_author}{$author}{removed}      += $removed;
            $stats{total}{by_author}{total}{added}          += $added;
            $stats{total}{by_author}{total}{removed}        += $removed;

            $stats{total}{by_file}{$file}{$author}{added}   += $added;
            $stats{total}{by_file}{$file}{$author}{removed} += $removed;
            $stats{total}{by_file}{$file}{total}{added}     += $added;
            $stats{total}{by_file}{$file}{total}{removed}   += $removed;
        }
    }
    close GIT_LOG;

    if ( ! open(GIT_BLAME,'-|',"git blame -w $file") ) {
        die "Failed to process 'git blame -w $file': $!\n";
    }
    while (my $log_line = <GIT_BLAME>) {
        if ( $log_line =~ m{\((.*?)\s+\d{4}} ) {
            my $author = $1;
            $stats{final}{by_author}{$author}     ++;
            $stats{final}{by_file}{$file}{$author}++;

            $stats{final}{by_author}{total}       ++;
            $stats{final}{by_file}{$file}{total}  ++;
            $stats{final}{by_file}{$file}{total}  ++;
        }
    }
    close GIT_BLAME;
}
close GIT_LS;

print "Total lines committed by author by file\n";
printf "%25s %25s %8s %8s %9s\n",'file','author','added','removed','pct add';
foreach my $file (sort keys %{$stats{total}{by_file}}) {
    printf "%25s %4.0f%%\n",$file
            ,100*$stats{total}{by_file}{$file}{total}{added}/$stats{total}{by_author}{total}{added};
    foreach my $author (sort keys %{$stats{total}{by_file}{$file}}) {
        next if $author eq 'total';
        if ( $stats{total}{by_file}{$file}{total}{added} ) {
            printf "%25s %25s %8d %8d %8.0f%%\n",'', $author,@{$stats{total}{by_file}{$file}{$author}}{qw{added removed}}
            ,100*$stats{total}{by_file}{$file}{$author}{added}/$stats{total}{by_file}{$file}{total}{added};
        } else {
            printf "%25s %25s %8d %8d\n",'', $author,@{$stats{total}{by_file}{$file}{$author}}{qw{added removed}} ;
        }
    }
}
print "\n";

print "Total lines in the final project by author by file\n";
printf "%25s %25s %8s %9s %9s\n",'file','author','final','percent', '% of all';
foreach my $file (sort keys %{$stats{final}{by_file}}) {
    printf "%25s %4.0f%%\n",$file
            ,100*$stats{final}{by_file}{$file}{total}/$stats{final}{by_author}{total};
    foreach my $author (sort keys %{$stats{final}{by_file}{$file}}) {
        next if $author eq 'total';
        printf "%25s %25s %8d %8.0f%% %8.0f%%\n",'', $author,$stats{final}{by_file}{$file}{$author}
            ,100*$stats{final}{by_file}{$file}{$author}/$stats{final}{by_file}{$file}{total}
            ,100*$stats{final}{by_file}{$file}{$author}/$stats{final}{by_author}{total}
        ;
    }
}
print "\n";


print "Total lines committed by author\n";
printf "%25s %8s %8s %9s\n",'author','added','removed','pct add';
foreach my $author (sort keys %{$stats{total}{by_author}}) {
    next if $author eq 'total';
    printf "%25s %8d %8d %8.0f%%\n",$author,@{$stats{total}{by_author}{$author}}{qw{added removed}}
        ,100*$stats{total}{by_author}{$author}{added}/$stats{total}{by_author}{total}{added};
};
print "\n";


print "Total lines in the final project by author\n";
printf "%25s %8s %9s\n",'author','final','percent';
foreach my $author (sort keys %{$stats{final}{by_author}}) {
    printf "%25s %8d %8.0f%%\n",$author,$stats{final}{by_author}{$author}
        ,100*$stats{final}{by_author}{$author}/$stats{final}{by_author}{total};
}

다음을 사용하여 로그를 파일에 저장합니다.

git log --author="<authorname>" --oneline --shortstat > logs.txt

Python을 사랑하는 사람들을(를)

with open(r".\logs.txt", "r", encoding="utf8") as f:
    files = insertions = deletions = 0
    for line in f:
        if ' changed' in line:
            line = line.strip()
            spl = line.split(', ')
            if len(spl) > 0:
                files += int(spl[0].split(' ')[0])
            if len(spl) > 1:
                insertions += int(spl[1].split(' ')[0])
            if len(spl) > 2:
                deletions += int(spl[2].split(' ')[0])

    print(str(files).ljust(10) + ' files changed')
    print(str(insertions).ljust(10) + ' insertions')
    print(str(deletions).ljust(10) + ' deletions')

출력은 다음과 같습니다.

225        files changed
6751       insertions
1379       deletions

질문은 특정 작성자에 대한 정보를 요청했지만 대부분의 답변은 변경된 코드 줄에 따라 순위가 매겨진 작성자 목록을 반환하는 솔루션이었습니다.

이것이 제가 찾던 것이었지만, 기존의 해결책은 그다지 완벽하지 않았습니다.구글을 통해 이 질문을 찾을 수 있는 사람들의 관심을 끌기 위해, 저는 그것들을 몇 가지 개선하여 셸 스크립트로 만들었습니다. 아래에 표시합니다.

Perl 또는 Ruby에 대한 종속성이 없습니다.또한 행 변경 횟수에는 공백, 이름 바꾸기 및 행 이동이 고려됩니다.이것을 파일에 넣고 첫 번째 매개 변수로 Git 저장소를 전달하기만 하면 됩니다.

#!/bin/bash
git --git-dir="$1/.git" log > /dev/null 2> /dev/null
if [ $? -eq 128 ]
then
    echo "Not a git repository!"
    exit 128
else
    echo -e "Lines  | Name\nChanged|"
    git --work-tree="$1" --git-dir="$1/.git" ls-files -z |\
    xargs -0n1 git --work-tree="$1" --git-dir="$1/.git" blame -C -M  -w |\
    cut -d'(' -f2 |\
    cut -d2 -f1 |\
    sed -e "s/ \{1,\}$//" |\
    sort |\
    uniq -c |\
    sort -nr
fi

Windows 사용자의 경우 지정된 작성자에 대해 추가/제거된 줄 수를 세는 다음 배치 스크립트를 사용할 수 있습니다.

@echo off

set added=0
set removed=0

for /f "tokens=1-3 delims= " %%A in ('git log --pretty^=tformat: --numstat --author^=%1') do call :Count %%A %%B %%C

@echo added=%added%
@echo removed=%removed%
goto :eof

:Count
  if NOT "%1" == "-" set /a added=%added% + %1
  if NOT "%2" == "-" set /a removed=%removed% + %2
goto :eof

https://gist.github.com/zVolodymyr/62e78a744d99d414d56646a5e8a1ff4f

여기 이 스크립트로 해결할 수 있습니다.authorship.sh , chmod +xit에 넣으면 모든 준비가 완료됩니다.

#!/bin/sh
declare -A map
while read line; do
    if grep "^[a-zA-Z]" <<< "$line" > /dev/null; then
        current="$line"
        if [ -z "${map[$current]}" ]; then 
            map[$current]=0
        fi
    elif grep "^[0-9]" <<<"$line" >/dev/null; then
        for i in $(cut -f 1,2 <<< "$line"); do
            map[$current]=$((map[$current] + $i))
        done
    fi
done <<< "$(git log --numstat --pretty="%aN")"

for i in "${!map[@]}"; do
    echo -e "$i:${map[$i]}"
done | sort -nr -t ":" -k 2 | column -t -s ":"

지금까지 확인한 최고의 도구는 git inspector입니다.사용자별, 주별 등의 설정 보고서를 제공합니다. 아래와 같이 npm으로 설치할 수 있습니다.

npm 설치 - git inspector

자세한 내용을 확인할 수 있는 링크

https://www.npmjs.com/package/gitinspector

https://github.com/ejwa/gitinspector/wiki/Documentation

https://github.com/ejwa/gitinspector

예제 명령은 다음과 같습니다.

gitinspector -lmrTw 
gitinspector --since=1-1-2017 etc

저는 그 작업을 수행하기 위해 이 Perl 스크립트를 작성했습니다.

#!/usr/bin/env perl

use strict;
use warnings;

# save the args to pass to the git log command
my $ARGS = join(' ', @ARGV);

#get the repo slug
my $NAME = _get_repo_slug();

#get list of authors
my @authors = _get_authors();
my ($projectFiles, $projectInsertions, $projectDeletions) = (0,0,0);
#for each author
foreach my $author (@authors) {
  my $command = qq{git log $ARGS --author="$author" --oneline --shortstat --no-merges};
  my ($files, $insertions, $deletions) = (0,0,0);
  my @lines = `$command`;
  foreach my $line (@lines) {
    if ($line =~ m/^\s(\d+)\s\w+\s\w+,\s(\d+)\s\w+\([\+|\-]\),\s(\d+)\s\w+\([\+|\-]\)$|^\s(\d+)\s\w+\s\w+,\s(\d+)\s\w+\(([\+|\-])\)$/) {
      my $lineFiles = $1 ? $1 : $4;
      my $lineInsertions = (defined $6 && $6 eq '+') ? $5 : (defined $2) ? $2 : 0;
      my $lineDeletions = (defined $6 && $6 eq '-') ? $5 : (defined $3) ? $3 : 0;
      $files += $lineFiles;
      $insertions += $lineInsertions;
      $deletions += $lineDeletions;
      $projectFiles += $lineFiles;
      $projectInsertions += $lineInsertions;
      $projectDeletions += $lineDeletions;
    }
  }
  if ($files || $insertions || $deletions) {
    printf(
      "%s,%s,%s,+%s,-%s,%s\n",
      $NAME,
      $author,
      $files,
      $insertions,
      $deletions,
      $insertions - $deletions
    );
  }
}

printf(
  "%s,%s,%s,+%s,-%s,%s\n",
  $NAME,
  'PROJECT_TOTAL',
  $projectFiles,
  $projectInsertions,
  $projectDeletions,
  $projectInsertions - $projectDeletions
);

exit 0;

#get the remote.origin.url joins that last two pieces (project and repo folder)
#and removes any .git from the results. 
sub _get_repo_slug {
  my $get_remote_url = "git config --get remote.origin.url";
  my $remote_url = `$get_remote_url`;
  chomp $remote_url;

  my @parts = split('/', $remote_url);

  my $slug = join('-', @parts[-2..-1]);
  $slug =~ s/\.git//;

  return $slug;
}

sub _get_authors {
  my $git_authors = 'git shortlog -s | cut -c8-';
  my @authors = `$git_authors`;
  chomp @authors;

  return @authors;
}

이름을 지었습니다git-line-changes-by-author 에투니다에 ./usr/local/bin에, 는 내경에저로릴 명 내 수 있 습 을 니 다 령 때 에 문 있 장 되 기 어 ▁command 니 있 ▁because ▁the 다 습 ▁issue 수 ▁i , ▁can ▁in ▁is 내 내 ▁path ▁saved ▁mygit line-changes-by-author --before 2018-12-31 --after 2020-01-01 .2019년.and면. 해 줄 입니다.그리고 만약 내가 git라는 이름의 철자를 잘못 쓴다면, 그것은 적절한 철자를 제안할 것입니다.

다음을 조정할 수 있습니다._get_repo_slug마지막 부분만 포함하는 서브remote.origin.url나의 저장소가 로 저장되어 있기 때문에project/repo당신은 아닐 수도 있어요.

당신은 Git black을 원합니다.

통계를 출력할 수 있는 --show-stats 옵션이 있습니다.

언급URL : https://stackoverflow.com/questions/1265040/how-to-count-total-lines-changed-by-a-specific-author-in-a-git-repository

반응형