Відповіді:
Виведення наступної команди повинно бути досить легко надіслати до сценарію, щоб скласти підсумки:
git log --author="<authorname>" --oneline --shortstat
Це дає статистику для всіх комісій на поточній ГЛАВІ. Якщо ви хочете додати статистику в інших галузях, вам доведеться надати їх як аргументи git log
.
Для переходу до сценарію, видалення навіть формату "oneline" можна зробити з порожнім форматом журналу, і, як коментує Якуб Нарбський, --numstat
- це ще одна альтернатива. Він генерує статистику за файлом, а не за рядком, але ще простіше аналізувати.
git log --author="<authorname>" --pretty=tformat: --numstat
--numstat
замість цього, --shortstat
якщо хочете трохи простіше додати статистику.
git help log
повідомляє мені, що перші додані рядки, другі видалені.
Це дає деякі статистичні дані про автора, за необхідними змінами.
Використання 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 }' -
Використання Awk на Mac 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 }' -
На Github є новий пакет, який виглядає гладким і використовує bash як залежності (тестується на Linux). Він більше підходить для прямого використання, а не сценаріїв.
Це git-quick-stats (github link) .
Скопіюйте 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
gawk
щоб awk
він працював у терміналі OSX
git clone https://github.com/arzzen/git-quick-stats.git
Якщо хтось хоче побачити статистику кожного користувача у його кодовій базі, недавно пару моїх колег придумали цей жахливий однокласник:
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 к.).
michael,: 6057 files changed, 854902 insertions(+), 26973 deletions(-), 827929 net
Git fame https://github.com/oleander/git-fame-rb
це хороший інструмент, щоб отримати кількість підрахунків для всіх авторів відразу, включаючи фіксацію та кількість модифікованих файлів:
sudo apt-get install ruby-dev
sudo gem install git_fame
cd /path/to/gitdir && git fame
Також є версія Python за адресою 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 |
+------------------------+--------+---------+-------+--------------------+
Але будьте попереджені: як згадував Джаред у коментарі, робити це у дуже великому сховищі буде потрібно години. Не впевнений, чи можна це вдосконалити, враховуючи, що він повинен обробити стільки даних Git.
git fame --branch=dev --timeout=-1 --exclude=Pods/*
Я виявив корисне наступне, щоб побачити, хто має найбільше рядків, які зараз перебувають у кодовій базі:
git ls-files -z | xargs -0n1 git blame -w | ruby -n -e '$_ =~ /^.*\((.*?)\s[\d]{4}/; puts $1.strip' | sort -f | uniq -c | sort -n
Інші відповіді здебільшого зосереджувались на рядках, змінених у комітах, але якщо комітети не виживають та перезаписуються, вони, можливо, просто розбиваються. Наведене вище заклик також дає вам всі дозволи, відсортовані за рядками, а не лише один за одним. Ви можете додати деякі параметри до git blame (-C -M), щоб отримати кращі номери, які враховують рух файлів та рух рядків між файлами, але команда може зайнятись значно довше, якщо ви це зробите.
Крім того, якщо ви шукаєте рядки, змінені у всіх комісіях для всіх виконавців, корисний наступний маленький сценарій:
/^.*\((.*?)\s[\d]{4}/
Потрібно /^.*?\((.*?)\s[\d]{4}/
запобігати збігу дужок у джерелі як автору.
Для підрахунку кількості фіксацій даного автора (чи всіх авторів) по даній галузі можна використовувати ГИТ-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
v1.6.4
тут, у цьому прикладі, зробити детермінований вихід: це буде те саме, незалежно від того, коли ви клонували та / або брали з сховища git.
v1.6.4
дає мені:fatal: ambiguous argument 'v1.6.4': unknown revision or path not in the working tree.
git shortlog -sne
або, якщо ви бажаєте не включати злиттяgit shortlog -sne --no-merges
-s
є --summary
, -n
є --numbered
і [new] -e
- --email
показувати електронні листи авторів (і рахувати окремо одного автора з різною електронною адресою з урахуванням .mailmap
виправлень). Гарний дзвінок о --no-merges
.
Після перегляду Алекса та Герти3000 відповідь «s, я спробував скоротити однострочнікі:
В основному, використовуючи нуместат журналу git і не відслідковуючи кількість файлів змінених .
Git версії 2.1.0 на Mac OSX:
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 з допомогою оболонки однострочнікі добре, але на самому справі, є ще одна помилка, де пробілу зіпсують імена користувачів , якщо є різні кількості прогалин між ім'ям користувача і датою. Пошкоджені імена користувачів дадуть кілька рядків для підрахунку користувачів, і вам доведеться підсумовувати їх самостійно.
Ця невелика зміна вирішила для мене проблему:
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
Зауважте + після \ s, який буде споживати всі пробіли від назви до дати.
Насправді я додаю цю відповідь стільки для власної пам’яті, скільки для допомоги комусь іншому, оскільки це принаймні вдруге я гуглю тему :)
--show-email
до git blame -w
агрегації електронної пошти замість цього, оскільки деякі користувачі використовують різні Name
формати на різних комп’ютерах, а іноді двоє людей з тим самим іменем працюють в одному git.unsupported file type
але в іншому випадку, здається, це працює добре навіть з ними (це їх пропускає).
Ось короткий однокласник, який створює статистику для всіх авторів. Це набагато швидше, ніж рішення Дана вище за адресою https://stackoverflow.com/a/20414465/1102119 (шахта має складність у часі O (N) замість O (NM), де 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
--no-show-signature
, інакше люди, які підписують свої документи, не зараховуються.
count-lines = "!f() { 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; }; f"
. (Зверніть увагу, я перебуваю в Windows; можливо, вам доведеться використовувати різні види цитат)
@mmrobins @AaronM @ErikZ @JamesMishra надав варіанти, які мають усі спільні проблеми: вони просять git створити суміш інформації, яка не призначена для споживання сценарію, включаючи вміст рядка з сховища в тому ж рядку, а потім співставити безлад з регулярним виразом .
Це проблема, коли для деяких рядків не є дійсним текст 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
) примусову обробку на рівні байтів (це також відбувається, щоб значно прискорити grep з локалів на базі UTF-8).
Рішення було надано з рубіном посередині, perl є трохи доступнішим за замовчуванням, тут є альтернативою використання perl для поточних рядків автором.
git ls-files -z | xargs -0n1 git blame -w | perl -n -e '/^.*\((.*?)\s*[\d]{4}/; print $1,"\n"' | sort -f | uniq -c | sort -n
Окрім відповіді Чарльза Бейлі , ви можете додати -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(-)
На мою думку, остання дає більш реалістичне уявлення про те, який вплив людина мала на проект, оскільки перейменування файлу - це набагато менша операція, ніж написання файлу з нуля.
ви можете використовувати whodid ( 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>
=====================================================
-g
повинні були прийти перед назвою пакета, на macOS
. Просто намагаюся допомогти.
Ось швидкий сценарій рубіну, який підкручує вплив на користувача на заданий запит журналу.
Наприклад, для rubinius :
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
Я подав модифікацію короткої відповіді вище, але це було недостатньо для моїх потреб. Мені потрібно було вміти класифікувати як присвоєні рядки, так і рядки у кінцевому коді. Я також хотів розбити файли. Цей код не повторюється, він поверне результати лише для одного каталогу, але це гарний початок, якщо хтось захотів піти далі. Скопіюйте та вставте у файл та зробіть його виконуваним або запустіть за допомогою 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};
}
Для користувачів 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
git-quick-stats
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)
Цей сценарій тут зробить це. Помістіть його в avtorhip.sh, chmod + x it, і все готово.
#!/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 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
Ви хочете, щоб Гіт звинувачувався .
Існує варіант - show-stats для друку деяких, ну, статистичних даних.
blame
, але це насправді не дало статистичних даних, які я вважав, що ОП потребуватиме?
Запитання запитувало інформацію про конкретного автора, але багато відповідей були рішеннями, які повертають ранжировані списки авторів на основі їх рядків коду.
Це я шукав, але існуючі рішення були не зовсім ідеальними. Для інтересів людей, які можуть знайти це питання через Google, я вніс деякі вдосконалення щодо них і перетворив їх на сценарій оболонки, який я показую нижче. Повідомлення (яке я продовжуватиму підтримувати) можна знайти на моєму Github .
Там немає жодної залежності на будь-який 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
Найкращий на даний момент інструмент, який я визначив, - це гітінспектор. Він дає встановлений звіт на користувача, тиждень тощо. Ви можете встановити, як нижче, з npm
npm встановити -g gitinspector
Посилання для отримання більш детальної інформації
https://www.npmjs.com/package/gitinspector
https://github.com/ejwa/gitinspector/wiki/Документація
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
. Оскільки це збережено на моєму шляху, я можу дати команду git line-changes-by-author --before 2018-12-31 --after 2020-01-01
отримати звіт за 2019 рік. Як приклад. І якби я неправильно написав ім'я git, то підкаже правильний написання.
Ви можете скорегувати _get_repo_slug
підпункт так, щоб він включав лише останню частину, remote.origin.url
оскільки мої репозиції збережені як такі, так project/repo
і ваші можуть не бути.
git://git.lwn.net/gitdm.git
.