Виноват: статистика
Как я могу "оскорбить" вину (или какую-то более подходящую функцию и / или в сочетании с командами оболочки), чтобы дать мне статистику того, сколько строк (кода) в данный момент находится в репозитории, происходящем от каждого коммиттера?
Пример вывода:
Committer 1: 8046 Lines
Committer 2: 4378 Lines
10 ответов
Обновить
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
Затем мы фильтруем выходные данные по появлению "автора", сортируем список и подсчитываем повторяющиеся строки по:
grep "^author "|sort|uniq -c|sort -nr
Заметка
Другие ответы на самом деле отфильтровывают строки, которые содержат только пробелы.
grep -Pzo "author [^\n]*\n([^\n]*\n){10}[\w]*[^\w]"|grep "author "
Команда выше будет печатать авторов строк, содержащих хотя бы один непробельный символ. Вы также можете использовать матч \w*[^\w#]
что также исключит строки, где первый непробельный символ не является #
(комментарий на многих языках сценариев).
Я написал гем под названием 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/ +$//'
Сортировать список авторов и подсчитать количество последовательно повторяющихся строк.
|sort|uniq -c
Пример вывода:
1334 Maneater
1924 Another guy
37195 Brian Ruby
1482 Anna Lambda
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%
Решение Эрика было потрясающим, но у меня были некоторые проблемы с диакритическими знаками (несмотря на мои LC_*
переменные окружения устанавливаются якобы правильно) и шум просачивается по строкам кода, в которых действительно есть даты. Мой сед-фу плох, поэтому я получил этот фрагмент Франкенштейна с рубином, но он работает для меня безупречно на 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
потому что это бинарная установка homebrew, оставляя систему без изменений.
Вот основной фрагмент ответа @Alex, который фактически выполняет операцию агрегации линий обвинения. Я сократил его, чтобы работать с одним файлом, а не с набором файлов.
git blame --line-porcelain path/to/file.txt | grep "^author " | sort | uniq -c | sort -nr
Я публикую это здесь, потому что я часто возвращаюсь к этому ответу, перечитываю пост и перевариваю примеры, чтобы извлечь часть, которую я ценю, которая облагается налогом. И при этом это не достаточно универсально для моего случая использования; его объем для всего проекта C.
Мне нравится перечислять статистику по файлам, полученную через bash for
итератор вместо xargs
поскольку я считаю, что 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 безопасен ctrl + c, если вам нужно поместить его в сценарий bash, вам может понадобиться перехватывать SIGINT и SIGTERM, если вы хотите, чтобы пользователь мог разорвать цикл for.
Проверьте команду gitstats, доступную на http://gitstats.sourceforge.net/
Это работает в любом каталоге исходной структуры репо, если вы хотите проверить определенный исходный модуль.
find . -name '*.c' | xargs -n1 git blame --line-porcelain | grep "^author "|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
switch, я добавил его, потому что он игнорирует изменения пробелов.
Производительность на моей машине была в пользу Powershell (~50 с против ~65 для того же репо), хотя решение Bash работало под WSL2.
У меня есть это решение, которое подсчитывает обвиняемые строки во всех текстовых файлах (исключая двоичные файлы, даже версионные):
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
Сделал свой собственный скрипт, который представляет собой комбинацию @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
Функция Bash, предназначенная для работы с одним исходным файлом в MacOS.
function glac {
# git_line_author_counts
git blame -w "$1" | sed -E "s/.*\((.*) +[0-9]{4}-[0-9]{2}.*/\1/g" | sort | uniq -c | sort -nr
}