Как отобразить коммиты конкретного пользователя в логе svn?

161

Как отобразить коммиты конкретного пользователя в SVN? Я не нашел никаких переключателей для этого для журнала SVN.

mimrock
источник
10
Используйте --searchопцию с Subversion 1.8 или более новым клиентом.
Бахреп

Ответы:

258

Вы можете использовать это:

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

Он покажет вам каждый коммит, сделанный указанным пользователем (USERNAME).

ОБНОВИТЬ

Как предполагает @bahrep, Subversion 1.8 поставляется с --searchопцией.

yvoyer
источник
6
Это решение идеально. Я хотел бы понять, что он делает, но я не смог найти ничего в документации sed, которая бы это объясняла. У кого-нибудь есть информация о том, почему это работает?
Мэтт Халс
1
+1 У меня тоже работает. Как и vi, в дистрибутивах Unix / Linux Sed более распространен, чем Python, и поэтому не нужно беспокоиться об установке.
therobyouknow
10
@MattHulse работает, потому что он использует sed для сопоставления всего между двумя указанными регулярными выражениями (имя пользователя и тире), а затем говорит ему напечатать это (the p).
Gijs
5
@ therobyouknow Нет, вам не нужно выполнять svn logна рабочей копии. Вы также можете указать хранилище, то есть svn log https://your-svn-repo.
MBober
4
Нет необходимости делать это больше. Используйте Subversion 1.8 или более новый клиент, который поддерживает --searchопцию.
Бахреп
101

С Subversion 1.8 или новее:

svn log --search johnsmith77 -l 50

Помимо совпадений авторов, это также включает SVN-коммиты, которые содержат это имя пользователя в сообщении фиксации, что не должно происходить, если ваше имя пользователя не является общим словом.

-l 50Будет ограничить поиск последних 50 записей.

--search ARG

Фильтры регистрируют сообщения, чтобы показать только те из них, которые соответствуют шаблону поиска ARG.

Сообщения журнала отображаются только в том случае, если предоставленный шаблон поиска соответствует какому-либо из автора, дате, тексту сообщения журнала (если --quietне используется) или, если --verboseопция также указана, измененному пути.

Если предусмотрено несколько --searchпараметров, отображается сообщение журнала, если оно соответствует любому из предоставленных шаблонов поиска.

Если --limitиспользуется, он ограничивает количество искомых сообщений журнала, а не ограничивает вывод определенным количеством соответствующих сообщений журнала.

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

Майкл Батлер
источник
1
@Izkata добавлена в SVN 1.8: svnbook.red-bean.com/en/1.8/svn.ref.svn.c.log.html
bahrep
если вы хотите найти более одного автора, 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
Это решение может быть использовано с --diff аргументом тоже (показать измененный код)
JORO
Любой способ отфильтровать появления в сообщениях коммита, если имя пользователя является общим (частью) словом?
Тор Клингберг
17

SVN не поставляется со встроенными опциями для этого. У него есть svn log --xmlопция, позволяющая вам разобрать вывод самостоятельно и получить интересные детали.

Вы можете написать скрипт для его анализа, например, в 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)

Если вы сохраните вышеупомянутое как svnLogStripByAuthor.py, вы можете вызвать его как:

svn log --xml other-options | svnLogStripByAuthor.py user
Avi
источник
Вот почему я тоже добавил тег 'bash'.
Мимрок
Вы можете написать служебный скрипт для его анализа - см. Мой пример
Avi
У меня не установлен Python, но, хотя моя проблема решена несвязанным способом, я предполагаю, что ваше решение работает, спасибо!
Мимрок
3
Магия это сила. Питон это Bash.
n611x007,
13

Поскольку все, кажется, склоняются к Linux (и др.): Вот эквивалент Windows:

svn log [SVNPath]|find "USERNAME"
user2197169
источник
Спасибо! Клиент использует Windows, так что это действительно помогло. Это управляемая система, у меня нет прав администратора и я не могу установить cygwin / perl / что угодно ...
n13
8
svn log | grep user

работает по большей части.

Или чтобы быть более точным:

svn log | egrep 'r[0-9]+ \| user \|'
moinudin
источник
Спасибо, но я не вижу сообщений о коммитах таким образом.
Мимрок
@ Mimrock Правда. Вы можете использовать grep -Aдля отображения контекста, но это число статическое, тогда как сообщение фиксации имеет переменную длину. Вы можете сделать решение с помощью sed или аналогичного, но это усилие. : P
Мойнудин
Это также работает под Windows, если вы устанавливаете расширения GIT ( code.google.com/p/gitextensions ) и запускаете командную строку GIT Bash.
Контанго
1
@marcog Для истинной полноты возьмите этот список ревизий и сделайте еще один звонок только с ними: | awk '{ print "-" $1 }' | xargs svn log
Izkata
5

В то время как решение yvoyer работает нормально, здесь один из них использует вывод XML SVN, анализируя его xmlstarlet.

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

Отсюда вы можете перейти к более сложным XML-запросам.

mxgr
источник
3

Вот мое решение с использованием xslt. Однако, к сожалению, xsltproc не является потоковым процессором, поэтому вы должны указать ограничение log. Пример использования:

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
источник
1

Вы можете использовать Perl для фильтрации журнала по имени пользователя и поддержки сообщений коммита. Просто установите переменную $ /, которая решает, что представляет собой «строку» в Perl. Если вы установите это в качестве разделителя записей журнала SVN, Perl будет читать по одной записи за раз, и тогда вы сможете сопоставить имя пользователя во всей записи. Увидеть ниже:

svn log | perl -ne 'BEGIN{$/="------------------------------------------------------------------------"} print if /USERNAME/'
Статис Сидерис
источник
Это работает, даже если вы хотите найти кучу результатов журнала на основе имени файла!
Walmik
1

Чтобы получить различия вместе с регистрацией.

Получить номера ревизий в файл:

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

Теперь прочитайте файл и выполните diff для каждой ревизии:

while read p; do   svn log -v"$p" --diff ; done < Revisions.txt 
user668958
источник
0

Я должен был написать скрипт на 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

и использовать:

$ 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
источник
Существующий ответ, который использует XML и правильно анализирует его, будет более надежным и гибким.
tripleee