Как получить список всех имён авторов коммитов Subversion?

83

Я ищу эффективный способ получить список уникальных авторов коммитов для репозитория SVN в целом или для заданного пути к ресурсу. Мне не удалось найти команду SVN специально для этого (и не ожидаю ее), но я надеюсь, что может быть лучший способ, чем то, что я пробовал до сих пор в Терминале (в OS X):

svn log --quiet | grep "^r" | awk '{print $3}'

svn log --quiet --xml | grep author | sed -E "s:</?author>::g"

Любой из них даст мне по одному имени автора в строке, но оба требуют отфильтровывать изрядное количество дополнительной информации. Они также не обрабатывают дубликаты одного и того же автора, поэтому при большом количестве коммитов несколькими авторами по сети течет тонна избыточности. Чаще всего я просто хочу увидеть уникальные имена пользователей авторов. (На самом деле может быть удобно при случае вывести количество фиксаций для каждого автора, но даже в этих случаях было бы лучше, если бы вместо этого отправлялись агрегированные данные.)

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

Куинн Тейлор
источник
6
Subversion не индексирует имена авторов (это просто свойство редакции), поэтому нет способа сделать это без сканирования всего журнала; решения будут отличаться только стоимостью фиксации.
Кевин Рид,

Ответы:

94

Для того, чтобы отфильтровать дубликаты, возьмите выход и через трубу: sort | uniq. Таким образом:

svn log --quiet | grep "^r" | awk '{print $3}' | sort | uniq

Я не удивлюсь, если это будет способ сделать то, о чем вы просите. Инструменты Unix часто ожидают, что пользователь будет выполнять сложную обработку и анализ с помощью других инструментов.

PS Если задуматься, можно объединить grepи awk...

svn log --quiet | awk '/^r/ {print $3}' | sort | uniq

PPS Пер Кевин Рид ...

svn log --quiet | awk '/^r/ {print $3}' | sort -u

P 3 .S. Per kan, используя вертикальные полосы вместо пробелов в качестве разделителей полей, чтобы правильно обрабатывать имена с пробелами (также обновлены примеры Python) ...

svn log --quiet | awk -F ' \\\\|' '/^r/ {print $2}' | sort -u

Для большей эффективности вы можете сделать однострочную версию Perl. Я не так хорошо знаю Perl, поэтому я бы сделал это на Python:

#!/usr/bin/env python
import sys
authors = set()
for line in sys.stdin:
    if line[0] == 'r':
        authors.add(line.split('|')[1].strip())
for author in sorted(authors):
    print(author)

Или, если вы хотите подсчетов:

#!/usr/bin/env python
from __future__ import print_function # Python 2.6/2.7
import sys
authors = {}
for line in sys.stdin:
    if line[0] != 'r':
        continue
    author = line.split('|')[1].strip()
    authors.setdefault(author, 0)
    authors[author] += 1
for author in sorted(authors):
    print(author, authors[author])

Тогда вы бы бежали:

svn log --quiet | ./authorfilter.py
Майк Дезимоун
источник
+1 за полезное предложение. Я знал, sortно не знал uniq, и, похоже, последний принимает -cпараметр, а не добавляет количество вхождений для каждой строки. Я все еще надеюсь на более эффективный (и масштабируемый) способ, но в крайнем случае это помогает.
Куинн Тейлор,
2
Кстати, если у вас есть под рукой XPath, то запрос //author/text()будет svn log --xmlнадежно извлекать только имена авторов . (В Mac OS X есть xpathкоманда, которая почти выполняет эту работу, но выдает посторонний текст и не может быть сконфигурирована для этого. Может быть, есть что-то еще.)
Кевин Рид,
@Kevin, ты должен добавить свой ответ, чтобы люди могли проголосовать за тебя. Мне нравятся все ваши комментарии, особенно совет sort / uniq.
Куинн Тейлор,
1
Поскольку в имени пользователя svn могут быть пробелы, было бы лучше использовать более точную фильтрациюawk -F " \\\\| " '{print $2}'
kan
2
отличный ответ, хотя мне пришлось изменить последний из awk, svn log --quiet | awk -F ' \\\\| ' '/^r/ {print $3}' | sort -uиначе я просто получал пустую строку
MJar
51

В PowerShell укажите местоположение рабочей копии и используйте эту команду.

svn.exe log --quiet |
? { $_ -notlike '-*' } |
% { ($_ -split ' \| ')[1] } |
Sort -Unique

Формат вывода svn.exe log --quietвыглядит следующим образом:

r20209 | tinkywinky | 2013-12-05 08:56:29 +0000 (Thu, 05 Dec 2013)
------------------------------------------------------------------------
r20208 | dispy | 2013-12-04 16:33:53 +0000 (Wed, 04 Dec 2013)
------------------------------------------------------------------------
r20207 | lala | 2013-12-04 16:28:15 +0000 (Wed, 04 Dec 2013)
------------------------------------------------------------------------
r20206 | po | 2013-12-04 14:34:32 +0000 (Wed, 04 Dec 2013)
------------------------------------------------------------------------
r20205 | tinkywinky | 2013-12-04 14:07:54 +0000 (Wed, 04 Dec 2013)

Отфильтруйте горизонтальные правила с помощью ? { $_ -notlike '-*' }.

r20209 | tinkywinky | 2013-12-05 08:56:29 +0000 (Thu, 05 Dec 2013)
r20208 | dispy | 2013-12-04 16:33:53 +0000 (Wed, 04 Dec 2013)
r20207 | lala | 2013-12-04 16:28:15 +0000 (Wed, 04 Dec 2013)
r20206 | po | 2013-12-04 14:34:32 +0000 (Wed, 04 Dec 2013)
r20205 | tinkywinky | 2013-12-04 14:07:54 +0000 (Wed, 04 Dec 2013)

Разделить на, ' \| 'чтобы превратить запись в массив.

$ 'r20209 | tinkywinky | 2013-12-05 08:56:29 +0000 (Thu, 05 Dec 2013)' -split ' \| '
r20209
tinkywinky
2013-12-05 08:56:29 +0000 (Thu, 05 Dec 2013)

Второй элемент - это имя.

Составьте массив из каждой строки и выберите второй элемент с помощью % { ($_ -split ' \| ')[1] }.

tinkywinky
dispy
lala
po
tinkywinky

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

dispy
lala
po
tinkywinky
Иэн Сэмюэл Маклин Старший
источник
1
Параметр Sort -Uniqueнечувствителен к регистру, вы должны использовать Sort-Object | Get-Unique –AsStringили Select-Object -Uniqueвместо него, чтобы получить проверку с учетом регистра.
Tom Kuijsten
2
В качестве альтернативы:([xml](svn log --xml)).SelectNodes('//author') | % {$_.InnerText} | Select -Unique
Натан Моинвазири 01
9

Мне пришлось сделать это в Windows, поэтому я использовал порт Super Sed для Windows ( http://www.pement.org/sed/ ) - и заменил команды AWK и GREP:

svn log --quiet --xml | sed -n -e "s/<\/\?author>//g" -e "/[<>]/!p" | sort | sed "$!N; /^\(.*\)\n\1$/!P; D" > USERS.txt

При этом используется «сортировка» окон, которая может присутствовать не на всех машинах.

Адам Рофер
источник
Я также сделал командный файл, который выполняет итерацию по папке и составляет уникальный список всех репозиториев: pastebin.com/CXiqLddp
Адам Рофер
4

Один удаленный репозиторий, который вы можете использовать:

 svn log --quiet https://url/svn/project/ | grep "^r" | awk '{print $3}' | sort | uniq
lvthillo
источник
Я не нашел эту команду, пока не разобрался сам ... Если вы просто хотите, чтобы пользователи удаленного репозитория, например, преобразовали его в git (см. git svn --help), Это действительно полезно в качестве проверки только для выполнения этой команды может занять слишком много времени.
seyfahni
2
svn log  path-to-repo | grep '^r' | grep '|' | awk '{print $3}' | sort | uniq > committers.txt

У этой команды есть дополнительная grep '|'функция, исключающая ложные значения. В противном случае случайные коммиты, начиная с 'r'get включены, и, таким образом, возвращаются слова из сообщений фиксации.

чудак
источник
вот почему аргумент --quietили -qиспользуется в других предложениях. Это печатает только заголовки журнала (редакция, автор и дата, время)
v01pe
1

Решение для windows 10.

  1. создать командный файл printAllAuthor.bat
@echo off
for /f "tokens=3" %%a in ('svn log --quiet ^|findstr /r "^r"') do echo %%a
@echo on
  1. запустить bat-файл с sortкомандой
printAllAuthor.bat | sort /unique >author.txt

PS:

  • На шаге 2 нужно запустить командный файл с правильным путем. либо укажите путь в% PATH%, либо используйте правильный формат пути ОС.
  • Шаг 2 также может быть преобразован в пакетный файл в соответствии с вашими потребностями.
каоглиш
источник
0

Powershell поддерживает XML, что устраняет необходимость синтаксического анализа вывода строк.

Вот быстрый скрипт, который я использовал на Mac, чтобы получить уникальный список пользователей в нескольких репозиториях.

#!/usr/bin/env pwsh

$repos = @(
    'Common/'
    'Database/'
    'Integration/'
    'Reporting/'
    'Tools/'
    'Web/'
    'Webservices/'
)

foreach ($repo in $repos) {
    $url = "https://svn.example.com:8443/svn/$repo"
    $users += ([Xml](svn log $url --xml)).log.logentry.author | Sort-Object -Unique
}

$users | Sort-Object -Unique
Джейсон С
источник
-2

Более простая альтернатива:

find . -name "*cpp" -exec svn log -q {} \;|grep -v "\-\-"|cut -d "|" -f 2|sort|uniq -c|sort -n
Венки
источник
Это будет смотреть только на файлы cpp, которые существуют в файловой системе во время его запуска.
echristopherson