5 use lib
$ENV{GL_LIBDIR
};
8 usage
($ARGV[1]) if $ARGV[1] and $ARGV[1] =~ /^[\w-]+$/ and $ARGV[0] eq '-h';
10 ( my $logdir = $ENV{GL_LOGFILE
} ) =~ s
(/[^/]+$)();
13 my %gl_log_lines_buffer;
16 migrate
(@ARGV) if $ARGV[0] eq '--migrate'; # won't return; exits right there
20 if ($ARGV[0] eq '--tip') {
25 # the normal who-pushed
26 usage
() if not @ARGV or @ARGV < 2 or $ARGV[0] eq '-h';
27 usage
() if $ARGV[1] !~ /^[0-9a-f]+$/i;
30 my $sha = shift; $sha =~ tr/A-F/a-f/;
32 $ENV{GL_USER
} and ( can_read
($repo) or die "no read permissions on '$repo'" );
34 # ----------------------------------------------------------------------
36 my $repodir = "$ENV{GL_REPO_BASE}/$repo.git";
37 chdir $repodir or die "repo '$repo' missing";
39 my @logfiles = reverse glob("$logdir/*");
40 @logfiles = ( "$repodir/gl-log" ) if -f
"$repodir/gl-log";
42 for my $logfile ( @logfiles ) {
44 for my $line ( reverse grep { m
(\tupdate
\t($repo|$repodir)\t) } <> ) {
46 my @fields = split /\t/, $line;
47 my ( $ts, $pid, $who, $ref, $d_old, $new ) = @fields[ 0, 1, 4, 6, 7, 8 ];
49 # d_old is what you display
51 $old = "" if $d_old eq ( "0" x
40 );
52 $old = "$old.." if $old;
55 print "$ts $pid $who $ref $d_old $new\n" if $new =~ /^$sha/;
57 system("git rev-list $old$new 2>/dev/null | grep ^$sha >/dev/null && echo '$ts $pid $who $ref $d_old $new'");
62 # ----------------------------------------------------------------------
66 chdir $ENV{GL_REPO_BASE
};
67 my @repos = `gitolite list-phy-repos`; chomp @repos;
69 my $count = scalar( grep { -f
"$_.git/gl-log" } @repos );
70 if ( $count and ( $_[1] || '' ) ne '--force' ) {
71 say2
"$count repo(s) already have gl-log files. To confirm overwriting, please re-run as:";
72 say2
"\tgitolite who-pushed --migrate --force";
73 say2
"see help ('-h', '-h logfiles', or '-h migrate') for details.";
77 foreach my $r (@repos) {
78 _print
("$r.git/gl-log", '');
81 my %repo_exists = map { $_ => 1 } @repos;
82 @ARGV = sort ( glob("$logdir/*") );
84 say2
"processed '$ARGV'" if eof(ARGV
);
85 next unless /\tupdate\t/;
89 $repo =~ s/^$ENV{GL_REPO_BASE}\///;
93 gen_gl_log
($repo, $_) if $repo_exists{$repo};
102 $countr++ unless $gl_log_lines_buffer{$repo}; # new repo, not yet seen
104 $gl_log_lines_buffer{$repo} .= $l;
106 # once we have buffered log lines for about 100 repos, or about 10,000 log
107 # lines, we flush them
108 flush_gl_log
() if $countr >= 100 or $countl >= 10_000
;
111 while (my ($r, $l) = each %gl_log_lines_buffer) {
112 open my $fh, ">>", "$r.git/gl-log" or _die
"open flush_gl_log failed: $!";
116 %gl_log_lines_buffer = ();
117 say2
"flushed $countl lines to $countr repos...";
118 $countr = $countl = 0;
124 uSAge: ssh git@host who-pushed [--tip] <repo> <SHA>
126 Determine who pushed the given commit. The first few hex digits of the SHA
127 should suffice. If the '--tip' option is supplied, it'll only look for the
128 SHA among "tip" commits (i.e., search the "new SHA"s, without running the
129 expensive 'git rev-parse' for each push).
131 Each line of the output contains the following fields: timestamp, a
132 transaction ID, username, refname, and the old and new SHAs for the ref.
134 Note on the "transaction ID" field: if looking at the log file doesn't help
135 you figure out what its purpose is, please just ignore it.
137 TO SEE ADDITIONAL HELP, run with options "-h logfiles" or "-h migrate".
141 There are 2 places that gitolite logs to, based on the value give to the
142 LOG_DEST rc variable. By default, log files go to ~/.gitolite/logs, but you
143 can choose to send them to syslog instead (in which case 'who-pushed' will not
144 work), or to both syslog and the normal log files.
146 In addition, gitolite can also be told to log just the "update" records to a
147 special "gl-log" file in the bare repo directory. This makes 'who-pushed'
148 **much** faster (thanks to milki for the problem *and* the simple solution).
150 'who-pushed' will look for that special file first and use only that if it is
151 found. Otherwise it will look in the normal gitolite log files, which will of
152 course be much slower.
156 If you installed gitolite before v3.6.4, and you wish to use the new, more
157 efficient logging that helps who-pushed run faster, you should first update
158 the rc file (see http://gitolite.com/gitolite/rc.html for notes on that) to
159 specify a suitable value for LOG_DEST.
161 After that you should probably do a one-time generation of the repo-specific
162 'gl-log' files from the normal log files. This can only be done from the
163 server command line, even if the 'who-pushed' command has been enabled for
166 To do this, just run 'gitolite who-pushed --migrate'. If some of your repos
167 already had gl-log files, it will warn you, and tell you how to override.
168 You're only supposed to to use this *once* after upgrading to v3.6.4 and
169 setting LOG_DEST in the rc file anyway.