Comment afficher les commits d'un utilisateur spécifique dans le journal svn?

161

Comment afficher les commits d'un utilisateur spécifique dans svn? Je n'ai trouvé aucun commutateur pour cela pour svn log.

mimrock
la source
10
Utilisez l' --searchoption avec Subversion 1.8 ou un client plus récent.
bahrep

Réponses:

258

Vous pouvez utiliser ceci:

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

Il vous montrera chaque commit effectué par l'utilisateur spécifié (USERNAME).

METTRE À JOUR

Comme suggéré par @bahrep, la subversion 1.8 est livrée avec une --searchoption.

yvoyer
la source
6
Cette solution est parfaite. J'aimerais comprendre ce qu'il fait mais je n'ai rien trouvé dans la documentation sed qui l'explique. Quelqu'un a des informations sur pourquoi cela fonctionne?
Matt Hulse le
1
+1 Fonctionne aussi pour moi. Comme vi, sur les distributions Unix / Linux, sed est peut-être plus omniprésent que Python - et donc pas besoin de s'inquiéter de l'installation.
therobyouknow
10
@MattHulse cela fonctionne car il utilise sed pour faire correspondre tout ce qui se trouve entre deux expressions régulières spécifiées (le nom d'utilisateur et les tirets), puis lui dit d'imprimer cela (le p).
Gijs
5
@therobyouknow Non, vous n'avez pas besoin de jouer svn logsur une copie de travail. Vous pouvez également spécifier votre référentiel, c'est-à-dire svn log https://your-svn-repo.
MBober
4
Plus besoin de faire ça. Utilisez Subversion 1.8 ou un client plus récent prenant en charge l' --searchoption.
bahrep
101

Avec Subversion 1.8 ou version ultérieure:

svn log --search johnsmith77 -l 50

Outre les correspondances d'auteur, cela affichera également les commits SVN contenant ce nom d'utilisateur dans le message de validation, ce qui ne devrait pas se produire si votre nom d'utilisateur n'est pas un mot courant.

Le -l 50limitera la recherche aux 50 dernières entrées.

--search ARG

Filtre les messages du journal pour n'afficher que ceux qui correspondent au modèle de recherche ARG.

Les messages de journal ne s'affichent que si le modèle de recherche fourni correspond à un auteur, une date, un texte de message de journal (sauf s'il --quietest utilisé) ou, si l' --verboseoption est également fournie, un chemin modifié.

Si plusieurs --searchoptions sont fournies, un message de journal s'affiche s'il correspond à l'un des modèles de recherche fournis.

Si --limitest utilisé, il limite le nombre de messages de journal recherchés, plutôt que de restreindre la sortie à un nombre particulier de messages de journal correspondants.

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

Michael Butler
la source
1
@Izkata ajouté dans SVN 1.8: svnbook.red-bean.com/en/1.8/svn.ref.svn.c.log.html
bahrep
si vous voulez rechercher plus d'un auteur, 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
Cette solution pourrait également être utilisée avec l'argument --diff (pour afficher le code modifié)
joro
Existe-t-il un moyen de filtrer les apparences dans les messages de validation, si le nom d'utilisateur est un (partie d'un) mot commun?
Tor Klingberg le
17

svn n'est pas livré avec des options intégrées pour cela. Il a une svn log --xmloption, pour vous permettre d'analyser la sortie vous-même et d'obtenir les parties intéressantes.

Vous pouvez écrire un script pour l'analyser, par exemple en Python 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)

Si vous enregistrez ce qui précède sous le nom svnLogStripByAuthor.py, vous pouvez l'appeler comme suit:

svn log --xml other-options | svnLogStripByAuthor.py user
Avi
la source
C'est pourquoi j'ai également ajouté la balise «bash».
mimrock
Vous pouvez écrire un script utilitaire pour l'analyser - voir mon exemple
Avi
Je n'ai pas installé python, mais bien que mon problème soit résolu d'une manière indépendante, je suppose que votre solution fonctionne, merci!
mimrock
3
La magie est puissante. Python est Bash.
n611x007
13

Puisque tout le monde semble pencher vers linux (et al): voici l'équivalent Windows:

svn log [SVNPath]|find "USERNAME"
user2197169
la source
Merci! Un client utilise Windows, ce qui a vraiment aidé. Ceci est un système géré, je n'ai pas les droits d'administrateur et je ne peux pas installer cygwin / perl / peu importe ...
n13
8
svn log | grep user

fonctionne pour la plupart.

Ou pour être plus précis:

svn log | egrep 'r[0-9]+ \| user \|'
moinudin
la source
Merci, mais je ne vois pas les messages de validation de cette façon.
mimrock
@mimrock Vrai. Vous pouvez grep -Apour afficher le contexte, mais ce nombre est statique alors que le message de validation est de longueur variable. Vous pourriez faire une solution avec sed ou similaire, mais c'est un effort. : P
moinudin
Cela fonctionne également sous Windows, si vous installez les extensions GIT ( code.google.com/p/gitextensions ) et démarrez une invite de commande GIT Bash.
Contango
1
@marcog Pour être vraiment complet, prenez cette liste de révisions et | awk '{ print "-" $1 }' | xargs svn log
passez
5

Bien que la solution d'voyer fonctionne correctement, en voici une qui utilise la sortie XML de SVN, en l'analysant avec xmlstarlet.

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

À partir de là, vous pouvez accéder à des requêtes XML plus avancées.

mxgr
la source
3

Voici ma solution en utilisant xslt. Malheureusement, xsltproc n'est pas un processeur de streaming, vous devez donc donner une limite au journal. Exemple d'utilisation:

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
la source
1

Vous pouvez utiliser Perl pour filtrer le journal par nom d'utilisateur et gérer les messages de validation. Définissez simplement la variable $ / qui décide de ce qui constitue une "ligne" en Perl. Si vous définissez ceci sur le séparateur des entrées du journal SVN, Perl lira un enregistrement à la fois et vous devriez alors pouvoir faire correspondre le nom d'utilisateur dans tout l'enregistrement. Voir ci-dessous:

svn log | perl -ne 'BEGIN{$/="------------------------------------------------------------------------"} print if /USERNAME/'
Stathis Sideris
la source
Celui-ci fonctionne même si vous voulez trouver un tas de résultats de journal basés sur un nom de fichier!
walmik
1

Pour OBTENIR des différences avec l'enregistrement.

Récupérez les numéros de révision dans un fichier:

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

Maintenant, lisez le fichier et exécutez diff pour chaque révision:

while read p; do   svn log -v"$p" --diff ; done < Revisions.txt 
user668958
la source
0

J'avais écrit un script par Python:

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

et utilise:

$ 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
la source
La réponse existante, qui utilise XML et analyse correctement, sera plus robuste et flexible.
tripleee