How to display a specific user's commits in svn log?

SvnBashVersion Control

Svn Problem Overview


How to display a specific user's commits in svn? I didn't find any switches for that for svn log.

Svn Solutions


Solution 1 - Svn

You could use this:

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

It will show you every commit made by the specified user (USERNAME).

UPDATE

As suggested by @bahrep, subversion 1.8 comes with a --search option.

Solution 2 - Svn

With Subversion 1.8 or later:

svn log --search johnsmith77 -l 50

Besides author matches, this will also turn up SVN commits that contain that username in the commit message, which shouldn't happen if your username is not a common word.

The -l 50 will limit the search to the latest 50 entries.

> --search ARG > > Filters log messages to show only those that match the search pattern ARG. > > Log messages are displayed only if the provided search pattern matches any of the author, date, log message text (unless --quiet is used), or, if the --verbose option is also provided, a changed path. > > If multiple --search options are provided, a log message is shown if it matches any of the provided search patterns. > > If --limit is used, it restricts the number of log messages searched, rather than restricting the output to a particular number of matching log messages.

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

Solution 3 - Svn

svn doesn't come with built-in options for this. It does have an svn log --xml option, to allow you to parse the output yourself, and get the interesting parts.

You can write a script to parse it, for example, in 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)

If you save the above as svnLogStripByAuthor.py, you could call it as:

svn log --xml other-options | svnLogStripByAuthor.py user

Solution 4 - Svn

Since everyone seems to be leaning toward linux (et al): Here is the Windows equivalent:

svn log [SVNPath]|find "USERNAME"

Solution 5 - Svn

svn log | grep user

works for the most part.

Or to be more accurate:

svn log | egrep 'r[0-9]+ \| user \|'

Solution 6 - Svn

While yvoyer's solution works fine, here is one making use of SVN's XML output, parsing it with xmlstarlet.

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

From here you could go into more advanced XML queries.

Solution 7 - Svn

Here’s my solution using xslt. Unfortunately, though, xsltproc is not a streaming processor, so you have to give log a limit. Example usage:

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>

Solution 8 - Svn

Beginning with Subversion 1.8, you can use --search and --search-and command-line options with svn log command.

So it should be as simple as running svn log --search JohnDoe.

Solution 9 - Svn

You can use Perl to filter the log by username and maintain the commit messages. Just set the $/ variable which decides what constitutes a "line" in Perl. If you set this to the separator of the entries of the SVN log, Perl will read one record at a time and then you should be able to match the the username in the entire record. See below:

svn log | perl -ne 'BEGIN{$/="------------------------------------------------------------------------"} print if /USERNAME/'

Solution 10 - Svn

To GET diffs along with the checkin.

Get the revision numbers into a file:

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

Now read through the file & executing diff for each revision:

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

Solution 11 - Svn

I had write a script by 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

and use:

$ 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmimrockView Question on Stackoverflow
Solution 1 - SvnyvoyerView Answer on Stackoverflow
Solution 2 - SvnMichael ButlerView Answer on Stackoverflow
Solution 3 - SvnAviView Answer on Stackoverflow
Solution 4 - Svnuser2197169View Answer on Stackoverflow
Solution 5 - SvnmoinudinView Answer on Stackoverflow
Solution 6 - SvnmxgrView Answer on Stackoverflow
Solution 7 - SvnyonranView Answer on Stackoverflow
Solution 8 - SvnbahrepView Answer on Stackoverflow
Solution 9 - SvnStathis SiderisView Answer on Stackoverflow
Solution 10 - Svnuser668958View Answer on Stackoverflow
Solution 11 - SvnruikyeView Answer on Stackoverflow