Этот вопрос также немного устарел, но я создал сценарий, который может быть полезен для простой отчетности/аудита Subversion и для отслеживания изменений, внесенных в репозиторий SVN, и я хотел поделиться им. Она извлекает информацию о коммитах SVN аналогично команде «svnlook», но имеет пару преимуществ. Во-первых, он позволяет перебирать все версии репозитория, чтобы отслеживать все внесенные изменения. Во-вторых, информация печатается в табличном формате, разделенном табуляцией (как в командах Unix, таких как ps или df), который удобен для чтения человеком и легко анализируется или импортируется в электронную таблицу, что отлично подходит для отчетов. Его также можно вызывать или встраивать в хук после фиксации SVN.
Это Perl-скрипт с именем svn-commit-info.pl, который принимает три аргумента. Первый — это путь к репозиторию, и он является обязательным. Второй, необязательный, — это шаблон файла для поиска. И третий, также необязательный, — номер версии для запроса.
Если выполняется только с путем к репозиторию, он выводит в STDOUT информацию о файлах, затронутых всеми фиксациями, сделанными в репозитории. Например, предположим, что репозиторий хранится в /svn/repos/test на сервере Subversion:
$ perl svn-commit-info.pl /svn/repos/test
# Repository: /svn/repos/test
# Fields: Action, Revision, Date, Author, Bytes, Path
# Actions: A = New, D = Deleted, U = Updated
A 1 2017-01-31 17:21:19 Samsa <DIR> TestProject/
A 2 2017-01-31 17:21:33 Samsa 815 TestProject/.project
A 2 2017-01-31 17:21:33 Samsa <DIR> TestProject/.settings/
A 2 2017-01-31 17:21:33 Samsa 564 TestProject/.settings/.jsdtscope
A 2 2017-01-31 17:21:33 Samsa <DIR> TestProject/www/
A 3 2017-01-31 17:27:48 David 355 TestProject/www/test.html
A 3 2017-01-31 17:27:48 David <DIR> TestProject/www/css/
A 3 2017-01-31 17:27:48 David 9622 TestProject/www/css/logo.jpg
A 3 2017-01-31 17:27:48 David 1231 TestProject/www/css/reportstyle.css
A 3 2017-01-31 17:27:48 David 168345 TestProject/www/css/style.css
U 4 2017-02-01 10:48:34 Samsa 183260 TestProject/www/css/style.css
D 5 2017-02-01 12:51:26 David 355 TestProject/www/test.html
Поля, разделенные табуляцией: выполненная операция, номер редакции, дата и время, автор редакции, размер файла в байтах (если файл не является каталогом, отмеченным строкой «‹DIR›») и путь к затронутому файлу в репозитории. Первые три строки содержат ориентированные на человека комментарии к выходным данным.
Вывод первой команды может занять много времени, если репозиторий большой, с большим количеством файлов или ревизий. Если вы хотите отслеживать изменения, внесенные в конкретный файл (или набор файлов), лучше указать шаблон файла (который, по сути, является регулярным выражением Perl). Например, чтобы получить информацию об изменениях, внесенных в файл style.css:
$ perl svn-commit-info.pl /svn/repos/test style.css
Если вас интересует конкретная ревизия, вы можете указать третий параметр. Например, распечатать все изменения третьей ревизии с учетом того, что '.' соответствует любому символу в регулярном выражении Perl:
$ perl svn-commit-info.pl /svn/repos/test . 3
И, конечно же, вы можете использовать возможности фильтров и конвейерной обработки Unix для выполнения более сложных запросов, например, для поиска всех изменений, сделанных пользователем Дэвидом:
$ svn-commit-info.pl /svn/repos/test | grep David
Чтобы найти все созданные файлы размером >= 1 Мб:
$ svn-commit-info.pl /svn/repos/test | awk '$1 = "A" && $6 ~ /[0-9]/ && $6 >= 1024*1024'
Сценарий использует стандартную команду Subversion "svnlook", но в остальном он автономен. Есть две вспомогательные функции для создания команды и получения вывода «svnlook», а затем последовательных вызовов команды для составления вывода. Для этого требуется Subversion >= 1.7, и он был протестирован на Perl 5.10.
#!/usr/bin/env perl
use strict;
my $SVNLOOKCMD = "/usr/bin/svnlook";
my @FIELDS = qw(Action Revision Date Author Bytes Path);
# Builds and returns the "svnlook" command
sub svnlook_cmd {
my($repository, $action, $revision, @varargs) = @_;
my $cmd = $SVNLOOKCMD;
$cmd.= " -r $revision" if $revision;
$cmd.= " $action '$repository'";
$cmd.= join "", map { " '$_'" } @varargs;
$cmd.= '|';
return $cmd;
}
# Executes the "svnlook" command and returns the output lines
sub svnlook_output {
my($repository, $action, $revision, @varargs) = @_;
open(my $svnlookfh, svnlook_cmd $repository, $action, $revision, @varargs);
my @output = <$svnlookfh>;
close $svnlookfh;
chomp @output;
return wantarray ? @output : $output[0];
}
my($repository, $file, $revision) = @ARGV;
unless($repository) {
# 'repository' is the only mandatory argument
print STDERR "$0 <repository> [<file>] [<revision>]\n";
print STDERR "\t<repository> = path of Subversion repository\n";
print STDERR "\t<file> = file pattern to search for (regular expression)\n";
print STDERR "\t<revision> = commit revision number\n";
exit 1;
}
$file = "." unless $file;
my $first = $revision ? $revision : 1;
my $last = $revision ? $revision : svnlook_output $repository, "youngest";
print "# Repository: $repository\n";
print "# Fields: ", join(", ", @FIELDS), "\n";
print "# Actions: A = New, D = Deleted, U = Updated\n";
for(my $rev = $first; $rev <= $last; $rev++) {
my $author = "";
my $date = "";
foreach my $line (svnlook_output $repository, "changed", $rev) {
if($line =~ /$file/i) {
unless($date) {
$date = svnlook_output $repository, "date", $rev;
$date =~ s|^(\S+) (\S+).*$|\1 \2|;
}
$author = uc svnlook_output $repository, "author", $rev unless $author;
my($action, $path) = split /\s+/, $line, 2;
my $size;
if($path =~ m|/$|) {
$size = sprintf("%12s", "<DIR>");
} else {
$size = svnlook_output $repository, "filesize", $rev, $path;
$size = sprintf("%12d", $size);
}
print join("\t", $action, $rev, $date, $author, $size, $path), "\n";
}
}
}
exit 0;
Надеюсь, это поможет и извините за длинный пост.
person
David Gil del Rosal
schedule
02.02.2017