Git blame: статистика



Как я могу "злоупотреблять" обвинением (или какой-то более подходящей функцией и/или в сочетании с командами оболочки), чтобы дать мне статистику того, сколько строк (кода) в настоящее время находится в репозитории, происходящем от каждого коммиттера?



Пример:



Committer 1: 8046 Lines
Committer 2: 4378 Lines
507   10  
git

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 .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 ''

дать список файлов (через канал) можно использовать 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 это может быть полезно.

установка и использование:

  1. $ gem install git_fame
  2. $ cd /path/to/gitdir
  3. $ 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 нетронутой.

git shortlog -sn

Это покажет список коммитов для каждого автора.

Проверьте команду 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

    Ничего не найдено.