* [PATCH 0/2] Make git_get_refs_list do work of git_get_references @ 2006-09-19 12:30 Jakub Narebski 2006-09-19 12:31 ` [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references Jakub Narebski 2006-09-19 12:33 ` [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references Jakub Narebski 0 siblings, 2 replies; 9+ messages in thread From: Jakub Narebski @ 2006-09-19 12:30 UTC (permalink / raw) To: git This is resend of short series of patches. Second patch in series was corrected twice ([PATCH 2/2 (take 2)] and [PATCH 2/2 (take 3)]), but neither of corrections made to git mailing list. Shortlog: [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references Diffstat: gitweb/gitweb.perl | 76 ++++++++++++++++++++++++++++++---------------------- 1 files changed, 44 insertions(+), 32 deletions(-) -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references 2006-09-19 12:30 [PATCH 0/2] Make git_get_refs_list do work of git_get_references Jakub Narebski @ 2006-09-19 12:31 ` Jakub Narebski 2006-09-20 16:09 ` Junio C Hamano 2006-09-19 12:33 ` [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references Jakub Narebski 1 sibling, 1 reply; 9+ messages in thread From: Jakub Narebski @ 2006-09-19 12:31 UTC (permalink / raw) To: git Instead of trying to read info/refs file, which might not be present (we did fallback to git-ls-remote), always use git-peek-remote in git_get_references. It is preparation for git_get_refs_info to also return references info. We cannot use info/refs for git_get_refs_info as the information contained therein is usually stale. Signed-off-by: Jakub Narebski <jnareb@gmail.com> --- gitweb/gitweb.perl | 10 ++-------- 1 files changed, 2 insertions(+), 8 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index c77270c..034a88c 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -828,16 +828,10 @@ sub git_get_project_owner { sub git_get_references { my $type = shift || ""; my %refs; - my $fd; # 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c refs/tags/v2.6.11 # c39ae07f393806ccf406ef966e9a15afc43cc36a refs/tags/v2.6.11^{} - if (-f "$projectroot/$project/info/refs") { - open $fd, "$projectroot/$project/info/refs" - or return; - } else { - open $fd, "-|", git_cmd(), "ls-remote", "." - or return; - } + open my $fd, "-|", $GIT, "peek-remote", "$projectroot/$project/" + or return; while (my $line = <$fd>) { chomp $line; -- 1.4.2.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references 2006-09-19 12:31 ` [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references Jakub Narebski @ 2006-09-20 16:09 ` Junio C Hamano 2006-09-20 18:13 ` Jakub Narebski 0 siblings, 1 reply; 9+ messages in thread From: Junio C Hamano @ 2006-09-20 16:09 UTC (permalink / raw) To: Jakub Narebski; +Cc: git Jakub Narebski <jnareb@gmail.com> writes: > Instead of trying to read info/refs file, which might not be present > (we did fallback to git-ls-remote), always use git-peek-remote in > git_get_references. > > It is preparation for git_get_refs_info to also return references > info. We cannot use info/refs for git_get_refs_info as the information > contained therein is usually stale. What the patch does is sane, but I think the last sentence of the proposed log message is not. If info/refs is "usually stale", it is a bug in the repository to have such a stale file. The real reason for this patch is that a repository served by gitweb is not necessarily meant to be fetched over HTTP and info/refs does not have to be there. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references 2006-09-20 16:09 ` Junio C Hamano @ 2006-09-20 18:13 ` Jakub Narebski 2006-09-21 9:07 ` Andreas Ericsson 0 siblings, 1 reply; 9+ messages in thread From: Jakub Narebski @ 2006-09-20 18:13 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Junio C Hamano wrote: > Jakub Narebski <jnareb@gmail.com> writes: > > > Instead of trying to read info/refs file, which might not be present > > (we did fallback to git-ls-remote), always use git-peek-remote in > > git_get_references. > > > > It is preparation for git_get_refs_info to also return references > > info. We cannot use info/refs for git_get_refs_info as the information > > contained therein is usually stale. > > What the patch does is sane, but I think the last sentence of > the proposed log message is not. If info/refs is "usually > stale", it is a bug in the repository to have such a stale file. > > The real reason for this patch is that a repository served by > gitweb is not necessarily meant to be fetched over HTTP and > info/refs does not have to be there. If the repository served by gitweb is updated using push, then info/refs updated using post-update hook is up-to-date. If repository is "live" repository, updated also using commit, rebase and such, info/refs is usually stale. If there were post-commit hook, and it's contents was the default post-update hook, info/refs would be never stale. And we could read from into/refs, and fallback to git-peek-remote if it doesn't exist... but we don't know if info/refs has current info. -- Jakub Narebski Poland ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references 2006-09-20 18:13 ` Jakub Narebski @ 2006-09-21 9:07 ` Andreas Ericsson 0 siblings, 0 replies; 9+ messages in thread From: Andreas Ericsson @ 2006-09-21 9:07 UTC (permalink / raw) To: Jakub Narebski; +Cc: Junio C Hamano, git Jakub Narebski wrote: > > If there were post-commit hook, and it's contents was the default > post-update hook, info/refs would be never stale. And we could read > from into/refs, and fallback to git-peek-remote if it doesn't exist... > but we don't know if info/refs has current info. ls -l .git/hooks/post-commit -rw-r----- 1 exon exon 152 Sep 21 10:54 .git/hooks/post-commit My post-update hook doesn't maintain info/refs for me. I'm sure that if someone set it up to do so they would also set the post-commit hook up to do the same. -- Andreas Ericsson andreas.ericsson@op5.se OP5 AB www.op5.se Tel: +46 8-230225 Fax: +46 8-230231 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references 2006-09-19 12:30 [PATCH 0/2] Make git_get_refs_list do work of git_get_references Jakub Narebski 2006-09-19 12:31 ` [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references Jakub Narebski @ 2006-09-19 12:33 ` Jakub Narebski 2006-09-20 18:12 ` Junio C Hamano 1 sibling, 1 reply; 9+ messages in thread From: Jakub Narebski @ 2006-09-19 12:33 UTC (permalink / raw) To: git Make git_get_refs_list do also work of git_get_references, to avoid calling git-peek-remote twice. Change meaning of git_get_refs_list meaning: it is now type, and not a full path, e.g. we now use git_get_refs_list("heads") instead of former git_get_refs_list("refs/heads"). Modify git_summary to use only one call to git_get_refs_list instead of one call to git_get_references and two to git_get_refs_list. Signed-off-by: Jakub Narebski <jnareb@gmail.com> --- Benchmarks show that this version is slightly faster than "before" version: 2626.133 +/- 98.1 ms after vs 3086.579 +/- 85.0 ms before (summary) 2233.814 +/- 13.9 ms after vs 2504.025 +/- 46.1 ms before (tags) 869.533 +/- 7.7 ms after vs 979.281 +/- 88.1 ms before (heads) gitweb/gitweb.perl | 66 +++++++++++++++++++++++++++++++++------------------- 1 files changed, 42 insertions(+), 24 deletions(-) diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 034a88c..01fae94 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -1119,7 +1119,8 @@ ## ..................................... ## parse to array of hashes functions sub git_get_refs_list { - my $ref_dir = shift; + my $type = shift || ""; + my %refs; my @reflist; my @refs; @@ -1127,14 +1128,21 @@ sub git_get_refs_list { or return; while (my $line = <$fd>) { chomp $line; - if ($line =~ m/^([0-9a-fA-F]{40})\t$ref_dir\/?([^\^]+)$/) { - push @refs, { hash => $1, name => $2 }; - } elsif ($line =~ m/^[0-9a-fA-F]{40}\t$ref_dir\/?(.*)\^\{\}$/ && - $1 eq $refs[-1]{'name'}) { - # most likely a tag is followed by its peeled - # (deref) one, and when that happens we know the - # previous one was of type 'tag'. - $refs[-1]{'type'} = "tag"; + if ($line =~ m/^([0-9a-fA-F]{40})\trefs\/($type\/?([^\^]+))(\^\{\})?$/) { + if (defined $refs{$1}) { + push @{$refs{$1}}, $2; + } else { + $refs{$1} = [ $2 ]; + } + + if (! $4) { # unpeeled, direct reference + push @refs, { hash => $1, name => $3 }; # without type + } elsif ($3 eq $refs[-1]{'name'}) { + # most likely a tag is followed by its peeled + # (deref) one, and when that happens we know the + # previous one was of type 'tag'. + $refs[-1]{'type'} = "tag"; + } } } close $fd; @@ -1150,7 +1158,7 @@ sub git_get_refs_list { } # sort refs by age @reflist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @reflist; - return \@reflist; + return (\@reflist, \%refs); } ## ---------------------------------------------------------------------- @@ -2114,14 +2122,14 @@ sub git_tags_body { sub git_heads_body { # uses global variable $project - my ($taglist, $head, $from, $to, $extra) = @_; + my ($headlist, $head, $from, $to, $extra) = @_; $from = 0 unless defined $from; - $to = $#{$taglist} if (!defined $to || $#{$taglist} < $to); + $to = $#{$headlist} if (!defined $to || $#{$headlist} < $to); print "<table class=\"heads\" cellspacing=\"0\">\n"; my $alternate = 0; for (my $i = $from; $i <= $to; $i++) { - my $entry = $taglist->[$i]; + my $entry = $headlist->[$i]; my %tag = %$entry; my $curr = $tag{'id'} eq $head; if ($alternate) { @@ -2291,7 +2299,19 @@ sub git_summary { my $owner = git_get_project_owner($project); - my $refs = git_get_references(); + my ($reflist, $refs) = git_get_refs_list(); + + my @taglist; + my @headlist; + foreach my $ref (@$reflist) { + if ($ref->{'name'} =~ s!^heads/!!) { + push @headlist, $ref; + } else { + $ref->{'name'} =~ s!^tags/!!; + push @taglist, $ref; + } + } + git_header_html(); git_print_page_nav('summary','', $head); @@ -2321,17 +2341,15 @@ sub git_summary { git_shortlog_body(\@revlist, 0, 15, $refs, $cgi->a({-href => href(action=>"shortlog")}, "...")); - my $taglist = git_get_refs_list("refs/tags"); - if (defined @$taglist) { + if (@taglist) { git_print_header_div('tags'); - git_tags_body($taglist, 0, 15, + git_tags_body(\@taglist, 0, 15, $cgi->a({-href => href(action=>"tags")}, "...")); } - my $headlist = git_get_refs_list("refs/heads"); - if (defined @$headlist) { + if (@headlist) { git_print_header_div('heads'); - git_heads_body($headlist, $head, 0, 15, + git_heads_body(\@headlist, $head, 0, 15, $cgi->a({-href => href(action=>"heads")}, "...")); } @@ -2542,7 +2560,7 @@ sub git_tags { git_print_page_nav('','', $head,undef,$head); git_print_header_div('summary', $project); - my $taglist = git_get_refs_list("refs/tags"); + my ($taglist) = git_get_refs_list("tags"); if (defined @$taglist) { git_tags_body($taglist); } @@ -2555,9 +2573,9 @@ sub git_heads { git_print_page_nav('','', $head,undef,$head); git_print_header_div('summary', $project); - my $taglist = git_get_refs_list("refs/heads"); - if (defined @$taglist) { - git_heads_body($taglist, $head); + my ($headlist) = git_get_refs_list("heads"); + if (defined @$headlist) { + git_heads_body($headlist, $head); } git_footer_html(); } -- 1.4.2.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references 2006-09-19 12:33 ` [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references Jakub Narebski @ 2006-09-20 18:12 ` Junio C Hamano 2006-09-20 22:40 ` Jakub Narebski 0 siblings, 1 reply; 9+ messages in thread From: Junio C Hamano @ 2006-09-20 18:12 UTC (permalink / raw) To: Jakub Narebski; +Cc: git Jakub Narebski <jnareb@gmail.com> writes: > Make git_get_refs_list do also work of git_get_references, to avoid > calling git-peek-remote twice. Change meaning of git_get_refs_list > meaning: it is now type, and not a full path, e.g. we now use > git_get_refs_list("heads") instead of former > git_get_refs_list("refs/heads"). > > Modify git_summary to use only one call to git_get_refs_list instead > of one call to git_get_references and two to git_get_refs_list. Will apply as-is; the following comments might be useful for further improvements. > diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl > index 034a88c..01fae94 100755 > --- a/gitweb/gitweb.perl > +++ b/gitweb/gitweb.perl > @@ -1127,14 +1128,21 @@ sub git_get_refs_list { > + if ($line =~ m/^([0-9a-fA-F]{40})\trefs\/($type\/?([^\^]+))(\^\{\})?$/) { > + if (defined $refs{$1}) { > + push @{$refs{$1}}, $2; > + } else { > + $refs{$1} = [ $2 ]; > + } Logically this should be "exists $refs{$1}" but defined would work fine in this particular case, because the elements of the hash are always an arrayref (this is just an advise to have the right habit). > + if (! $4) { # unpeeled, direct reference > + push @refs, { hash => $1, name => $3 }; # without type > + } elsif ($3 eq $refs[-1]{'name'}) { > + # most likely a tag is followed by its peeled > + # (deref) one, and when that happens we know the > + # previous one was of type 'tag'. > + $refs[-1]{'type'} = "tag"; > + } >... > - return \@reflist; > + return (\@reflist, \%refs); You are maintaining reflist (an array of hashrefs each element of which describes name, type, hash and other parse_ref() information for the ref) and refs (a hash that maps from name to hash) separatly. I wonder if this really has the performance advantage over just compute and return reflist from here and have the callers who need the mapping to derive it from the list (i.e. my ($reflist) = git_get_refs_list(); my %refs = map { $_->{name} => $_->{hash} } @$reflist; ). > @@ -2114,14 +2122,14 @@ sub git_tags_body { > > sub git_heads_body { > # uses global variable $project > - my ($taglist, $head, $from, $to, $extra) = @_; > + my ($headlist, $head, $from, $to, $extra) = @_; > $from = 0 unless defined $from; > - $to = $#{$taglist} if (!defined $to || $#{$taglist} < $to); > + $to = $#{$headlist} if (!defined $to || $#{$headlist} < $to); > > print "<table class=\"heads\" cellspacing=\"0\">\n"; > my $alternate = 0; > for (my $i = $from; $i <= $to; $i++) { > - my $entry = $taglist->[$i]; > + my $entry = $headlist->[$i]; > my %tag = %$entry; > my $curr = $tag{'id'} eq $head; > if ($alternate) { I guess either would do but I think it is more conventional to say: my $limit = @list; for (my $i = $from; $i < $limit; $i++) { ... } than my $limit = $#list; for (my $i = $from; $i <= $limit; $i++) { ... } At least the former would be easier to read for C types among us. The remaining hunks are very nice improvements. > @@ -2291,7 +2299,19 @@ sub git_summary { > @@ -2321,17 +2341,15 @@ sub git_summary { > @@ -2542,7 +2560,7 @@ sub git_tags { > @@ -2555,9 +2573,9 @@ sub git_heads { ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references 2006-09-20 18:12 ` Junio C Hamano @ 2006-09-20 22:40 ` Jakub Narebski 2006-09-20 23:14 ` Junio C Hamano 0 siblings, 1 reply; 9+ messages in thread From: Jakub Narebski @ 2006-09-20 22:40 UTC (permalink / raw) To: Junio C Hamano; +Cc: git Junio C Hamano wrote: > Jakub Narebski wrote: >> + if (! $4) { # unpeeled, direct reference >> + push @refs, { hash => $1, name => $3 }; # without type >> + } elsif ($3 eq $refs[-1]{'name'}) { >> + # most likely a tag is followed by its peeled >> + # (deref) one, and when that happens we know the >> + # previous one was of type 'tag'. >> + $refs[-1]{'type'} = "tag"; >> + } >>... >> - return \@reflist; >> + return (\@reflist, \%refs); > > You are maintaining reflist (an array of hashrefs each element > of which describes name, type, hash and other parse_ref() > information for the ref) and refs (a hash that maps from name to > hash) separatly. I wonder if this really has the performance > advantage over just compute and return reflist from here and > have the callers who need the mapping to derive it from the list > (i.e. > > my ($reflist) = git_get_refs_list(); > my %refs = map { $_->{name} => $_->{hash} } @$reflist; > ). The %refs hash contain also map from peeled (dereferenced) object to ref name. The information about derefs is not present in @reflist. So the answer is that you can't derive %refs from @reflist. -- Jakub Narebski ShadeHawk on #git Poland ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references 2006-09-20 22:40 ` Jakub Narebski @ 2006-09-20 23:14 ` Junio C Hamano 0 siblings, 0 replies; 9+ messages in thread From: Junio C Hamano @ 2006-09-20 23:14 UTC (permalink / raw) To: Jakub Narebski; +Cc: git Jakub Narebski <jnareb@gmail.com> writes: > The %refs hash contain also map from peeled (dereferenced) object > to ref name. The information about derefs is not present in @reflist. > So the answer is that you can't derive %refs from @reflist. There we found one candidate for further interface clean-up ;-). ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-09-21 9:07 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-09-19 12:30 [PATCH 0/2] Make git_get_refs_list do work of git_get_references Jakub Narebski 2006-09-19 12:31 ` [PATCH 1/2] gitweb: Always use git-peek-remote in git_get_references Jakub Narebski 2006-09-20 16:09 ` Junio C Hamano 2006-09-20 18:13 ` Jakub Narebski 2006-09-21 9:07 ` Andreas Ericsson 2006-09-19 12:33 ` [PATCH 2/2] gitweb: Make git_get_refs_list do work of git_get_references Jakub Narebski 2006-09-20 18:12 ` Junio C Hamano 2006-09-20 22:40 ` Jakub Narebski 2006-09-20 23:14 ` Junio C Hamano
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).