2010-03-22 14 views
58

Ich suche nach einem effizienten Weg, um die Liste der eindeutigen Commit-Autoren für ein SVN-Repository als Ganzes oder für einen bestimmten Ressourcenpfad zu erhalten. Ich war nicht in der Lage, einen SVN-Befehl speziell dafür zu finden (und erwarte nicht einen), aber ich hoffe, dass es einen besseren Weg gibt, was ich bisher in Terminal (unter OS X) versucht habe:Wie bekomme ich eine Liste aller Subversion-Commit-Autoren-Benutzernamen?

Einer dieser beiden gibt mir einen Autorenname pro Zeile, aber beide erfordern eine ausreichende Menge an zusätzlichen Informationen zu filtern. Sie verarbeiten auch keine Duplikate mit dem gleichen Autorennamen, so dass für viele Commits von wenigen Autoren Tonnen von Redundanz über die Leitung fließen. Meistens möchte ich nur die eindeutigen Benutzernamen des Autors sehen. (Es tatsächlich könnte nützlich sein, um die Zählung für jeden Autor gelegentlich begehen zu schließen, aber auch in diesen Fällen wäre es besser, wenn die aggregierten Daten über statt gesendet wurden.)

ich in der Regel mit client- arbeiten bin Nur Zugriff, also svnadmin Befehle sind weniger nützlich, aber wenn nötig, kann ich einen besonderen Gefallen des Repository-Admins stellen, wenn dies unbedingt notwendig oder sehr viel effizienter ist. Die Repositories, mit denen ich arbeite, haben Zehntausende von Commits und viele aktive Benutzer, und ich möchte niemanden belästigen.

+6

Subversion nicht * index * Autorennamen (sie sind nur eine Revisionseigenschaft), so gibt es keine Möglichkeit, es zu tun, ohne das gesamte Protokoll abgetastet wird; Lösungen variieren nur nach den Kosten pro Commit. –

Antwort

70

Um Duplikate herauszufiltern, nehmen Sie Ihre Ausgabe und führen Sie durch: . Also:

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

Ich wäre nicht überrascht, wenn dies der Weg ist zu tun, was Sie fragen. Unix-Tools erwarten oft, dass der Benutzer mit anderen Werkzeugen komplexe Verarbeitungen und Analysen durchführt.

P.S. Kommen Sie, daran zu denken, können Sie die grep und awk fusionieren können ...

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

P.P.S. Per Kevin Reid ...

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

P .S. Per kan, die vertikalen Balken anstelle von Räumen als Feldtrennzeichen verwenden, um richtig Namen mit Leerzeichen zu verarbeiten (auch die Python Beispiele aktualisiert) ...

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

Für effizienter zu gestalten, könnten Sie ein Perl-Einzeiler tun. Ich weiß Perl nicht so gut, also würde ich aufzuwickeln es in Python zu tun:

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

Oder, wenn Sie zählt wollten:

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

Dann würden Sie laufen:

svn log --quiet | ./authorfilter.py 
+0

+1 für den nützlichen Vorschlag. Ich kannte "sort", aber nicht "uniq", und es scheint, dass letzterer einen '-c' Parameter als die Anzahl der Vorkommen für jede Zeile vornimmt. Ich hoffe immer noch auf eine effizientere (und skalierbare) Art und Weise, aber das macht den Trick zur Not. –

+5

'sort -u' hat' sort | uniq' in einem Befehl. –

+1

Übrigens, wenn Sie XPath handlich haben, dann wird die Abfrage '// author/text()' nur die Autorennamen aus 'svn log --xml' robust erhalten. (Mac OS X hat einen Befehl 'xpath', der * fast * diesen Job ausführt, aber überflüssigen Text erzeugt und nicht konfiguriert werden kann. Vielleicht gibt es noch etwas.) –

9

ich hatte dies in Windows zu tun, also habe ich die Windows-Portierung von super Sed (http://www.pement.org/sed/) - und ersetzt die AWK & GREP-Befehle:

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

Dies verwendet Windows "sort", die möglicherweise nicht auf allen Computern vorhanden sind.

+0

Ich habe auch eine Batch-Datei, die durch einen Ordner iteriert und kompiliert eine eindeutige Liste aller Repositories gemacht: http://pastebin.com/CXiqLddp –

2
svn log path-to-repo | grep '^r' | grep '|' | awk '{print $3}' | sort | uniq > committers.txt 

Dieser Befehl verfügt über die zusätzliche grep '|', die falsche Werte eliminiert. Andernfalls werden Random-Commits, die mit 'r' beginnen, eingeschlossen und somit werden Wörter von Commit-Nachrichten zurückgegeben.

+0

Deshalb wird das Argument '--quiet' oder' -q' in den anderen Vorschlägen verwendet. Dies druckt nur die Log-Header (Revision, Autor und Datum, Uhrzeit) – v01pe

34

Setzen Sie in PowerShell Ihren Standort auf die Arbeitskopie und verwenden Sie diesen Befehl.

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

Das Ausgabeformat von svn.exe log --quiet sieht wie folgt aus:

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) 

Filter mit ? { $_ -notlike '-*' } die horizontalen Regeln aus.

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) 

Split durch ' \| ' einen Datensatz in einem Array zu drehen.

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

Das zweite Element ist der Name.

Erstellen Sie ein Array für jede Linie und wählen Sie das zweite Element mit % { ($_ -split ' \| ')[1] }.

tinkywinky 
dispy 
lala 
po 
tinkywinky 

Return einzigartige Vorkommen mit Sort -Unique. Dies sortiert die Ausgabe als Nebeneffekt.

dispy 
lala 
po 
tinkywinky 
+7

+1 Für diejenigen von uns steckte auf Windows. – CrazyPyro

+0

Die 'Sort-Unique 'unterscheidet nicht zwischen Groß- und Kleinschreibung, Sie sollten' Sort-Object | verwenden Get-Unique-AsString' oder 'Select-Object-Unique', um eine Groß-/Kleinschreibung zu überprüfen. –

+1

Alternativ: '([xml] (svn log --xml)). SelectNodes ('// author') | % {$ _. Innerer Text} | Select -Unique –

-2

Eine einfachere Alternative:

find . -name "*cpp" -exec svn log -q {} \;|grep -v "\-\-"|cut -d "|" -f 2|sort|uniq -c|sort -n 
+0

Dies würde nur cpp-Dateien anzeigen, die zum Zeitpunkt der Ausführung im Dateisystem vorhanden sind. – echristopherson