Jak uzyskać listę wszystkich nazw użytkowników autorów zatwierdzania Subversion?

83

Szukam wydajnego sposobu na uzyskanie listy unikalnych autorów zatwierdzeń dla repozytorium SVN jako całości lub dla danej ścieżki zasobów. Nie udało mi się znaleźć polecenia SVN specjalnie do tego (i nie oczekuję go), ale mam nadzieję, że może być lepszy sposób niż to, co próbowałem do tej pory w Terminalu (na OS X):

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

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

Każde z nich da mi jedno nazwisko autora w każdym wierszu, ale oba wymagają odfiltrowania sporej ilości dodatkowych informacji. Nie obsługują również duplikatów o tym samym nazwisku autora, więc w przypadku wielu zatwierdzeń przez kilku autorów istnieje mnóstwo nadmiarowości przepływającej przez sieć. Częściej niż nie chcę po prostu zobaczyć unikalne nazwy użytkowników autorów. (Właściwie może przydać się okazjonalne wywnioskowanie liczby zatwierdzeń dla każdego autora, ale nawet w takich przypadkach byłoby lepiej, gdyby zamiast tego przesłano zagregowane dane).

Generalnie pracuję z dostępem tylko do klienta, więc svnadminpolecenia są mniej przydatne, ale w razie potrzeby mógłbym poprosić administratora repozytorium o specjalną przysługę, jeśli jest to konieczne lub znacznie bardziej wydajne. Repozytoria, z którymi pracuję, mają dziesiątki tysięcy zatwierdzeń i wielu aktywnych użytkowników, i nie chcę nikomu przeszkadzać.

Quinn Taylor
źródło
6
Subversion nie indeksuje nazwisk autorów (są one tylko właściwością wersji), więc nie można tego zrobić bez skanowania całego dziennika; rozwiązania będą się różnić tylko kosztem zobowiązania.
Kevin Reid,

Odpowiedzi:

94

Aby odfiltrować duplikaty, należy przyjąć moc i rurę przez: sort | uniq. A zatem:

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

Nie zdziwiłbym się, gdyby to był sposób na zrobienie tego, o co prosisz. Narzędzia uniksowe często wymagają od użytkownika wymyślnego przetwarzania i analizy za pomocą innych narzędzi.

PS Pomyśl o tym, możesz połączyć grepi awk...

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

PPS według Kevina Reida ...

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

P 3 .S. Per kan, używanie pionowych kresek zamiast spacji jako separatorów pól, aby poprawnie obsługiwać nazwy ze spacjami (zaktualizowano również przykłady w Pythonie) ...

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

Aby uzyskać większą wydajność, możesz zrobić jedną linijkę Perla. Nie znam Perla za dobrze, więc skończyłbym na zrobieniu tego w Pythonie:

#!/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)

Lub, jeśli chcesz, liczy się:

#!/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])

Wtedy uciekłbyś:

svn log --quiet | ./authorfilter.py
Mike DeSimone
źródło
+1 za przydatną sugestię. Byłem tego świadomy, sortale nie uniq, i wydaje się, że ten ostatni przyjmuje -cparametr, który poprzedza liczbę wystąpień dla każdego wiersza. Nadal liczę na bardziej wydajny (i skalowalny) sposób, ale to załatwia sprawę w mgnieniu oka.
Quinn Taylor
2
Nawiasem mówiąc, jeśli masz pod ręką XPath, zapytanie //author/text()zwróci svn log --xmlsolidnie tylko nazwiska autorów . (Mac OS X ma xpathpolecenie, które prawie wykonuje tę pracę, ale generuje obcy tekst i nie można go skonfigurować tak, aby nie robił. Może jest coś innego.)
Kevin Reid
@Kevin, powinieneś dodać własną odpowiedź, aby ludzie mogli na Ciebie głosować. Podobają mi się wszystkie twoje komentarze, szczególnie wskazówka sort / uniq.
Quinn Taylor
1
Ponieważ nazwa użytkownika svn może zawierać spacje, lepiej byłoby użyć dokładniejszego filtrowaniaawk -F " \\\\| " '{print $2}'
kan
2
świetna odpowiedź, chociaż musiałem zmienić ostatni awk na svn log --quiet | awk -F ' \\\\| ' '/^r/ {print $3}' | sort -uinaczej, po prostu otrzymywałem pustą linię
MJar
51

W programie PowerShell ustaw swoją lokalizację na kopię roboczą i użyj tego polecenia.

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

Format wyjściowy svn.exe log --quietwygląda następująco:

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)

Odfiltruj reguły poziome za pomocą ? { $_ -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)

Podziel według, ' \| 'aby przekształcić rekord w tablicę.

$ '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)

Drugim elementem jest nazwa.

Utwórz tablicę z każdej linii i wybierz drugi element za pomocą % { ($_ -split ' \| ')[1] }.

tinkywinky
dispy
lala
po
tinkywinky

Zwróć unikalne wystąpienia za pomocą Sort -Unique. Sortuje to wyjście jako efekt uboczny.

dispy
lala
po
tinkywinky
Iain Samuel McLean Elder
źródło
1
W tym Sort -Uniqueprzypadku nie jest rozróżniana wielkość liter, należy użyć Sort-Object | Get-Unique –AsStringlub Select-Object -Uniquezamiast tego, aby sprawdzić wielkość liter.
Tom Kuijsten,
2
Alternatywnie:([xml](svn log --xml)).SelectNodes('//author') | % {$_.InnerText} | Select -Unique
Nathan Moinvaziri,
9

Musiałem to zrobić w Windows, więc użyłem portu Windows Super Sed ( http://www.pement.org/sed/ ) - i zastąpiłem polecenia AWK i GREP:

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

Używa "sortowania" okien, które może nie być obecne na wszystkich komputerach.

Adam Rofer
źródło
Stworzyłem również plik wsadowy, który iteruje w folderze i kompiluje unikalną listę wszystkich repozytoriów: pastebin.com/CXiqLddp
Adam Rofer
4

Jedno zdalne repozytorium, którego możesz użyć:

 svn log --quiet https://url/svn/project/ | grep "^r" | awk '{print $3}' | sort | uniq
lvthillo
źródło
Nie znalazłem tego polecenia, dopóki sam tego nie wymyśliłem ... Jeśli chcesz po prostu przekonać użytkowników zdalnego repozytorium, aby np. Przekonwertowali je na git (patrz git svn --help), jest to naprawdę przydatne jako checkout tylko do wykonania tego polecenia może zająć zbyt dużo czasu.
seyfahni
2
svn log  path-to-repo | grep '^r' | grep '|' | awk '{print $3}' | sort | uniq > committers.txt

To polecenie ma dodatkowe, grep '|'które eliminują fałszywe wartości. W przeciwnym razie, losowe zatwierdzenia zaczynające się od 'r'get włączone, a tym samym zwracane są słowa z komunikatów o zatwierdzeniach.

Crankparty
źródło
dlatego argument --quietlub -qjest używany w innych sugestiach. Spowoduje to wydrukowanie tylko nagłówków dziennika (wersja, autor i data, godzina)
v01pe Kwietnia
1

Rozwiązanie dla Windows 10.

  1. utwórz plik wsadowy printAllAuthor.bat
@echo off
for /f "tokens=3" %%a in ('svn log --quiet ^|findstr /r "^r"') do echo %%a
@echo on
  1. uruchom plik bat za pomocą sortpolecenia
printAllAuthor.bat | sort /unique >author.txt

PS:

  • Krok 2 wymaga uruchomienia pliku wsadowego z właściwą ścieżką. ustaw ścieżkę w% PATH% lub użyj właściwego formatu ścieżki systemu operacyjnego.
  • Krok 2 można również przekształcić w plik wsadowy w zależności od potrzeb.
kaoglish
źródło
0

PowerShell obsługuje XML, co eliminuje potrzebę analizowania wyjściowego ciągu znaków.

Oto krótki skrypt, którego użyłem na komputerze Mac, aby uzyskać unikalną listę użytkowników w wielu repozytoriach.

#!/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
Jason C
źródło
-2

Prostsza alternatywa:

find . -name "*cpp" -exec svn log -q {} \;|grep -v "\-\-"|cut -d "|" -f 2|sort|uniq -c|sort -n
Venki
źródło
Spowoduje to sprawdzenie tylko plików cpp, które istnieją w systemie plików w momencie uruchomienia.
echristopherson