Jak wyświetlić zatwierdzenia konkretnego użytkownika w dzienniku svn?

161

Jak wyświetlić zatwierdzenia konkretnego użytkownika w svn? Nie znalazłem żadnych przełączników do tego dla dziennika svn.

mimrock
źródło
10
Użyj --searchopcji z klientem Subversion 1.8 lub nowszym.
bahrep

Odpowiedzi:

258

Możesz użyć tego:

svn log | sed -n '/USERNAME/,/-----$/ p' 

Pokaże ci każde zatwierdzenie dokonane przez określonego użytkownika (NAZWA UŻYTKOWNIKA).

AKTUALIZACJA

Zgodnie z sugestią @bahrep, Subversion 1.8 zawiera --searchopcję.

yvoyer
źródło
6
To rozwiązanie jest idealne. Chciałbym zrozumieć, co robi, ale nie udało mi się znaleźć w dokumentacji seda niczego, co by to wyjaśniało. Czy ktoś ma jakieś informacje o tym, dlaczego to działa?
Matt Hulse,
1
+1 dla mnie też działa. Podobnie jak vi, w dystrybucjach systemów Unix / Linux sed jest prawdopodobnie bardziej wszechobecny niż Python - i dlatego nie ma potrzeby martwić się o instalację.
therobyouknow
10
@MattHulse to działa, ponieważ używa seda do dopasowania wszystkiego między dwoma określonymi wyrażeniami regularnymi (nazwa użytkownika i myślniki), a następnie nakazuje wydrukować to (the p).
Gijs,
5
@therobyouknow Nie, nie musisz wykonywać svn logna kopii roboczej. Możesz również określić swoje repozytorium, tj svn log https://your-svn-repo.
MBober,
4
Nie musisz już tego robić. Użyj klienta Subversion 1.8 lub nowszego, który obsługuje --searchopcję.
bahrep
101

Z Subversion 1.8 lub nowszym:

svn log --search johnsmith77 -l 50

Oprócz dopasowań autorskich, spowoduje to również wyświetlenie zatwierdzeń SVN, które zawierają tę nazwę użytkownika w komunikacie zatwierdzenia, co nie powinno mieć miejsca, jeśli nazwa użytkownika nie jest popularnym słowem.

-l 50Będzie ograniczyć wyszukiwanie do najnowszych 50 wpisów.

--search ARG

Filtruje komunikaty dziennika, aby wyświetlić tylko te, które pasują do wzorca wyszukiwania ARG.

Komunikaty dziennika są wyświetlane tylko wtedy, gdy podany wzorzec wyszukiwania jest zgodny z autorem, datą, tekstem komunikatu dziennika (o ile nie --quietjest używany) lub, jeśli --verbosepodano również opcję, ze zmienioną ścieżką.

Jeśli --searchpodano wiele opcji, komunikat dziennika jest wyświetlany, jeśli pasuje do któregokolwiek z podanych wzorców wyszukiwania.

Jeśli --limitjest używany, ogranicza liczbę przeszukiwanych komunikatów dziennika, a nie ogranicza wynik do określonej liczby zgodnych komunikatów dziennika.

http://svnbook.red-bean.com/en/1.8/svn.ref.svn.html#svn.ref.svn.sw.search

Michael Butler
źródło
1
@Izkata dodana w SVN 1.8: svnbook.red-bean.com/en/1.8/svn.ref.svn.c.log.html
bahrep
jeśli chcesz wyszukać więcej niż jednego autora, svn log --search foo --search bar -l 30. If multiple --search options are provided, a log message is shown if it matches any of the provided search patterns.
zhuguowei
To rozwiązanie może być również użyte z argumentem --diff (aby pokazać zmieniony kod)
joro
Jakikolwiek sposób na odfiltrowanie pojawiania się w komunikatach dotyczących zmian, jeśli nazwa użytkownika jest wspólną (częścią) słowa?
Tor Klingberg
17

svn nie ma wbudowanych opcji do tego. Ma svn log --xmlopcję, aby umożliwić ci samodzielne przeanalizowanie wyniku i pobranie interesujących części.

Możesz napisać skrypt, aby go przeanalizować, na przykład w Pythonie 2.6:

import sys
from xml.etree.ElementTree import iterparse, dump

author = sys.argv[1]
iparse = iterparse(sys.stdin, ['start', 'end'])

for event, elem in iparse:
    if event == 'start' and elem.tag == 'log':
        logNode = elem
        break

logentries = (elem for event, elem in iparse
                   if event == 'end' and elem.tag == 'logentry')

for logentry in logentries:
    if logentry.find('author').text == author:
        dump(logentry)
    logNode.remove(logentry)

Jeśli zapiszesz powyższe jako svnLogStripByAuthor.py, możesz nazwać to jako:

svn log --xml other-options | svnLogStripByAuthor.py user
Avi
źródło
Dlatego też dodałem tag „bash”.
mimrock
Możesz napisać skrypt narzędziowy, który go przeanalizuje - zobacz mój przykład
Avi
Nie mam zainstalowanego Pythona, ale chociaż mój problem został rozwiązany w niepowiązany sposób, zakładam, że Twoje rozwiązanie działa, dziękuję!
mimrock
3
Magia jest mocą. Python to Bash.
n611x007
13

Ponieważ wydaje się, że wszyscy skłaniają się ku Linuksowi (i inni): Oto odpowiednik systemu Windows:

svn log [SVNPath]|find "USERNAME"
user2197169
źródło
Dzięki! Klient używa systemu Windows, więc to naprawdę pomogło. To jest system zarządzany, nie mam uprawnień administratora i nie mogę zainstalować cygwin / perl / cokolwiek ...
n13
8
svn log | grep user

działa w większości.

Albo mówiąc dokładniej:

svn log | egrep 'r[0-9]+ \| user \|'
moinudin
źródło
Dzięki, ale nie widzę komunikatów o zmianach w ten sposób.
mimrock
@mimrock True. Możesz grep -Awyświetlać kontekst, ale ta liczba jest statyczna, podczas gdy komunikat zatwierdzenia ma zmienną długość. Możesz znaleźć rozwiązanie z sedem lub podobnym, ale to wysiłek. : P
moinudin
Działa to również w systemie Windows, jeśli zainstalujesz rozszerzenia GIT ( code.google.com/p/gitextensions ) i uruchomisz wiersz poleceń GIT Bash.
Contango,
1
@marcog Aby uzyskać pełną kompletność, weź tę listę poprawek i wykonaj kolejne połączenie tylko z nimi: | awk '{ print "-" $1 }' | xargs svn log
Izkata
5

Chociaż rozwiązanie yvoyer działa dobrze, tutaj jest rozwiązanie korzystające z wyjścia SVN XML i parsujące je xmlstarlet.

svn log --xml | xmlstarlet sel -t -m 'log/logentry' \
  --if "author = '<AUTHOR>'" \
  -v "concat('Revision ', @revision, ' ', date)" -n -v msg -n -n

Stąd możesz przejść do bardziej zaawansowanych zapytań XML.

mxgr
źródło
3

Oto moje rozwiązanie przy użyciu xslt. Niestety, xsltproc nie jest procesorem przesyłania strumieniowego, więc musisz określić limit dziennika. Przykładowe użycie:

svn log -v --xml --limit=500  | xsltproc --stringparam author yonran /path/to/svnLogFilter.xslt  - | xsltproc /path/to/svnLogText.xslt  - | less

svnLogFilter.xslt

<!--
svnLogFilter.xslt

Usage: (note: use double dashes; I can't do double dashes in a XML comment)
svn log -xml | xsltproc -stringparam author yonran svnLogFilter.xslt -
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:param name="author" select="''"/>
  <xsl:strip-space elements="log"/>
  <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
  <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'"/>
  <xsl:variable name="lowercaseAuthor" select="translate($author, $uppercase, $lowercase)"/>

<xsl:template match="/log">
  <xsl:copy>
    <xsl:apply-templates name="entrymatcher"/>
  </xsl:copy>
</xsl:template>

<xsl:template name="entrymatcher" match="logentry">
  <xsl:variable name="lowercaseChangeAuthor" select="translate(author, $uppercase, $lowercase)"/>
  <xsl:choose>
    <xsl:when test="contains($lowercaseChangeAuthor, $lowercaseAuthor)">
      <xsl:call-template name="insideentry"/>
    </xsl:when>
    <!--Filter out-->
    <xsl:otherwise/>
  </xsl:choose>
</xsl:template>


<xsl:template name="insideentry" match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

svnLogText.xslt

<!--
svnLogText.xslt

Usage: (note: use double dashes; I can't do double dashes in a XML comment)
svn log -xml -limit=1000 | xsltproc svnLogText.xslt -
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:param name="author" select="''"/>
  <xsl:param name="xml" select="false()"/>
  <xsl:output method="text"/>

<xsl:template match="/log">
  <xsl:apply-templates name="entrymatcher"/>
  <xsl:text>------------------------------------------------------------------------&#xa;</xsl:text>
</xsl:template>

<xsl:template name="entrymatcher" match="logentry">
  <xsl:text>------------------------------------------------------------------------&#xa;</xsl:text>
  <xsl:text>r</xsl:text><xsl:value-of select="@revision"/>
  <xsl:text> | </xsl:text>
  <xsl:value-of select="author"/>
  <xsl:text> | </xsl:text>
  <xsl:value-of select="date"/>
  <xsl:text>&#xa;&#xa;</xsl:text>
  <xsl:if test="paths">
    <xsl:text>Changed paths:&#xa;</xsl:text>
    <xsl:for-each select="paths/path">
      <xsl:text>   </xsl:text>
      <xsl:value-of select="@action"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="."/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
  </xsl:if>
  <xsl:text>&#xa;</xsl:text>
  <xsl:value-of select="msg"/>
  <xsl:text>&#xa;</xsl:text>
</xsl:template>

</xsl:stylesheet>
yonran
źródło
1

Możesz użyć Perla do filtrowania dziennika według nazwy użytkownika i utrzymywania komunikatów o zatwierdzeniach. Po prostu ustaw zmienną $ /, która decyduje o tym, co stanowi „linię” w Perlu. Jeśli ustawisz to jako separator wpisów dziennika SVN, Perl będzie czytać po jednym rekordzie na raz i wtedy powinieneś być w stanie dopasować nazwę użytkownika w całym rekordzie. Zobacz poniżej:

svn log | perl -ne 'BEGIN{$/="------------------------------------------------------------------------"} print if /USERNAME/'
Stathis Sideris
źródło
Ten działa, nawet jeśli chcesz znaleźć kilka wyników dziennika na podstawie nazwy pliku!
walmik
1

Aby uzyskać różnice wraz z checkin.

Pobierz numery wersji do pliku:

svn log | sed -n '/USERNAME/,/-----$/ p'| grep "^r" 

Teraz przeczytaj plik i wykonaj różnicę dla każdej wersji:

while read p; do   svn log -v"$p" --diff ; done < Revisions.txt 
user668958
źródło
0

Napisałem skrypt w Pythonie:

#!/usr/bin/python
# coding:utf-8

import sys

argv_len = len(sys.argv)


def help():
    print 'Filter svnlog by user or date!       '
    print 'USEAGE: svnlog [ARGs]                '
    print 'ARGs:                                '
    print '    -n[=name]:                       '
    print '      filter by the special [=name]\n'
    print '    -t[=date]:                       '
    print '      filter by the special [=date]  '
    print 'EXP:                                 '
    print '1. Filter ruikye\'s commit log       \n'
    print '     svn log -l 50 | svnlog -n=ruikye\n'


if not argv_len - 1:
    help()
    quit()

author = ''
date = ''

for index in range(1, argv_len):
    argv = sys.argv[index]
    if argv.startswith('-n='):
        author = argv.replace('-n=', '')
    elif argv.startswith('-t='):
        date = argv.replace('-t=', '')
    else:
        help()
        quit()

if author == '' and date == '':
    help()
    quit()


SPLIT_LINE =
    '------------------------------------------------------------------------'
src = ''.join(sys.stdin.readlines()).replace('\n\n', '\n')
lines = src.split(SPLIT_LINE)

for line in lines:
    if author in line and date in line:
        print SPLIT_LINE, line

if len(lines):
    print SPLIT_LINE

I użyć:

$ mv svnlog.py svnlog          

$ chmod a+x svnlog             

$ cd /usr/local/bin
$ ln -s ~/mycmd/svnlog filter 

$ svn log | filter -n=ruikye -t=2015-03-04
ruikye
źródło
Istniejąca odpowiedź, która używa XML i właściwie ją analizuje, będzie bardziej niezawodna i elastyczna.
tripleee