Как сгенерировать статистику Git изменений для каждого типа файла? - PullRequest
4 голосов
/ 08 мая 2020

Сколько строк кода было добавлено и удалено для каждого типа файла в репозитории git? Желательно иметь возможность запрашивать эту статистику за прошлые X коммиты. Скажем, я бы запросил это для прошлых 100 коммитов, мой ожидаемый результат будет примерно таким:

.css, 100 files changed,  2879 insertions(+), 1134 deletions(-)
.js,   17 files changed,   415 insertions(+),  502 deletions(-)
.php,   6 files changed,   478 insertions(+),  176 deletions(-)
.py,   10 files changed,   156 insertions(+),   56 deletions(-)

Это должно быть каким-то образом возможно, но я не могу найти решение. Я прочитал этот вопрос , а также попытался использовать Gitstats и RepoExplorer .

Ответы [ 2 ]

5 голосов
/ 10 мая 2020

Есть два способа вычислить нужные данные. Один из них - вычислить различия для диапазонов фиксации в целом, а другой - вычислить каждую фиксацию индивидуально и суммировать значения. Последний может быть больше первого, если к файлу прикоснуться несколько раз. Поскольку вы не указали, я покажу вам оба.

Чтобы вычислить первое, что проще, вы можете использовать следующую команду:

git diff --numstat BASE_COMMIT.. | ruby -rset -e '
  x = {}
  while gets
    line = $_.chomp.split("\t")
    chunks = line[2].split(".")
    next if chunks.length == 1
    type = chunks[-1]
    x[type] ||= [0, 0, Set.new]
    2.times { |i| x[type][i] += line[i].to_i }
    x[type][2] << line[2]
  end
  x.sort_by { |(k, v)| k }.each do |(type, (add, del, set))|
    puts ".#{type} #{set.length} files changed, #{add} insertions(+), #{del} deletions(-)"
  end'

Здесь используется git diff --numstat для обработки коммитов из BASE_COMMIT в текущую ветвь и выполнения операции. Если вы хотите обработать последние X коммиты, напишите HEAD~X. Обратите внимание, что при этом игнорируются файлы без суффикса, а двоичные файлы обрабатываются как без добавления или удаления строк. Он также не создает выровненных столбцов, но вы можете добавить это, если хотите. Вы также можете использовать другой язык или сценарий вместо однострочного.

Если вы хотите выполнить сумму всех отдельных коммитов, замените вызов git diff на это:

git rev-list BASE_COMMIT.. | xargs -I{} git diff --numstat {}^..{}
2 голосов
/ 10 мая 2020

Я бы разделил эту проблему на подзадачи:

Raw log magi c

Я бы начал с определения отправной точки, с которой проблема относительно проста

Если вы запустите

git log

, вы увидите список итогов фиксации. Конечно, это неприятно - пока.

Теперь давайте ограничим наш домен, допустим, нас интересует статистика c для последних 100 коммитов:

git log -100

Теперь количество рассматриваемых коммитов является подходящим. Но мы по-прежнему не видим добавлений и удалений, давайте исправим это:

git log -100 --stat

Стало лучше, правда? Давайте улучшим его дальше:

git log -5 --stat --format=""

Намного, намного лучше. Теперь для каждой фиксации у вас есть «полезные строки», то есть строки, содержащие количество изменений и последнюю строку формата

9 файлов изменено, 189 вставок (+), 1 удаление (-)

в основном, если у вас есть строка, содержащая «файлы изменены» или «файл изменен», вам нужно игнорировать ее, если у вас нет файла с таким именем. Все остальные строки являются полезными необработанными входными данными.

Алгоритм для статистики

Вам нужна структура данных, которая будет содержать тип файла в качестве ключа и пару чисел в качестве значения. Первое число - это количество минусов, второе число - количество плюсов. Псевдокод:

For Each ln In Lines Do
    If (Not ln.Replace("files", "file").Contains("file changed")) And ln.Contains(".") Then
        FileExtension = ln.Substring(ln.IndexOf(".") + 1, ln.IndexOf(" "))
        If (Not Extensions.Has(FileExtension)) Then
            Extensions(FileExtension) = [0, 0]
        End
        UsefulSubstring = ln.Substring(ln.LastIndexOf(" ") + 1)
        For Each char In UsefulSubstring Do
            If char = '+' Then
                Extensions(FileExtension)[1] = Extensions(FileExtension)[1] + 1
            Else
                Extensions(FileExtension)[0] = Extensions(FileExtension)[0] + 1
            End If
        End For
    End If
End For

Этот алгоритм построит ваш вывод, который вам нужно поместить в вывод консоли в том формате, который вы предпочитаете. Итак, вы можете вызвать эту программу с нужным вам вводом. Вы даже можете встроить в проект команду git log. Это не очень большая задача, поэтому если вы потратите на это несколько часов, а может и меньше, вы получите нужный результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...