gitolite 是一个很常用的 git 仓库管理软件,可以通过命令行方式便捷操作自己拥有权限的项目仓库。不过不是所有的操作都可以通过命令完成,很多还是需要通知 gitolite 管理员来统一修改配置然后生效。比如通过 hook 发邮件这件事情。邮件收件人地址肯定每个项目就不一样,这个还要让管理员逐一来改,就不太好。所以这里实现了一个 mailinglist 的命令行操作子命令。
注意这里修改的 hooks 是针对整个 gitolite 的总 hooks 目录。而不是每个 repo 自己的 hooks,这个是单独有 repo-special-hooks 命令来管理的。
代码上的修改主要就是两处:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use lib $ENV{GL_LIBDIR};
use Gitolite::Rc;
use Gitolite::Common;
use Gitolite::Easy;
use Gitolite::Conf::Load;
our %one_repo;
our %one_config;
my $repo = $ARGV[0];
my $addr = $ARGV[1];
$ENV{GL_USER} or _die "GL_USER not set";
my $generic_error = "repo does not exist, or you are not authorised";
_die $generic_error if not owns($repo);
if ( $addr ) {
# write
_chdir("$rc{GL_REPO_BASE}/$repo.git");
if ( -f "gl-conf" ) {
my $cc = "./gl-conf";
_die "parse '$cc' failed: " . ( $! or $@ ) unless do $cc;
}
my $num;
my $i;
for ( @{ $one_config{$repo} } ) {
$num = $_->[0];
next unless $_->[1] eq 'hooks.mailinglist';
$_->[2] = $addr and $i++ and last;
}
push @{$one_config{$repo}}, [ $num, 'hooks.mailinglist', $addr] unless $i;
open( my $compiled_fh, ">", "gl-conf" ) or _die $!;
my $dumped_data = '';
$dumped_data = Data::Dumper->Dump( [ \%one_repo ], [qw(*one_repo)] );
$dumped_data .= Data::Dumper->Dump( [ \%one_config ], [qw(*one_config)] );
print $compiled_fh $dumped_data;
close $compiled_fh;
} else {
# read
my $val = git_config($repo, 'hooks.mailinglist');
print $val->{'hooks.mailinglist'};
}
1;
修改 src/lib/Gitolite/Rc.pm 如下:
@@ -459,7 +459,7 @@ DATA UMASK => 0077,
# look for "git-config" in the documentation - GIT_CONFIG_KEYS => '', + GIT_CONFIG_KEYS => 'hooks.*',
# comment out if you don't need all the extra detail in the logfile
LOG_EXTRA => 1, @@ -520,6 +520,7 @@ __DATA__
'info',
'perms',
'writable', + 'mailinglist',
gitolite 本身相关的代码解析,和实现思路,我写成了这个 slide,欢迎观看: