How to display a specific user's commits in svn? I didn't find any switches for that for svn log.
-
10Use `--search` option with Subversion 1.8 or newer client. – bahrep Jan 06 '16 at 11:19
11 Answers
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.

- 7,476
- 5
- 33
- 37
-
6This solution is perfect. I would like to understand what it is doing but I haven't been able to find anything in the sed documentation that explains it. Anyone have any info about why this works? – Matt Hulse Jun 04 '12 at 17:38
-
1+1 Works for me too. Like vi, on Unix/Linux distros sed is perhaps more ubiquitous than Python - and therefore no need to worry about installation. – therobyouknow Jul 20 '12 at 15:32
-
1P.S. you need to run this in a folder that contains your `working copy` of the repository (i.e. that which you obtained from `checkout` ) – therobyouknow Jul 20 '12 at 15:34
-
10@MattHulse it works because it uses sed to match everything between two specified regular expressions (the username and the dashes), and then tells it to print that (the `p`). – Gijs Dec 21 '12 at 06:18
-
5@therobyouknow No, you don't need to perform `svn log` on a working copy. You can also specify your repository, i.e. `svn log https://your-svn-repo`. – MBober Jul 08 '13 at 06:28
-
1Works for me as well. For understanding the trick observe: Ranges by patterns chapter in http://www.grymoire.com/Unix/Sed.html – Gur Feb 13 '14 at 07:27
-
4No need to do this anymore. Use Subversion 1.8 or newer client that supports `--search` option. – bahrep Jan 06 '16 at 11:25
-
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

- 1
- 1

- 6,079
- 3
- 38
- 46
-
1@Izkata added in SVN 1.8: http://svnbook.red-bean.com/en/1.8/svn.ref.svn.c.log.html – bahrep Jan 06 '16 at 11:26
-
if you want to search more than one author, `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 Mar 17 '16 at 12:30
-
This solution could be used with --diff argument too (to show changed code) – JRr May 15 '17 at 14:39
-
Any way to filter out appearances in commit messages, if the username is a common (part of) a word? – Tor Klingberg Jun 14 '19 at 10:40
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

- 286,113
- 34
- 456
- 610

- 19,934
- 4
- 57
- 70
-
-
-
I don't have python installed, but while my problem is solved in an unrelated way, I assume your solution is working, thank you! – mimrock Dec 21 '10 at 14:56
-
3
Since everyone seems to be leaning toward linux (et al): Here is the Windows equivalent:
svn log [SVNPath]|find "USERNAME"

- 146,324
- 30
- 291
- 331

- 147
- 1
- 5
-
Thanks! A client is using Windows so that really helped. This is a managed system, I don't have admin rights and can't install cygwin/perl/whatever... – n13 Apr 02 '13 at 04:47
svn log | grep user
works for the most part.
Or to be more accurate:
svn log | egrep 'r[0-9]+ \| user \|'

- 134,091
- 45
- 190
- 216
-
-
@mimrock True. You could grep's `-A` to display context, but this number is static whereas the commit message is of variable length. You could make a solution with sed or similar, but that's effort. :P – moinudin Dec 21 '10 at 13:58
-
This also works under Windows, if you install GIT Extensions (http://code.google.com/p/gitextensions/) and start a GIT Bash command prompt. – Contango Jan 14 '14 at 11:08
-
1@marcog For true completeness, take that list of revisions and make another call with just them: `| awk '{ print "-" $1 }' | xargs svn log` – Izkata May 15 '14 at 16:23
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.

- 300
- 3
- 7
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>------------------------------------------------------------------------
</xsl:text>
</xsl:template>
<xsl:template name="entrymatcher" match="logentry">
<xsl:text>------------------------------------------------------------------------
</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>

</xsl:text>
<xsl:if test="paths">
<xsl:text>Changed paths:
</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>
</xsl:text>
</xsl:for-each>
</xsl:if>
<xsl:text>
</xsl:text>
<xsl:value-of select="msg"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>

- 18,156
- 8
- 72
- 97
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
.

- 29,961
- 12
- 103
- 150
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/'

- 624
- 4
- 10
-
This one works even if you want to find a bunch of log results based on a file name! – walmik Jun 06 '12 at 17:21
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

- 58,485
- 12
- 111
- 141

- 11
- 1
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

- 1
- 2
-
The existing answer which uses XML and properly parses it is going to be more robust and flexible. – tripleee Mar 06 '15 at 06:46