Git blame: статистика
Как я могу "злоупотреблять" обвинением (или какой-то более подходящей функцией и/или в сочетании с командами оболочки), чтобы дать мне статистику того, сколько строк (кода) в настоящее время находится в репозитории, происходящем от каждого коммиттера?
Пример:
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 -- | 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 .cgit authors '*/*.[ch]' # look for all files recursively ending in .c or .hgit 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 ''дать список файлов (через канал) можно использовать xargs для вызова команды и распространения аргументов. Команды, которые позволяют несколько файлов, которые будут обработаны obmit в
-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 "приведенная выше команда выведет авторов строк, содержащих хотя бы один символ без пробела. Вы также можете использовать match
\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} .*//' -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} .*//' -e 's/ +$//'сортировать список авторов, и иметь uniq подсчитать количество последовательно повторяющихся строк
|sort|uniq -cпример:
1334 Maneater 1924 Another guy 37195 Brian Ruby 1482 Anna Lambda
git summary --lineС git-extras пакет-это именно то, что вам нужно.
оформить документы на git-extras-git-summary
вывод будет выглядеть так:
project : TestProject lines : 13397 authors : 8927 John Doe 66.6% 4447 Jane Smith 33.2% 23 Not Committed Yet 0.2%
решение Эрика было потрясающим, но у меня были некоторые проблемы с диакритикой (несмотря на мой
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 .strip if $_ =~ /^\w{8} \((.*?)\s*\d{4}-\d{2}-\d{2}/' | \ sort | uniq -c | sort -rgтакже Примечание!--2--> вместо
sedпотому что это двоичный доморощенный устанавливает, оставив систему sed нетронутой.
Проверьте команду gitstats, доступную из http://gitstats.sourceforge.net/
вот основной фрагмент из ответа @Alex, который фактически выполняет операцию агрегирования строк вины. Я сократил его, чтобы оперировать на одним файлом а не набор файлов.
git blame --line-porcelain path/to/file.txt | grep "^author " | sort | uniq -c | sort -nrя публикую это здесь, потому что я часто возвращаюсь к этому ответу и перечитываю сообщение и перевариваю примеры, чтобы извлечь часть, которую я ценю, она облагается налогом. Он также не является достаточно общим для моего случая использования; его область действия-для целого C проект.
мне нравится перечислять статистику за файл, полученную с помощью bash
forитератор вместоxargsпоскольку я нахожу xargs менее читаемым и трудным для использования/запоминания, преимущество/недостатки xargs vs for следует обсудить в другом месте.вот практический фрагмент, который покажет результаты для каждого файла в отдельности:
for file in $(git ls-files); do \ echo $file; \ git blame --line-porcelain $file \ | grep "^author " | sort | uniq -c | sort -nr; \ echo; \ doneи я протестировал, запустив этот stright в оболочке bash, это ctrl+c safe, если вам нужно поместить это внутрь bash скрипт вам может понадобиться ловушка на SIGINT и SIGTERM если вы хотите, чтобы пользователь мог разорвать ваш цикл for.
У меня есть это решение, которое подсчитывает обвиняемые строки во всех текстовых файлах (за исключением двоичных файлов, даже версионных):
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
Comments