如何获取所有 Subversion 提交作者用户名的列表?

Posted

技术标签:

【中文标题】如何获取所有 Subversion 提交作者用户名的列表?【英文标题】:How to get a list of all Subversion commit author usernames? 【发布时间】:2011-01-30 12:00:26 【问题描述】:

我正在寻找一种有效的方法来获取整个 SVN 存储库或给定资源路径的唯一提交作者列表。我无法找到专门为此的 SVN 命令(并且不要指望一个),但我希望可能有一种更好的方法,我迄今为止在终端(在 OS X 上)中尝试过的方法:

svn log --quiet | grep "^r" | awk 'print $3'

svn log --quiet --xml | grep author | sed -E "s:</?author>::g"

其中任何一个都会给我每行一个作者姓名,但它们都需要过滤掉相当多的额外信息。他们也不处理相同作者姓名的重复,因此对于少数作者的大量提交,有大量冗余流过网络。很多时候,我只想查看唯一的作者用户名。 (实际上,有时可能可以方便地推断出每个作者的提交计数,但即使在这些情况下,如果改为发送聚合数据会更好。)

我通常使用仅限客户端的访问权限,因此svnadmin 命令的用处不大,但如果有必要,如果绝对必要或更高效,我也许可以请求存储库管理员的特别帮助。我正在使用的存储库有数以万计的提交和许多活跃用户,我不想给任何人带来不便。

【问题讨论】:

Subversion 没有index 作者姓名(它们只是一个修订属性),所以没有扫描整个日志就没有办法;解决方案只会因每次提交的成本而异。 【参考方案1】:

要过滤掉重复项,请将您的输出和管道通过:sort | uniq。因此:

svn log --quiet | grep "^r" | awk 'print $3' | sort | uniq

如果这是按照您的要求行事的方式,我不会感到惊讶。 Unix 工具通常希望用户使用其他工具进行精美的处理和分析。

附:想想看,可以合并grepawk...

svn log --quiet | awk '/^r/ print $3' | sort | uniq

附言根据凯文·里德...

svn log --quiet | awk '/^r/ print $3' | sort -u

P3.S. Per kan,使用竖线而不是空格作为字段分隔符,以正确处理带有空格的名称(也更新了 Python 示例)...

svn log --quiet | awk -F ' \\\\|' '/^r/ print $2' | sort -u

为了提高效率,您可以使用 Perl 单线。我不太了解 Perl,所以我最终会用 Python 来做:

#!/usr/bin/env python
import sys
authors = set()
for line in sys.stdin:
    if line[0] == 'r':
        authors.add(line.split('|')[1].strip())
for author in sorted(authors):
    print(author)

或者,如果你想要计数:

#!/usr/bin/env python
from __future__ import print_function # Python 2.6/2.7
import sys
authors = 
for line in sys.stdin:
    if line[0] != 'r':
        continue
    author = line.split('|')[1].strip()
    authors.setdefault(author, 0)
    authors[author] += 1
for author in sorted(authors):
    print(author, authors[author])

然后你会运行:

svn log --quiet | ./authorfilter.py

【讨论】:

+1 获得有用的建议。我知道sort,但不知道uniq,似乎后者采用-c 参数而不是每行的出现次数。我仍然希望有一种更有效(和可扩展)的方式,但这在紧要关头可以解决问题。 顺便说一句,如果您有方便的 XPath,那么查询 //author/text() 将可靠地从 svn log --xml 中获取作者姓名。 (Mac OS X 有一个xpath 命令,几乎可以完成这项工作,但会产生无关的文本,并且无法配置为不这样做。也许还有别的东西。) @Kevin,您应该添加自己的答案,以便人们为您投票。我喜欢你所有的 cmets,尤其是 sort/uniq 提示。 由于svn用户名可以有空格,所以最好使用更精确的过滤awk -F " \\\\| " 'print $2' 很好的答案,虽然我不得不将最后一个 awk 更改为 svn log --quiet | awk -F ' \\\\| ' '/^r/ print $3' | sort -u 否则我只是得到空行【参考方案2】:

我必须在 Windows 中执行此操作,因此我使用了 Super Sed 的 Windows 端口 (http://www.pement.org/sed/) - 并替换了 AWK 和 GREP 命令:

svn log --quiet --xml | sed -n -e "s/<\/\?author>//g" -e "/[<>]/!p" | sort | sed "$!N; /^\(.*\)\n\1$/!P; D" > USERS.txt

这使用了可能并非在所有机器上都存在的窗口“排序”。

【讨论】:

我还制作了一个批处理文件,它遍历文件夹并编译所有存储库的唯一列表:pastebin.com/CXiqLddp【参考方案3】:
svn log  path-to-repo | grep '^r' | grep '|' | awk 'print $3' | sort | uniq > committers.txt

此命令具有额外的grep '|',可消除错误值。 否则,会包含以'r' 开头的随机提交,从而返回提交消息中的单词。

【讨论】:

这就是为什么在其他建议中使用 --quiet-q 参数的原因。这只会打印日志标题(修订、作者和日期、时间)【参考方案4】:

在 PowerShell 中,将您的位置设置为工作副本并使用此命令。

svn.exe log --quiet |
?  $_ -notlike '-*'  |
%  ($_ -split ' \| ')[1]  |
Sort -Unique

svn.exe log --quiet 的输出格式如下:

r20209 | tinkywinky | 2013-12-05 08:56:29 +0000 (Thu, 05 Dec 2013)
------------------------------------------------------------------------
r20208 | dispy | 2013-12-04 16:33:53 +0000 (Wed, 04 Dec 2013)
------------------------------------------------------------------------
r20207 | lala | 2013-12-04 16:28:15 +0000 (Wed, 04 Dec 2013)
------------------------------------------------------------------------
r20206 | po | 2013-12-04 14:34:32 +0000 (Wed, 04 Dec 2013)
------------------------------------------------------------------------
r20205 | tinkywinky | 2013-12-04 14:07:54 +0000 (Wed, 04 Dec 2013)

? $_ -notlike '-*' 过滤掉水平线。

r20209 | tinkywinky | 2013-12-05 08:56:29 +0000 (Thu, 05 Dec 2013)
r20208 | dispy | 2013-12-04 16:33:53 +0000 (Wed, 04 Dec 2013)
r20207 | lala | 2013-12-04 16:28:15 +0000 (Wed, 04 Dec 2013)
r20206 | po | 2013-12-04 14:34:32 +0000 (Wed, 04 Dec 2013)
r20205 | tinkywinky | 2013-12-04 14:07:54 +0000 (Wed, 04 Dec 2013)

' \| ' 拆分,将记录转换为数组。

$ 'r20209 | tinkywinky | 2013-12-05 08:56:29 +0000 (Thu, 05 Dec 2013)' -split ' \| '
r20209
tinkywinky
2013-12-05 08:56:29 +0000 (Thu, 05 Dec 2013)

第二个元素是名称。

为每一行创建一个数组,并用% ($_ -split ' \| ')[1] 选择第二个元素。

tinkywinky
dispy
lala
po
tinkywinky

使用 Sort -Unique 返回唯一的匹配项。这会将输出排序为副作用。

dispy
lala
po
tinkywinky

【讨论】:

Sort -Unique 不区分大小写,您应该使用Sort-Object | Get-Unique –AsStringSelect-Object -Unique 来进行区分大小写的检查。 或者:([xml](svn log --xml)).SelectNodes('//author') | % $_.InnerText | Select -Unique【参考方案5】:

一个更简单的选择:

find . -name "*cpp" -exec svn log -q  \;|grep -v "\-\-"|cut -d "|" -f 2|sort|uniq -c|sort -n

【讨论】:

这只会查看运行时文件系统中存在的 cpp 文件。【参考方案6】:

Powershell 支持 XML,无需解析字符串输出。

这是我在 Mac 上使用的快速脚本,用于获取跨多个存储库的唯一用户列表。

#!/usr/bin/env pwsh

$repos = @(
    'Common/'
    'Database/'
    'Integration/'
    'Reporting/'
    'Tools/'
    'Web/'
    'Webservices/'
)

foreach ($repo in $repos) 
    $url = "https://svn.example.com:8443/svn/$repo"
    $users += ([Xml](svn log $url --xml)).log.logentry.author | Sort-Object -Unique


$users | Sort-Object -Unique

【讨论】:

【参考方案7】:

一个您可以使用的远程存储库:

 svn log --quiet https://url/svn/project/ | grep "^r" | awk 'print $3' | sort | uniq

【讨论】:

我没有找到这个命令,直到我自己想出来......如果你只是想让远程存储库的用户例如将其转换为 git(请参阅git svn --help)这非常有用,因为仅执行此命令的结帐可能会花费太多时间。【参考方案8】:

Windows 10 的解决方案。

    创建批处理文件printAllAuthor.bat
@echo off
for /f "tokens=3" %%a in ('svn log --quiet ^|findstr /r "^r"') do echo %%a
@echo on
    使用sort 命令运行bat 文件
printAllAuthor.bat | sort /unique >author.txt

PS:

步骤 2 需要以正确的路径运行批处理文件。在 %PATH% 中设置路径或使用正确的操作系统路径格式。 步骤2也可以根据需要制作成批处理文件。

【讨论】:

以上是关于如何获取所有 Subversion 提交作者用户名的列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止没有注释的 Subversion 提交?

svn 命令行怎么解决冲突

没有作者颠覆 svn 提交

subversion - 从匹配模式中获取修订号

Subversion:如何获取所有活动的,未合并的分支的列表

SVN到Git的一键迁移脚本(保留所有分支、Tag及提交记录)