From: Junio C Hamano <gitster@pobox.com>
To: Krzesimir Nowak <krzesimir@endocode.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] gitweb: Add an option for adding more branch refs
Date: Tue, 26 Nov 2013 13:48:10 -0800 [thread overview]
Message-ID: <xmqqr4a2vnqd.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <1385462243-7898-1-git-send-email-krzesimir@endocode.com> (Krzesimir Nowak's message of "Tue, 26 Nov 2013 11:37:23 +0100")
Krzesimir Nowak <krzesimir@endocode.com> writes:
> Overriding an @additional_branch_refs configuration variable with
> value ('wip') will make gitweb to show branches that appear in
> refs/heads and refs/wip (refs/heads is hardcoded). Might be useful for
> gerrit setups where user branches are not stored under refs/heads/.
>
> Signed-off-by: Krzesimir Nowak <krzesimir@endocode.com>
> ---
> gitweb/gitweb.perl | 99 ++++++++++++++++++++++++++++++++++++++++--------------
> 1 file changed, 74 insertions(+), 25 deletions(-)
>
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index 68c77f6..9bfd38b 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -17,6 +17,7 @@ use Encode;
> use Fcntl ':mode';
> use File::Find qw();
> use File::Basename qw(basename);
> +use List::Util qw(min);
> use Time::HiRes qw(gettimeofday tv_interval);
> binmode STDOUT, ':utf8';
>
> @@ -122,6 +123,10 @@ our $logo_label = "git homepage";
> # source of projects list
> our $projects_list = "++GITWEB_LIST++";
>
> +# list of additional "directories" under "refs/" we want to display as
> +# branches
> +our @additional_branch_refs = ();
> +
> # the width (in characters) of the projects list "Description" column
> our $projects_list_description_width = 25;
>
> @@ -626,14 +631,29 @@ sub feature_avatar {
> return @val ? @val : @_;
> }
>
> +sub get_branch_refs {
> + return ('heads', @additional_branch_refs);
> +}
> +
> # checking HEAD file with -e is fragile if the repository was
> # initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed
> # and then pruned.
> sub check_head_link {
> my ($dir) = @_;
> my $headfile = "$dir/HEAD";
> - return ((-e $headfile) ||
> - (-l $headfile && readlink($headfile) =~ /^refs\/heads\//));
> +
> + if (-e $headfile) {
> + return 1;
> + }
> + if (-l $headfile) {
> + my $rl = readlink($headfile);
> +
> + for my $ref (get_branch_refs()) {
> + return 1 if $rl =~ /^refs\/$ref\//;
> + }
> + }
> + return 0;
The change to this function is wrong. A non-detached HEAD that
points at anything other than refs/heads/ should be considered a
repository corruption and should not be encouraged.
> @@ -2515,6 +2535,7 @@ sub format_snapshot_links {
> sub get_feed_info {
> my $format = shift || 'Atom';
> my %res = (action => lc($format));
> + my $matched_ref = 0;
>
> # feed links are possible only for project views
> return unless (defined $project);
> @@ -2522,12 +2543,17 @@ sub get_feed_info {
> # or don't have specific feed yet (so they should use generic)
> return if (!$action || $action =~ /^(?:tags|heads|forks|tag|search)$/x);
>
> - my $branch;
> - # branches refs uses 'refs/heads/' prefix (fullname) to differentiate
> - # from tag links; this also makes possible to detect branch links
> - if ((defined $hash_base && $hash_base =~ m!^refs/heads/(.*)$!) ||
> - (defined $hash && $hash =~ m!^refs/heads/(.*)$!)) {
> - $branch = $1;
> + my $branch = undef;
> + # branches refs uses 'refs/' + $get_branch_refs()[x] + '/' prefix
> + # (fullname) to differentiate from tag links; this also makes
> + # possible to detect branch links
> + for my $ref (get_branch_refs()) {
> + if ((defined $hash_base && $hash_base =~ m!^refs/$ref/(.*)$!) ||
> + (defined $hash && $hash =~ m!^refs/$ref/(.*)$!)) {
> + $branch = $1;
> + $matched_ref = $ref;
> + last;
> + }
> }
> # find log type for feed description (title)
> my $type = 'log';
> @@ -2540,7 +2566,7 @@ sub get_feed_info {
> }
>
> $res{-title} = $type;
> - $res{'hash'} = (defined $branch ? "refs/heads/$branch" : undef);
> + $res{'hash'} = (defined $branch ? "refs/$matched_ref/$branch" : undef);
> $res{'file_name'} = $file_name;
OK.
> @@ -3184,24 +3210,43 @@ sub git_get_project_owner {
> return $owner;
> }
>
> -sub git_get_last_activity {
> - my ($path) = @_;
> - my $fd;
> +sub git_get_last_activity_age {
> + my ($refs) = @_;
> + my $fd = -1;
>
> - $git_dir = "$projectroot/$path";
> open($fd, "-|", git_cmd(), 'for-each-ref',
> '--format=%(committer)',
> '--sort=-committerdate',
> '--count=1',
> - 'refs/heads') or return;
> + $refs) or return undef;
> +
> my $most_recent = <$fd>;
> - close $fd or return;
> + close $fd or return undef;
> if (defined $most_recent &&
> $most_recent =~ / (\d+) [-+][01]\d\d\d$/) {
> my $timestamp = $1;
> - my $age = time - $timestamp;
> - return ($age, age_string($age));
> + return time - $timestamp;
> }
> +
> + return undef;
> +}
> +
> +sub git_get_last_activity {
> + my ($path) = @_;
> + my @ages = ();
> +
> + $git_dir = "$projectroot/$path";
> + for my $ref (get_branch_refs()) {
> + my $age = git_get_last_activity_age('refs/' . $_);
> +
> + push @ages, $age if defined $age;
> + }
> + if (@ages) {
> + my $min_age = min(@ages);
> +
> + return ($min_age, age_string($min_age));
> + }
> +
> return (undef, undef);
> }
The original runs
for-each-ref --count=1 refs/heads
and picks the latest one, so shouldn't it be the matter of running
for-each-ref --count=1 refs/heads refs/extra
i.e. something like
@@ -3193,7 +3193,7 @@ sub git_get_last_activity {
'--format=%(committer)',
'--sort=-committerdate',
'--count=1',
- 'refs/heads') or return;
+ map { "refs/$_" } get_branch_refs()) or return;
my $most_recent = <$fd>;
close $fd or return;
if (defined $most_recent &&
to grab the latest among the refs you care about?
> @@ -3223,7 +3268,7 @@ sub git_get_remotes_list {
> next if $wanted and not $remote eq $wanted;
> my ($url, $key) = ($1, $2);
>
> - $remotes{$remote} ||= { 'heads' => () };
> + $remotes{$remote} ||= { map { $_ => () } get_branch_refs() };
> $remotes{$remote}{$key} = $url;
> }
> close $fd or return;
> @@ -3237,9 +3282,11 @@ sub fill_remote_heads {
> my @heads = map { "remotes/$_" } keys %$remotes;
> my @remoteheads = git_get_heads_list(undef, @heads);
> foreach my $remote (keys %$remotes) {
> - $remotes->{$remote}{'heads'} = [ grep {
> - $_->{'name'} =~ s!^$remote/!!
> - } @remoteheads ];
> + foreach my $ref (get_branch_refs()) {
> + $remotes->{$remote}{$ref} = [ grep {
> + $_->{'name'} =~ s!^$remote/!!
> + } @remoteheads ];
> + }
> }
> }
Hmmm, why? Aren't these additional ones about the local
"branch-like" refs? What makes us think that these names are also
shared with the names from remote hierarchies?
> @@ -3644,7 +3691,7 @@ sub parse_from_to_diffinfo {
>
> sub git_get_heads_list {
> my ($limit, @classes) = @_;
> - @classes = ('heads') unless @classes;
> + @classes = get_branch_refs() unless @classes;
> my @patterns = map { "refs/$_" } @classes;
> my @headslist;
>
> @@ -3662,7 +3709,8 @@ sub git_get_heads_list {
> my ($committer, $epoch, $tz) =
> ($committerinfo =~ /^(.*) ([0-9]+) (.*)$/);
> $ref_item{'fullname'} = $name;
> - $name =~ s!^refs/(?:head|remote)s/!!;
> + my $strip_refs = join '|', get_branch_refs();
> + $name =~ s!^refs/(?:$strip_refs|remotes)/!!;
>
> $ref_item{'name'} = $name;
> $ref_item{'id'} = $hash;
> @@ -4286,7 +4334,7 @@ sub git_print_page_nav {
> # available if the feature is enabled
> sub format_ref_views {
> my ($current) = @_;
> - my @ref_views = qw{tags heads};
> + my @ref_views = ('tags', get_branch_refs());
> push @ref_views, 'remotes' if gitweb_check_feature('remote_heads');
> return join " | ", map {
> $_ eq $current ? $_ :
> @@ -7179,7 +7227,8 @@ sub snapshot_name {
> $ver = $1;
> } else {
> # branches and other need shortened SHA-1 hash
> - if ($hash =~ m!^refs/(?:heads|remotes)/(.*)$!) {
> + my $strip_refs = join '|', get_branch_refs();
> + if ($hash =~ m!^refs/(?:$strip_refs|remotes)/(.*)$!) {
> $ver = $1;
> }
> $ver .= '-' . git_get_short_hash($project, $hash);
As the elements of @additional_branch_refs are expected by code
added by this patch to never have any special metacharacters in
them, it probably is a good idea to sanity check it to catch
misconfigurations and typos before doing anything else.
Other than that, looks good to me.
Thanks.
next prev parent reply other threads:[~2013-11-26 21:48 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-26 10:37 [PATCH] gitweb: Add an option for adding more branch refs Krzesimir Nowak
2013-11-26 21:48 ` Junio C Hamano [this message]
2013-11-27 15:34 ` Krzesimir Nowak
2013-11-27 15:56 ` Jakub Narębski
2013-11-27 16:15 ` Krzesimir Nowak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqr4a2vnqd.fsf@gitster.dls.corp.google.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=krzesimir@endocode.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.