threads / patch / 15140

patchgitweb: ref markers link to named shortlogs

Subject: [PATCH] gitweb: ref markers link to named shortlogs

## tl;dr

33 messages between Aug 21, 2008 and Aug 28, 2008. Diffs are folded; open one to read it.

replies: 32people: 5as markdown or json

Giuseppe Bilotta· Aug 21, 2008, 18:04 UTC · lore

This patch turns ref markers for tags and heads into links to appropriate views for the ref name. Appropriate changes are made in the CSS to prevent ref markers to be annoyingly blue and underlined.

For all git ref types it's assumed that the preferred view is named like the ref type itself. For commits, we map the view to shortlog.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---

This is a resend of version 2 of the patch, as it seems to have dropped into oblivion without ACKs or NACKs.

 gitweb/gitweb.css  |    5 +++++
 gitweb/gitweb.perl |    7 ++++++-
 2 files changed, 11 insertions(+), 1 deletions(-)
Show changes to 2 files +11 −1

gitweb/gitweb.css, gitweb/gitweb.perl

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index aa0eeca..2b43eea 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -481,6 +481,11 @@ span.refs span {
 	border-color: #ffccff #ff00ee #ff00ee #ffccff;
 }
 
+span.refs span a {
+	text-decoration: none;
+	color: inherit;
+}
+
 span.refs span.ref {
 	background-color: #aaaaff;
 	border-color: #ccccff #0033cc #0033cc #ccccff;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 90cd99b..a12ce87 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1093,10 +1093,14 @@ sub format_log_line_html {
 sub format_ref_marker {
 	my ($refs, $id) = @_;
 	my $markers = '';
+	my %view = (
+		"commit" => "shortlog",
+	);
 
 	if (defined $refs->{$id}) {
 		foreach my $ref (@{$refs->{$id}}) {
 			my ($type, $name) = qw();
+			my $git_type = git_get_type($ref);
 			# e.g. tags/v2.6.11 or heads/next
 			if ($ref =~ m!^(.*?)s?/(.*)$!) {
 				$type = $1;
@@ -1107,7 +1111,8 @@ sub format_ref_marker {
 			}
 
 			$markers .= " <span class=\"$type\" title=\"$ref\">" .
-			            esc_html($name) . "</span>";
+				$cgi->a({-href => href(action=>$view{$git_type} || $git_type, hash=>$name)}, $name) .
+				"</span>";
 		}
 	}
 
-- 
1.5.6.3
Jakub Narebski· Aug 21, 2008, 21:32 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Thu, 21 Aug 2008, Giuseppe Bilotta wrote:
Show 6 quoted lines
> This patch turns ref markers for tags and heads into links to
> appropriate views for the ref name. Appropriate changes are made in the
> CSS to prevent ref markers to be annoyingly blue and underlined.
> 
> For all git ref types it's assumed that the preferred view is named like
> the ref type itself. For commits, we map the view to shortlog.
NAK.
It is a good idea, but not so good solution.
> --- a/gitweb/gitweb.css
> +++ b/gitweb/gitweb.css
> +span.refs span a {
> +	text-decoration: none;
> +	color: inherit;
> +}
Possible improvement:

We would probably want to make this link discoverable, by adding underline on :hover, like for other "hidden links" in gitweb (for example in commitdiff view).

Show 19 quoted lines
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index 90cd99b..a12ce87 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -1093,10 +1093,14 @@ sub format_log_line_html {
>  sub format_ref_marker {
>  	my ($refs, $id) = @_;
>  	my $markers = '';
> +	my %view = (
> +		"commit" => "shortlog",
> +	);
>  
>  	if (defined $refs->{$id}) {
>  		foreach my $ref (@{$refs->{$id}}) {
>  			my ($type, $name) = qw();
> +			my $git_type = git_get_type($ref);
>  			# e.g. tags/v2.6.11 or heads/next
>  			if ($ref =~ m!^(.*?)s?/(.*)$!) {
>  				$type = $1;

git_get_type calls 'git cat-file -t', so for each ref shown you make *additional call* to git command (additional fork). Not good, especially that you can get information if a ref is a tag (indirect reference) or not one can get from within git_get_references; which in turn uses "git show-refs --dereference" and used to use either "git peek-remote ." or ".git/info/refs" file. If there is <name>^{}, then <name> is indirect reference: is a tag.

As we display ref markers only for log-like views, marker can be tag or can be "lightweight reference" and be only a commit (in theory we could show ref markers also for tree and blob items, but it is not important now).

-- 
Jakub Narebski
Poland
Giuseppe Bilotta· Aug 22, 2008, 07:21 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

> It is a good idea, but not so good solution.
Ok, let's see if I can find a better way to do it 8-)
Show 13 quoted lines
>> --- a/gitweb/gitweb.css
>> +++ b/gitweb/gitweb.css
>
>> +span.refs span a {
>> +     text-decoration: none;
>> +     color: inherit;
>> +}
>
> Possible improvement:
>
> We would probably want to make this link discoverable, by adding
> underline on :hover, like for other "hidden links" in gitweb (for
> example in commitdiff view).
Can do that.
Show 18 quoted lines
>>                       my ($type, $name) = qw();
>> +                     my $git_type = git_get_type($ref);
>>                       # e.g. tags/v2.6.11 or heads/next
>>                       if ($ref =~ m!^(.*?)s?/(.*)$!) {
>>                               $type = $1;
>
> git_get_type calls 'git cat-file -t', so for each ref shown you make
> *additional call* to git command (additional fork).  Not good, especially
> that you can get information if a ref is a tag (indirect reference)
> or not one can get from within git_get_references; which in turn
> uses "git show-refs --dereference" and used to use either
> "git peek-remote ." or ".git/info/refs" file.  If there is <name>^{},
> then <name> is indirect reference: is a tag.
>
> As we display ref markers only for log-like views, marker can be tag
> or can be "lightweight reference" and be only a commit (in theory
> we could show ref markers also for tree and blob items, but it is not
> important now).

By looking at git_get_reference() what I see is basically the use of the same field as $type in format_ref_marker(). I can probably use that, although it means that any future extensions to ref marker display will need to hack the routine too. (This would mean that the patch would be more similar to my original patch http://marc.info/?l=git&m=121769155017642&w=2 ).

If this is not what you're suggesting, then I'm afraid I don't fully grasp your idea.

-- 
Giuseppe "Oblomov" Bilotta
Jakub Narebski· Aug 22, 2008, 08:49 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Fri, 22 Aug 2008, Giuseppe Bilotta wrote:
Show 15 quoted lines
>>> --- a/gitweb/gitweb.css
>>> +++ b/gitweb/gitweb.css
>>
>>> +span.refs span a {
>>> +     text-decoration: none;
>>> +     color: inherit;
>>> +}
>>
>> Possible improvement:
>>
>> We would probably want to make this link discoverable, by adding
>> underline on :hover, like for other "hidden links" in gitweb (for
>> example in commitdiff view).
> 
> Can do that.
Additional idea: it would be nice to know if clicking on ref marker
would lead us to 'shortlog' view, or to 'tag' view; so perhaps we should
distinguish somehow indirect refs, for example using bold font-weight.
 
Show 28 quoted lines
>>>                       my ($type, $name) = qw();
>>> +                     my $git_type = git_get_type($ref);
>>>                       # e.g. tags/v2.6.11 or heads/next
>>>                       if ($ref =~ m!^(.*?)s?/(.*)$!) {
>>>                               $type = $1;
>>
>> git_get_type calls 'git cat-file -t', so for each ref shown you make
>> *additional call* to git command (additional fork).  Not good, especially
>> that you can get information if a ref is a tag (indirect reference)
>> or not one can get from within git_get_references; which in turn
>> uses "git show-refs --dereference" and used to use either
>> "git peek-remote ." or ".git/info/refs" file.  If there is <name>^{},
>> then <name> is indirect reference: is a tag.
>>
>> As we display ref markers only for log-like views, marker can be tag
>> or can be "lightweight reference" and be only a commit (in theory
>> we could show ref markers also for tree and blob items, but it is not
>> important now).
> 
> By looking at git_get_reference() what I see is basically the use of
> the same field as $type in format_ref_marker(). I can probably use
> that, although it means that any future extensions to ref marker
> display will need to hack the routine too. (This would mean that the
> patch would be more similar to my original patch
> http://marc.info/?l=git&m=121769155017642&w=2 ).
> 
> If this is not what you're suggesting, then I'm afraid I don't fully
> grasp your idea.
No, that is not what I was suggesting.

What format_ref_marker() uses is not exactly 'type' of reference, but more 'kind of' reference. It is based on reference namespace, not on type of object the reference is at (points to). So code based on this info (like your v3 patch) would fail on lightweight tag, i.e. if there is ref in 'refs/tags' namespace which points directly to commit, and not to tag object.

But 'git show-ref --dereference' _has_ information about whether given reference points directly or indirectly to given object ($refs->{$id}), but currently we neither save it, nor use it. For example we can have:

  781c1834f5419bdf81bb7f3750170ccd6b809174 refs/heads/maint
  ...
  124c62e8781a8f03ee0256bee78f7b392e3920af refs/stash
  ...
  89e6fcde639d65823e8113c307067441701ac74f refs/tags/Attic/gitweb/parse_rev_list
  b69a41a384d19fe253b9f4f34c9019ad96ca571d refs/tags/Attic/gitweb/patchset_body
  781c1834f5419bdf81bb7f3750170ccd6b809174 refs/tags/TEMP
  ...
  07cca3b30ee2b5d060e44e5b18d7c22929c63d1a refs/tags/v1.5.6.5
  781c1834f5419bdf81bb7f3750170ccd6b809174 refs/tags/v1.5.6.5^{}

Now in this example we have three refs pointing to commit object 781c1834: refs/heads/maint, refs/tags/TEMP and refs/tags/v1.5.6.5. From those only refs/tags/v1.5.6.5 is (via) tag, even though TEMP is in tags namespace. Currently git_get_references() strips '^{}' indirect reference marker from the output (from refname), and doesn't make use of it. One solution would be to not stip it in git_get_references(), but leave it, and strip it and make use of it (if ref ends with '^{}' it must be tag object) in format_ref_marker().

But that is just a proposal...
-- 
Jakub Narebski
Poland
Giuseppe Bilotta· Aug 22, 2008, 08:03 UTC · re: Jakub Narebski · lore

[PATCHv3] gitweb: ref markers link to named shortlogs

This patch turns ref markers into links to appropriate views for the ref name, using the full ref name as hash. Appropriate changes are made in the CSS to prevent ref markers to be annoyingly blue and underlined, unless hovered on.

For all git ref types it's assumed that the preferred view is named like the ref type itself. If the corresponding action is not defined, shortlog is used.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---

Following Jakub Narebski's suggestions, an underlined :hover is added for the ref marker css, and we use $type instead of $git_type, sparing ourselves a bunch of git calls.

An additional change wrt the previous version is that the full ref name is used (to link to the correct object when e.g. a head and a tag by the same name exist).

 gitweb/gitweb.css  |    9 +++++++++
 gitweb/gitweb.perl |    3 ++-
 2 files changed, 11 insertions(+), 1 deletions(-)
Show changes to 2 files +11 −1

gitweb/gitweb.css, gitweb/gitweb.perl

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index aa0eeca..fadce1b 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -481,6 +481,15 @@ span.refs span {
 	border-color: #ffccff #ff00ee #ff00ee #ffccff;
 }
 
+span.refs span a {
+	text-decoration: none;
+	color: inherit;
+}
+
+span.refs span a:hover {
+	text-decoration: underline;
+}
+
 span.refs span.ref {
 	background-color: #aaaaff;
 	border-color: #ccccff #0033cc #0033cc #ccccff;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 90cd99b..77b2442 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1107,7 +1107,8 @@ sub format_ref_marker {
 			}
 
 			$markers .= " <span class=\"$type\" title=\"$ref\">" .
-			            esc_html($name) . "</span>";
+				$cgi->a({-href => href(action=> $actions{$type} || "shortlog", hash=>$ref)}, $name) .
+				"</span>";
 		}
 	}
 
-- 
1.5.6.3
Lea Wiemann· Aug 24, 2008, 19:30 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

Giuseppe Bilotta wrote:
> +			my $git_type = git_get_type($ref);
> [...]
> +				$cgi->a({-href => href(action=>$view{$git_type} || $git_type, hash=>$name)}, $name) .

Since some of this thread seems to be about performance, you might just make this a link to action => 'object' (and save the git_get_type call) and let gitweb Do The Right Thing when the link is followed.

[Disclaimer: Haven't read the whole thread, and haven't checked if action=object is actually doing the right thing here.]

-- Lea
Giuseppe Bilotta· Aug 24, 2008, 19:41 UTC · re: Lea Wiemann · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Sun, Aug 24, 2008 at 9:30 PM, Lea Wiemann <lewiemann@gmail.com> wrote:
Show 11 quoted lines
> Giuseppe Bilotta wrote:
>> +                     my $git_type = git_get_type($ref);
>> [...]
>> +                             $cgi->a({-href => href(action=>$view{$git_type} || $git_type, hash=>$name)}, $name) .
>
> Since some of this thread seems to be about performance, you might just
> make this a link to action => 'object' (and save the git_get_type call)
> and let gitweb Do The Right Thing when the link is followed.
>
> [Disclaimer: Haven't read the whole thread, and haven't checked if
> action=object is actually doing the right thing here.]

The object would do the right thing if we wanted 'commit' to be the default action for commits, but we actually want shortlogs in that case.

However, this remark of yours makes me think of a different way to approach the problem: create an 'objectview' action that acts just like object, but actually maps those objects to an appropriate default view. I'd like to hear Petr's and Jakub's opinion, and if they think it's a better approach than the latest version of my patch http://marc.info/?l=git&m=121941177812828&w=2 (which has not received any comments yet), I'll implemented it that way.

-- 
Giuseppe "Oblomov" Bilotta
Jakub Narebski· Aug 24, 2008, 20:37 UTC · re: Lea Wiemann · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

Lea Wiemann wrote:
Show 11 quoted lines
> Giuseppe Bilotta wrote:
> > +			my $git_type = git_get_type($ref);
> > [...]
> > +				$cgi->a({-href => href(action=>$view{$git_type} || $git_type, hash=>$name)}, $name) .
> 
> Since some of this thread seems to be about performance, you might just
> make this a link to action => 'object' (and save the git_get_type call)
> and let gitweb Do The Right Thing when the link is followed.
> 
> [Disclaimer: Haven't read the whole thread, and haven't checked if
> action=object is actually doing the right thing here.]

First, only the first patch (and perhaps second) called git_get_type; v4 and v5 do not. Second, link to 'object' action would not do the right thing; we want either 'shortlog' or 'tag' view, not 'commit' or 'tag' view.

What this patch does is making ref markers in the log-like views, and in the commit subject line headers in other view be "hidden links" to either 'shortlog' (in the case of ref being head/branch, or lightweight tag), or to 'tag' view in the case of annotated tag. We rely on the fact that we know what type of object refs points to (currently it is only 'commit', which might change, but the fact that we know type of object for which we show marker would not change), and the fact that tags point to given object only indirectly, and only tags can point indirectly (^{} suffix in "git show-ref --dereference", and "git ls-remote .", and $GIT_DIR/info/refs).

So you could have spared yourself this comment if you have read commit and the rest of thread more carefully...

-- 
Jakub Narebski
Poland
Giuseppe Bilotta· Aug 25, 2008, 23:28 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Sun, Aug 24, 2008 at 10:37 PM, Jakub Narebski <jnareb@gmail.com> wrote:
Show 28 quoted lines
> Lea Wiemann wrote:
>> Giuseppe Bilotta wrote:
>> > +                   my $git_type = git_get_type($ref);
>> > [...]
>> > +                           $cgi->a({-href => href(action=>$view{$git_type} || $git_type, hash=>$name)}, $name) .
>>
>> Since some of this thread seems to be about performance, you might just
>> make this a link to action => 'object' (and save the git_get_type call)
>> and let gitweb Do The Right Thing when the link is followed.
>>
>> [Disclaimer: Haven't read the whole thread, and haven't checked if
>> action=object is actually doing the right thing here.]
>
> First, only the first patch (and perhaps second) called git_get_type;
> v4 and v5 do not.  Second, link to 'object' action would not do the
> right thing; we want either 'shortlog' or 'tag' view, not 'commit'
> or 'tag' view.
>
> What this patch does is making ref markers in the log-like views, and
> in the commit subject line headers in other view be "hidden links" to
> either 'shortlog' (in the case of ref being head/branch, or lightweight
> tag), or to 'tag' view in the case of annotated tag.  We rely on the
> fact that we know what type of object refs points to (currently it is
> only 'commit', which might change, but the fact that we know type of
> object for which we show marker would not change), and the fact that
> tags point to given object only indirectly, and only tags can point
> indirectly (^{} suffix in "git show-ref --dereference", and
> "git ls-remote .", and $GIT_DIR/info/refs).

However, Lea's idea has its own merit. I hacked up a patch series that implements a git_marker_view() function (or fucntion as the shortlog says 8-P) and *that* one is used for ref markers, you can see it (3 patches) here: http://git.oblomov.eu/git/shortlog/heads/gitweb/shortlog..heads/gitweb/refmark [it's on top of other stuff but it's actually independent from the other stuff].

The advantage of this approach is that you actually it's more flexible in case future expansions lead to other differences in object vs marker view (currently the only difference is commit => shortlog): such differences just need to be added to the appropriate %views hash.

The disadvantage is that we don't care about the difference between lightweight and annotated tags, so there is no more visual difference about it, something which patch v5 does. This could of course be addressed separately as needed.

So, should I resend v5 with the small change about refs canonical form, or is somebody else doing it? Or is the new idea as implemented in the above mentioned changeset preferrable? Should I send that patches to the mailing list?

Let me know, I've got plenty more stuff ready for gitweb and I'm eager to see them accepted upstream 8-D

-- 
Giuseppe "Oblomov" Bilotta
Jakub Narebski· Aug 26, 2008, 08:15 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Tue, 26 August 2008, Giuseppe Bilotta wrote:
Show 46 quoted lines
> On Sun, Aug 24, 2008 at 10:37 PM, Jakub Narebski <jnareb@gmail.com> wrote:
>> Lea Wiemann wrote:
>>> Giuseppe Bilotta wrote:
>>>> +                   my $git_type = git_get_type($ref);
>>>> [...]
>>>> +                           $cgi->a({-href => href(action=>$view{$git_type} || $git_type, hash=>$name)}, $name) .
>>>
>>> Since some of this thread seems to be about performance, you might just
>>> make this a link to action => 'object' (and save the git_get_type call)
>>> and let gitweb Do The Right Thing when the link is followed.
>>>
>>> [Disclaimer: Haven't read the whole thread, and haven't checked if
>>> action=object is actually doing the right thing here.]
>>
>> First, only the first patch (and perhaps second) called git_get_type;
>> v4 and v5 do not.  Second, link to 'object' action would not do the
>> right thing; we want either 'shortlog' or 'tag' view, not 'commit'
>> or 'tag' view.
>>
>> What this patch does is making ref markers in the log-like views, and
>> in the commit subject line headers in other view be "hidden links" to
>> either 'shortlog' (in the case of ref being head/branch, or lightweight
>> tag), or to 'tag' view in the case of annotated tag.  We rely on the
>> fact that we know what type of object refs points to (currently it is
>> only 'commit', which might change, but the fact that we know type of
>> object for which we show marker would not change), and the fact that
>> tags point to given object only indirectly, and only tags can point
>> indirectly (^{} suffix in "git show-ref --dereference", and
>> "git ls-remote .", and $GIT_DIR/info/refs).
> 
> However, Lea's idea has its own merit. I hacked up a patch series that
> implements a git_marker_view() function (or fucntion as the shortlog
> says 8-P) and *that* one is used for ref markers, you can see it (3
> patches) here: http://git.oblomov.eu/git/shortlog/heads/gitweb/shortlog..heads/gitweb/refmark
> [it's on top of other stuff but it's actually independent from the
> other stuff].
> 
> The advantage of this approach is that you actually it's more flexible
> in case future expansions lead to other differences in object vs
> marker view (currently the only difference is commit => shortlog):
> such differences just need to be added to the appropriate %views hash.
> 
> The disadvantage is that we don't care about the difference between
> lightweight and annotated tags, so there is no more visual difference
> about it, something which patch v5 does. This could of course be
> addressed separately as needed.

NAK. For me using 'objectview' action, i.e. deciding on action based on the type of object, it is a bad idea. Let me explain in more detail.

First, I pretty much think that user would want to know if clicking on ref marker would lead him/her to 'tag' view, or to 'shortlog' view. So having visual difference is something that we want to have. And if we do that when generating link, why not go one extra step and in addition to visual difference also use different action in link?

Second, for me the whole idea of deciding on action based on the type of object, either via 'object' view/action or via actionless gitweb URL is either necessary evil or a tradeoff. We use it because of the following issues:

 * Calculating proper action during link generation via git_get_type()
   is costly; it is additional fork (this can be avoided by using
   'reuse connection' get type from Lea gitweb caching work), extra
   CPU load, and extra I/O hit.  If it *cannot be avoided* (which is
   not the case of ref markers links) it is better to defer this cost
   till user actually follows the link.  This feature is used for
   sha-1 committags (turning something that looks like sha-1 into
   gitweb hyperlink) and for links to symbolic links targets in 'tree'
   view (where link target can not exist - dangling symlink, or can
   lead to file or directory).
   (That is necessary evil part).
 * Guessing action based on type of objects allows gitweb to be more
   robust, support URL editing/mangling more easily, and aid the
   creation of shortcuts to git repositories (e.g. in bugtracker)
   more easily (see commit 7f9778b19b07601ae81).  Currently it is
   done in dispatch phase, and does not do redirection.
   (That is tradeoff: more robust and extra feature for extra get type).

BTW. one thing that can be done is consolidation of "guessing action" code: it is done by simply calculating what is to put in $action during dispatch, or is done in 'object' view to calculate redirect URL with proper action. I have tried to bring them together, but patches were I think lost in the noise.

> So, should I resend v5 with the small change about refs canonical
> form, or is somebody else doing it? Or is the new idea as implemented
> in the above mentioned changeset preferrable? Should I send that
> patches to the mailing list?
IMHO v5 with small change making refs canonical (hash=>"refs/$ref")
is preferred way to do this.  You can send v6 patch or I can send
it (I planned doing this today).
 
> Let me know, I've got plenty more stuff ready for gitweb and I'm eager
> to see them accepted upstream 8-D

First, the great problem with gitweb patches as of today is if Lea Google Summer of Code 2008 work on gitweb caching would be accepted (merged in) into git repository; I pretty much think that any gitweb improvements would be "incompatibile" (read: causing conflicts) with 'gitweb caching' patch covering such large parts of code... but I might be mistaken about that.

Second, I have planned on sending "gitweb TODO and wishlist", or "what's cooking in gitweb", with links to threads on git mailing list, and sometimes explanation why some feature should wait on infrastructure improvements, such as consolidating log-like views code.

Thank you for contributing to gitweb...
-- 
Jakub Narebski
Poland
Giuseppe Bilotta· Aug 26, 2008, 10:58 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Tue, Aug 26, 2008 at 10:15 AM, Jakub Narebski <jnareb@gmail.com> wrote:
Show 5 quoted lines
> BTW. one thing that can be done is consolidation of "guessing action"
> code: it is done by simply calculating what is to put in $action during
> dispatch, or is done in 'object' view to calculate redirect URL with
> proper action.  I have tried to bring them together, but patches were
> I think lost in the noise.

Ah, but the problem is that guessing the action based on the object sometimes depends on the context: for some cases the 'commit' action is the correct one for commits, in other cases shortlog is preferred. This is why I introduced the %views hash in some of my patches.

> IMHO v5 with small change making refs canonical (hash=>"refs/$ref")
> is preferred way to do this.  You can send v6 patch or I can send
> it (I planned doing this today).
I can do it, no problem.
Show 6 quoted lines
> First, the great problem with gitweb patches as of today is if Lea
> Google Summer of Code 2008 work on gitweb caching would be accepted
> (merged in) into git repository; I pretty much think that any gitweb
> improvements would be "incompatibile" (read: causing conflicts) with
> 'gitweb caching' patch covering such large parts of code... but
> I might be mistaken about that.

That's ok, I can wait for Lea's code to get into the repo, so I can work on the conflicts myself. I'm not sure what parts of the code she touches though, so for some things it might be easy (the pathinfo stuff, for example). Other features such as my allheads thing would probably need to be reworked for caching.

> Thank you for contributing to gitweb...
My pleasure.
-- 
Giuseppe "Oblomov" Bilotta
Jakub Narebski· Aug 26, 2008, 11:49 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Tue, 26 Aug 2008 12:58, Giuseppe Bilotta wrote:
Show 12 quoted lines
> On Tue, Aug 26, 2008 at 10:15 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> >
> > BTW. one thing that can be done is consolidation of "guessing action"
> > code: it is done by simply calculating what is to put in $action during
> > dispatch, or is done in 'object' view to calculate redirect URL with
> > proper action.  I have tried to bring them together, but patches were
> > I think lost in the noise.
> 
> Ah, but the problem is that guessing the action based on the object
> sometimes depends on the context: for some cases the 'commit' action
> is the correct one for commits, in other cases shortlog is preferred.
> This is why I introduced the %views hash in some of my patches.

By the way, this is argument *for* selecting action when generating link, if it is possible without incurring unnecessary (if you don't follow the link) performance penalty. For example in the case of ref markers links, you can link to 'log' in log view, 'shortlog' in 'shortlog' view, perhaps even 'history' in 'history' and 'tree'/'blob' views; or just 'shortlog' in all other views (for "commit subject" line heading).

Just my 2 eurocents.
-- 
Jakub Narebski
Poland
Giuseppe Bilotta· Aug 26, 2008, 12:29 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Tue, Aug 26, 2008 at 1:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:
Show 7 quoted lines
> By the way, this is argument *for* selecting action when generating
> link, if it is possible without incurring unnecessary (if you don't
> follow the link) performance penalty.  For example in the case of
> ref markers links, you can link to 'log' in log view, 'shortlog'
> in 'shortlog' view, perhaps even 'history' in 'history' and 'tree'/'blob'
> views; or just 'shortlog' in all other views (for "commit subject"
> line heading).

An interesting idea. I'll start experimenting with this context-sensitive action selection for ref-markers. (In the mean time, I've sent v6 with the simpler 'shortlog or tags' view. I guess an eventual context-sensitive action can be applied as a subsequent patch).

-- 
Giuseppe "Oblomov" Bilotta
Giuseppe Bilotta· Aug 27, 2008, 18:36 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Tue, Aug 26, 2008 at 1:49 PM, Jakub Narebski <jnareb@gmail.com> wrote:
Show 13 quoted lines
> On Tue, 26 Aug 2008 12:58, Giuseppe Bilotta wrote:
>> Ah, but the problem is that guessing the action based on the object
>> sometimes depends on the context: for some cases the 'commit' action
>> is the correct one for commits, in other cases shortlog is preferred.
>> This is why I introduced the %views hash in some of my patches.
>
> By the way, this is argument *for* selecting action when generating
> link, if it is possible without incurring unnecessary (if you don't
> follow the link) performance penalty.  For example in the case of
> ref markers links, you can link to 'log' in log view, 'shortlog'
> in 'shortlog' view, perhaps even 'history' in 'history' and 'tree'/'blob'
> views; or just 'shortlog' in all other views (for "commit subject"
> line heading).

So, I managed to get this feature into the latest version of the refmark patch (v7). Hope it's really the final form 8-)

-- 
Giuseppe "Oblomov" Bilotta
Lea Wiemann· Aug 28, 2008, 01:43 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

Jakub Narebski wrote:
> By the way, this is argument *for* selecting action when generating
> link, if it is possible without incurring unnecessary (if you don't
> follow the link) performance penalty.

I agree that it's much cleaner to select the action when generating the page, rather than having an 'objectview' action or so.

Worrying about performance seems like premature optimization though -- my guesstimate is that the performance penalty for looking up the object type is not practically noticeable (read: relevant), and with my patch applied (even without caching activated) it should move below the measurable range. So don't complicate the code to gain another 0.01% performance. ;-)

-- Lea
Giuseppe Bilotta· Aug 28, 2008, 06:26 UTC · re: Lea Wiemann · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Thu, Aug 28, 2008 at 3:43 AM, Lea Wiemann <lewiemann@gmail.com> wrote:
Show 7 quoted lines
> Jakub Narebski wrote:
>> By the way, this is argument *for* selecting action when generating
>> link, if it is possible without incurring unnecessary (if you don't
>> follow the link) performance penalty.
>
> I agree that it's much cleaner to select the action when generating the
> page, rather than having an 'objectview' action or so.
In that case v7 of my patch is The Way (TM).
Show 6 quoted lines
> Worrying about performance seems like premature optimization though --
> my guesstimate is that the performance penalty for looking up the object
> type is not practically noticeable (read: relevant), and with my patch
> applied (even without caching activated) it should move below the
> measurable range.  So don't complicate the code to gain another 0.01%
> performance. ;-)

Well, considering that after Jakub's suggestion we just get the target type from the presence and absence of ^{} in the output of show-refs, we're not making the code overly complex :)

BTW, any ETA on your caching changes landing in git? I'm really curious to see how many of my changes are not compatible with it 8-D

-- 
Giuseppe "Oblomov" Bilotta
Jakub Narebski· Aug 28, 2008, 06:48 UTC · re: Lea Wiemann · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

Lea Wiemann wrote:
Show 15 quoted lines
> Jakub Narebski wrote:
> >
> > By the way, this is argument *for* selecting action when generating
> > link, if it is possible without incurring unnecessary (if you don't
> > follow the link) performance penalty.
> 
> I agree that it's much cleaner to select the action when generating the
> page, rather than having an 'objectview' action or so.
> 
> Worrying about performance seems like premature optimization though --
> my guesstimate is that the performance penalty for looking up the object
> type is not practically noticeable (read: relevant), and with my patch
> applied (even without caching activated) it should move below the
> measurable range.  So don't complicate the code to gain another 0.01%
> performance. ;-)

First, without your 'git cat-file --batch-check' reuse-connection trick it wouldn't be _one_ additional fork; it is one fork per ref marker, which might be quite a lot in tag-heavy, branch-heavy, and using for example StGIT (with its refs) environment. Note that not all operating systems have lightweight fork, and that even with "caching" it is IO hit, and a bit of CPU hit.

Second, it isn't much more code than git_get_type solution, it is bit larger change: leave ^{} alone, check if ^{} and strip it, as compared to git_get_type.

-- 
Jakub Narebski
Poland
Jakub Narebski· Aug 22, 2008, 10:56 UTC · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Fri, 22 August 2008, Giuseppe Bilotta wrote:
Show 40 quoted lines
> On Fri, Aug 22, 2008 at 10:49 AM, Jakub Narebski <jnareb@gmail.com> wrote:
> >
> > What format_ref_marker() uses is not exactly 'type' of reference, but
> > more 'kind of' reference.  It is based on reference namespace, not
> > on type of object the reference is at (points to).  So code based
> > on this info (like your v3 patch) would fail on lightweight tag, i.e.
> > if there is ref in 'refs/tags' namespace which points directly to commit,
> > and not to tag object.
> >
> > But 'git show-ref --dereference' _has_ information about whether
> > given reference points directly or indirectly to given object
> > ($refs->{$id}), but currently we neither save it, nor use it.
> > For example we can have:
> >
> >  781c1834f5419bdf81bb7f3750170ccd6b809174 refs/heads/maint
> >  ...
> >  124c62e8781a8f03ee0256bee78f7b392e3920af refs/stash
> >  ...
> >  89e6fcde639d65823e8113c307067441701ac74f refs/tags/Attic/gitweb/parse_rev_list
> >  b69a41a384d19fe253b9f4f34c9019ad96ca571d refs/tags/Attic/gitweb/patchset_body
> >  781c1834f5419bdf81bb7f3750170ccd6b809174 refs/tags/TEMP
> >  ...
> >  07cca3b30ee2b5d060e44e5b18d7c22929c63d1a refs/tags/v1.5.6.5
> >  781c1834f5419bdf81bb7f3750170ccd6b809174 refs/tags/v1.5.6.5^{}
> >
> > Now in this example we have three refs pointing to commit object
> > 781c1834: refs/heads/maint, refs/tags/TEMP and refs/tags/v1.5.6.5.
> > From those only refs/tags/v1.5.6.5 is (via) tag, even though TEMP
> > is in tags namespace.  Currently git_get_references() strips '^{}'
> > indirect reference marker from the output (from refname), and doesn't
> > make use of it.  One solution would be to not stip it in
> > git_get_references(), but leave it, and strip it and make use of
> > it (if ref ends with '^{}' it must be tag object) in format_ref_marker().
> 
> Ah, I see what you mean. If I understand correctly, this particular
> situation is only a problem with tags, as they can be either
> lighweight tags (that reference a commit) or actual tag objects (that
> are indirect references to commits and direct references to
> themselves), whereas everything else is just direct references to
> object.

Yes, properly managed git repository should have refs pointing to tag objects only in 'refs/tags' (tags) namespace.

> Handling this requires a couple of extra info to be carried 
> over in $refs, so I guess I'll have to experiment with it  a little
> since it would require a more extensive change than I originally
> planned.

This "couple of extra info" could be just '^{}' suffix. So I don't think it would be very complicated.

You could simply do not strip '^{}' suffix in git_get_references() subroutine (so for example $refs->{$id} could be "tags/v1.6.0^{}", and not simply "tags/v1.6.0" when $id is sha-1 of a _commit_ indirectly referenced by v1.6.0, i.e. referenced by v1.6.0 _tag_), and strip it and make use of it in format_ref_marker():

   if ($ref =~ s/\^\{\}$//) {
      # $ref is a tag
   } else {
      # $ref points directly to object
   }
HTH.
P.S. I have re-added git mailing list to Cc:.
-- 
Jakub Narebski
Poland
Giuseppe Bilotta· Aug 22, 2008, 12:34 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: ref markers link to named shortlogs

On Fri, Aug 22, 2008 at 12:56 PM, Jakub Narebski <jnareb@gmail.com> wrote:
Show 14 quoted lines
> This "couple of extra info" could be just '^{}' suffix.  So I don't
> think it would be very complicated.
>
> You could simply do not strip '^{}' suffix in git_get_references()
> subroutine (so for example $refs->{$id} could be "tags/v1.6.0^{}",
> and not simply "tags/v1.6.0" when $id is sha-1 of a _commit_ indirectly
> referenced by v1.6.0, i.e. referenced by v1.6.0 _tag_), and strip
> it and make use of it in format_ref_marker():
>
>   if ($ref =~ s/\^\{\}$//) {
>      # $ref is a tag
>   } else {
>      # $ref points directly to object
>   }

I've actually changed the format of $refs, making the values into arrays whose first value is the name and the other is the ^{} marker, if present. Patch incoming.

> P.S. I have re-added git mailing list to Cc:.
Oops, didn't realized I had forgotten it.
-- 
Giuseppe "Oblomov" Bilotta
Giuseppe Bilotta· Aug 22, 2008, 12:39 UTC · re: Jakub Narebski · lore

[PATCH v4] gitweb: ref markers link to named shortlogs

This patch turns ref markers for tags and heads into links to appropriate views for the ref name. For annotated tags, we link to the tag view, while shortlog is used for anything else.

Appropriate changes are made in the CSS to prevent ref markers from being annoyingly blue and underlined, unless hovered. A visual indication of the target view difference is also implemented by making annotated tags show up in italic.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---

This version collects the suggestions made by Jakub Narebski, including an enhancement to git_get_references() to preserve information on the nature of a tag, and the exploitation of this extra information to differentiate between shortlog an tag view. Tag objects are also made visually different from lightweight tags by use of italics.

 gitweb/gitweb.css  |   13 +++++++++++++
 gitweb/gitweb.perl |   23 +++++++++++++++++------
 2 files changed, 30 insertions(+), 6 deletions(-)
Show changes to 2 files +30 −6

gitweb/gitweb.css, gitweb/gitweb.perl

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 5f4a4b8..3e50060 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -491,6 +491,19 @@ span.refs span {
 	border-color: #ffccff #ff00ee #ff00ee #ffccff;
 }
 
+span.refs span a {
+	text-decoration: none;
+	color: inherit;
+}
+
+span.refs span a:hover {
+	text-decoration: underline;
+}
+
+span.refs span.indirect {
+	font-style: italic;
+}
+
 span.refs span.ref {
 	background-color: #aaaaff;
 	border-color: #ccccff #0033cc #0033cc #ccccff;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a0d9272..5cb332f 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1201,7 +1201,12 @@ sub format_ref_marker {
 	my $markers = '';
 
 	if (defined $refs->{$id}) {
-		foreach my $ref (@{$refs->{$id}}) {
+		foreach my $aref (@{$refs->{$id}}) {
+			# this code exploits the fact that non-lightweight tags are the
+			# only indirect objects, and that they are the only objects for which
+			# we want to use tag instead of shortlog as action
+			my $ref = $aref->[0];
+			my $indirect = $aref->[1];
 			my ($type, $name) = qw();
 			# e.g. tags/v2.6.11 or heads/next
 			if ($ref =~ m!^(.*?)s?/(.*)$!) {
@@ -1212,8 +1217,14 @@ sub format_ref_marker {
 				$name = $ref;
 			}
 
-			$markers .= " <span class=\"$type\" title=\"$ref\">" .
-			            esc_html($name) . "</span>";
+			my $class = $type;
+			if ($indirect) {
+				$class .= " indirect";
+			}
+
+			$markers .= " <span class=\"$class\" title=\"$ref\">" .
+				$cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"), hash=>$ref)}, $name) .
+				"</span>";
 		}
 	}
 
@@ -2035,11 +2046,11 @@ sub git_get_references {
 
 	while (my $line = <$fd>) {
 		chomp $line;
-		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) {
+		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)(\^\{\})?$!) {
 			if (defined $refs{$1}) {
-				push @{$refs{$1}}, $2;
+				push @{$refs{$1}}, [$2, $3];
 			} else {
-				$refs{$1} = [ $2 ];
+				$refs{$1} = [ [$2, $3] ];
 			}
 		}
 	}
-- 
1.5.6.3
Jakub Narebski· Aug 22, 2008, 13:01 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH v4] gitweb: ref markers link to named shortlogs

On Fri, 22 August 2008, Giuseppe Bilotta wrote:
Show 50 quoted lines
> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
> index a0d9272..5cb332f 100755
> --- a/gitweb/gitweb.perl
> +++ b/gitweb/gitweb.perl
> @@ -1201,7 +1201,12 @@ sub format_ref_marker {
>  	my $markers = '';
>  
>  	if (defined $refs->{$id}) {
> -		foreach my $ref (@{$refs->{$id}}) {
> +		foreach my $aref (@{$refs->{$id}}) {
> +			# this code exploits the fact that non-lightweight tags are the
> +			# only indirect objects, and that they are the only objects for which
> +			# we want to use tag instead of shortlog as action
> +			my $ref = $aref->[0];
> +			my $indirect = $aref->[1];
>  			my ($type, $name) = qw();
>  			# e.g. tags/v2.6.11 or heads/next
>  			if ($ref =~ m!^(.*?)s?/(.*)$!) {
> @@ -1212,8 +1217,14 @@ sub format_ref_marker {
>  				$name = $ref;
>  			}
>  
> -			$markers .= " <span class=\"$type\" title=\"$ref\">" .
> -			            esc_html($name) . "</span>";
> +			my $class = $type;
> +			if ($indirect) {
> +				$class .= " indirect";
> +			}
> +
> +			$markers .= " <span class=\"$class\" title=\"$ref\">" .
> +				$cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"), hash=>$ref)}, $name) .
> +				"</span>";
>  		}
>  	}
>  
> @@ -2035,11 +2046,11 @@ sub git_get_references {
>  
>  	while (my $line = <$fd>) {
>  		chomp $line;
> -		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) {
> +		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)(\^\{\})?$!) {
>  			if (defined $refs{$1}) {
> -				push @{$refs{$1}}, $2;
> +				push @{$refs{$1}}, [$2, $3];
>  			} else {
> -				$refs{$1} = [ $2 ];
> +				$refs{$1} = [ [$2, $3] ];
>  			}
>  		}
>  	}

Seems overly complicated. How about something like this, instead? It simply moves stripping ^{} from refs to format_ref_marker(), and uses "tags/v1.5.0^{}" instead of [ "tags/v1.5.0", 1 ].

NOT TESTED!
 gitweb/gitweb.perl |   22 ++++++++++++++--------
 1 files changed, 14 insertions(+), 8 deletions(-)
Show changes to gitweb/gitweb.perl +14 −8
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 4c104d2..261307f 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1096,18 +1096,24 @@ sub format_ref_marker {
 
 	if (defined $refs->{$id}) {
 		foreach my $ref (@{$refs->{$id}}) {
-			my ($type, $name) = qw();
+			my ($class, $name, $indirect) = qw();
+			# strip ^{} suffix from indirect refs, like tags/v2.6.11^{}
+			$indirect = ($ref =~ s/\^{}$//);
 			# e.g. tags/v2.6.11 or heads/next
 			if ($ref =~ m!^(.*?)s?/(.*)$!) {
-				$type = $1;
-				$name = $2;
+				$class = $1;
+				$name  = $2;
 			} else {
-				$type = "ref";
-				$name = $ref;
+				$class = "ref";
+				$name  = $ref;
 			}
+			$class .= " indirect" if $indirect;
 
-			$markers .= " <span class=\"$type\" title=\"$ref\">" .
-			            esc_html($name) . "</span>";
+			$markers .= " <span class=\"$class\" title=\"$ref\">" .
+			            esc_html($name) .
+			            $cgi->a({-href => href(action=>($indirect ? "tag" : "shortlog"),
+			                                   hash=>$ref)}, $name) .
+			            "</span>";
 		}
 	}
 
@@ -1959,7 +1965,7 @@ sub git_get_references {
 
 	while (my $line = <$fd>) {
 		chomp $line;
-		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) {
+		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?.+)$!) {
 			if (defined $refs{$1}) {
 				push @{$refs{$1}}, $2;
 			} else {
-- 
Jakub Narebski
Poland
Giuseppe Bilotta· Aug 22, 2008, 13:20 UTC · re: Jakub Narebski · lore

Re: [PATCH v4] gitweb: ref markers link to named shortlogs

On Fri, Aug 22, 2008 at 3:01 PM, Jakub Narebski <jnareb@gmail.com> wrote:
>
> Seems overly complicated.  How about something like this, instead?
> It simply moves stripping ^{} from refs to format_ref_marker(),
> and uses "tags/v1.5.0^{}" instead of [ "tags/v1.5.0", 1 ].

My thought was that if the refs stuff was being used for something else than format_ref_marker, it would fail more spectacularly due to the different kind of values, rather than introducing potentially subtle bugs due to the additiona ^{} popping in unexpectedly, but it wouldn't be a problem to do it the simple way. Let me clean the patch up and resubmit it.

-- 
Giuseppe "Oblomov" Bilotta
Jakub Narebski· Aug 22, 2008, 13:42 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH v4] gitweb: ref markers link to named shortlogs

Giuseppe Bilotta wrote:
Show 12 quoted lines
> On Fri, Aug 22, 2008 at 3:01 PM, Jakub Narebski <jnareb@gmail.com> wrote:
> >
> > Seems overly complicated.  How about something like this, instead?
> > It simply moves stripping ^{} from refs to format_ref_marker(),
> > and uses "tags/v1.5.0^{}" instead of [ "tags/v1.5.0", 1 ].
> 
> My thought was that if the refs stuff was being used for something
> else than format_ref_marker, it would fail more spectacularly due to
> the different kind of values, rather than introducing potentially
> subtle bugs due to the additiona ^{} popping in unexpectedly, but it
> wouldn't be a problem to do it the simple way. Let me clean the patch
> up and resubmit it.

This might be good idea, but for the two following reasons: a) it makes code more complicated, b) it is inconsistent, because ref type would be saved in refname then stripped in format_ref_marker, while indirection would be saved in git_get_references; consistent would be ["tags", "v1.5.0", 1].

Thanks for your work on improving gitweb.
-- 
Jakub Narebski
Poland
Giuseppe Bilotta· Aug 22, 2008, 14:03 UTC · re: Jakub Narebski · lore

Re: [PATCH v4] gitweb: ref markers link to named shortlogs

On Fri, Aug 22, 2008 at 3:42 PM, Jakub Narebski <jnareb@gmail.com> wrote:
Show 6 quoted lines
>
> This might be good idea, but for the two following reasons: a) it makes
> code more complicated, b) it is inconsistent, because ref type would
> be saved in refname then stripped in format_ref_marker, while indirection
> would be saved in git_get_references; consistent would be
> ["tags", "v1.5.0", 1].
Ah, I'll keep that in mind for future enhancements.
> Thanks for your work on improving gitweb.

My pleasure, I actually have a long list of patches in store and I hope to be able to push them through for the next release :)

-- 
Giuseppe "Oblomov" Bilotta
Giuseppe Bilotta· Aug 22, 2008, 13:29 UTC · re: Jakub Narebski · lore

[PATCH v5] gitweb: ref markers link to named shortlogs

This patch turns ref markers for tags and heads into links to appropriate views for the ref name. For annotated tags, we link to the tag view, while shortlog is used for anything else.

Appropriate changes are made in the CSS to prevent ref markers from being annoyingly blue and underlined, unless hovered. A visual indication of the target view difference is also implemented by making annotated tags show up in italic.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---

As suggested by Jakub Narebski, the git_get_references() format gets extended to include the final ^{} for tag objects, and the name cleanup and indirection detection is moved to format_ref_marker()

 gitweb/gitweb.css  |   13 +++++++++++++
 gitweb/gitweb.perl |   16 +++++++++++++---
 2 files changed, 26 insertions(+), 3 deletions(-)
Show changes to 2 files +26 −3

gitweb/gitweb.css, gitweb/gitweb.perl

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 5f4a4b8..3e50060 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -491,6 +491,19 @@ span.refs span {
 	border-color: #ffccff #ff00ee #ff00ee #ffccff;
 }
 
+span.refs span a {
+	text-decoration: none;
+	color: inherit;
+}
+
+span.refs span a:hover {
+	text-decoration: underline;
+}
+
+span.refs span.indirect {
+	font-style: italic;
+}
+
 span.refs span.ref {
 	background-color: #aaaaff;
 	border-color: #ccccff #0033cc #0033cc #ccccff;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a0d9272..def4136 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1202,7 +1202,11 @@ sub format_ref_marker {
 
 	if (defined $refs->{$id}) {
 		foreach my $ref (@{$refs->{$id}}) {
+			# this code exploits the fact that non-lightweight tags are the
+			# only indirect objects, and that they are the only objects for which
+			# we want to use tag instead of shortlog as action
 			my ($type, $name) = qw();
+			my $indirect = ($ref =~ s/\^\{\}$//);
 			# e.g. tags/v2.6.11 or heads/next
 			if ($ref =~ m!^(.*?)s?/(.*)$!) {
 				$type = $1;
@@ -1212,8 +1216,14 @@ sub format_ref_marker {
 				$name = $ref;
 			}
 
-			$markers .= " <span class=\"$type\" title=\"$ref\">" .
-			            esc_html($name) . "</span>";
+			my $class = $type;
+			if ($indirect) {
+				$class .= " indirect";
+			}
+
+			$markers .= " <span class=\"$class\" title=\"$ref\">" .
+				$cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"), hash=>$ref)}, $name) .
+				"</span>";
 		}
 	}
 
@@ -2035,7 +2045,7 @@ sub git_get_references {
 
 	while (my $line = <$fd>) {
 		chomp $line;
-		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) {
+		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type.*)$!) {
 			if (defined $refs{$1}) {
 				push @{$refs{$1}}, $2;
 			} else {
-- 
1.5.6.3
Jakub Narebski· Aug 24, 2008, 23:53 UTC · re: Giuseppe Bilotta · lore

Re: [PATCH v5] gitweb: ref markers link to named shortlogs

On Fri, 22 Aug 2008, Giuseppe Bilotta wrote:
Show 8 quoted lines
> This patch turns ref markers for tags and heads into links to
> appropriate views for the ref name. For annotated tags, we link to the
> tag view, while shortlog is used for anything else.
> 
> Appropriate changes are made in the CSS to prevent ref markers from
> being annoyingly blue and underlined, unless hovered. A visual
> indication of the target view difference is also implemented by making
> annotated tags show up in italic.
Nice. I like it (read: Ack), with the following caveat
> +			$markers .= " <span class=\"$class\" title=\"$ref\">" .
> +				$cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"), hash=>$ref)}, $name) .
> +				"</span>";

We strip leading "refs/" in git_get_references(), so $ref does not contain it. I'm not sure of one has to use refs/heads/aaa and refs/tags/aaa to distinguish between tag and head with the same name, or heads/aaa and tags/aaa is enough.

Also, the above line is bit long.
-- 
Jakub Narebski
Poland
Miklos Vajna· Aug 25, 2008, 02:05 UTC · re: Jakub Narebski · lore

Re: [PATCH v5] gitweb: ref markers link to named shortlogs

On Mon, Aug 25, 2008 at 01:53:30AM +0200, Jakub Narebski <jnareb@gmail.com> wrote:
> We strip leading "refs/" in git_get_references(), so $ref does not
> contain it. I'm not sure of one has to use refs/heads/aaa and refs/tags/aaa
> to distinguish between tag and head with the same name, or heads/aaa and
> tags/aaa is enough.

You can have both heads/master and refs/heads/master, then heads/master is ambiguous.

Given that git fsck will not barf on such a configuration, I think gitweb should handle such a case as well.

Jakub Narebski· Aug 25, 2008, 02:44 UTC · re: Miklos Vajna · lore

Re: [PATCH v5] gitweb: ref markers link to named shortlogs

Miklos Vajna wrote:
Show 12 quoted lines
> On Mon, Aug 25, 2008 at 01:53:30AM +0200, Jakub Narebski <jnareb@gmail.com> wrote:
> >
> > We strip leading "refs/" in git_get_references(), so $ref does not
> > contain it. I'm not sure of one has to use refs/heads/aaa and refs/tags/aaa
> > to distinguish between tag and head with the same name, or heads/aaa and
> > tags/aaa is enough.
> 
> You can have both heads/master and refs/heads/master, then heads/master
> is ambiguous.
> 
> Given that git fsck will not barf on such a configuration, I think
> gitweb should handle such a case as well.
What I wanted to say was that I am not sure if current
+                     $markers .= " <span class=\"$class\" title=\"$ref\">" .
+                             $cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"),
+                                                    hash=>$ref)}, $name) .
+                             "</span>";
is enough, or should gitweb use
+                     $markers .= " <span class=\"$class\" title=\"$ref\">" .
+                             $cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"),
+                                                    hash=>"refs/$ref")}, $name) .
+                             "</span>";
or equivalent (not stripping "refs/" in git_get_references).
P.S. We are interested _only_ in refs shown by git-show-ref.
-- 
Jakub Narebski
Poland
Junio C Hamano· Aug 25, 2008, 04:11 UTC · re: Jakub Narebski · lore

Re: [PATCH v5] gitweb: ref markers link to named shortlogs

Jakub Narebski <jnareb@gmail.com> writes:
Show 6 quoted lines
> +                     $markers .= " <span class=\"$class\" title=\"$ref\">" .
> +                             $cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"),
> +                                                    hash=>"refs/$ref")}, $name) .
> +                             "</span>";
>
> or equivalent (not stripping "refs/" in git_get_references).

If you mean by "hash => $it", I think it is only used as the URL the anchor points at, and it is much more preferable to use the canonical form. "...?h=refs/heads/master" and "...h=heads/master" might produce the same output, but then it is better for smart caching layer if you always used canonical form, isn't it?

Jakub Narebski· Aug 25, 2008, 18:42 UTC · re: Junio C Hamano · lore

Re: [PATCH v5] gitweb: ref markers link to named shortlogs

On Mon, 25 Aug 2008, Junio C Hamano wrote:
Show 14 quoted lines
> Jakub Narebski <jnareb@gmail.com> writes:
> 
> > +                     $markers .= " <span class=\"$class\" title=\"$ref\">" .
> > +                             $cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"),
> > +                                                    hash=>"refs/$ref")}, $name) .
> > +                             "</span>";
> >
> > or equivalent (not stripping "refs/" in git_get_references).
> 
> If you mean by "hash => $it", I think it is only used as the URL the
> anchor points at, and it is much more preferable to use the canonical
> form.  "...?h=refs/heads/master" and "...h=heads/master" might produce the
> same output, but then it is better for smart caching layer if you always
> used canonical form, isn't it?
Will you do the change, or do you need resend from Giuseppe?

I like the feature that this patch introduces, and this time I don't have any reservations to the code. So, FWIW, Ack from me.

-- 
Jakub Narebski
Poland
Junio C Hamano· Aug 25, 2008, 19:48 UTC · re: Jakub Narebski · lore

Re: [PATCH v5] gitweb: ref markers link to named shortlogs

Jakub Narebski <jnareb@gmail.com> writes:
Show 20 quoted lines
> On Mon, 25 Aug 2008, Junio C Hamano wrote:
>> Jakub Narebski <jnareb@gmail.com> writes:
>> 
>> > +                     $markers .= " <span class=\"$class\" title=\"$ref\">" .
>> > +                             $cgi->a({-href => href(action=>( $indirect ? "tag" : "shortlog"),
>> > +                                                    hash=>"refs/$ref")}, $name) .
>> > +                             "</span>";
>> >
>> > or equivalent (not stripping "refs/" in git_get_references).
>> 
>> If you mean by "hash => $it", I think it is only used as the URL the
>> anchor points at, and it is much more preferable to use the canonical
>> form.  "...?h=refs/heads/master" and "...h=heads/master" might produce the
>> same output, but then it is better for smart caching layer if you always
>> used canonical form, isn't it?
>
> Will you do the change, or do you need resend from Giuseppe?
>
> I like the feature that this patch introduces, and this time I don't
> have any reservations to the code. So, FWIW, Ack from me.

I could do it, but my preference is for somebody I trust to resend with appropriate Ack lines so that I can just run "git am" on the message without editing.

Giuseppe Bilotta· Aug 26, 2008, 12:16 UTC · re: Jakub Narebski · lore

[PATCH v6] gitweb: ref markers link to named shortlogs

This patch turns ref markers for tags and heads into links to appropriate views for the ref name. For annotated tags, we link to the tag view, while shortlog is used for anything else.

Appropriate changes are made in the CSS to prevent ref markers from being annoyingly blue and underlined, unless hovered. A visual indication of the target view difference is also implemented by making annotated tags show up in italic.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---

This (hopefully final) version of the refmark link patch for gitweb uses canonical refnames for the links by prepending 'refs/' to the refname unless it's already present.

It's also slightly reworked to reduce line length.
 gitweb/gitweb.css  |   13 +++++++++++++
 gitweb/gitweb.perl |   23 ++++++++++++++++++++---
 2 files changed, 33 insertions(+), 3 deletions(-)
Show changes to 2 files +33 −3

gitweb/gitweb.css, gitweb/gitweb.perl

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 5f4a4b8..3e50060 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -491,6 +491,19 @@ span.refs span {
 	border-color: #ffccff #ff00ee #ff00ee #ffccff;
 }
 
+span.refs span a {
+	text-decoration: none;
+	color: inherit;
+}
+
+span.refs span a:hover {
+	text-decoration: underline;
+}
+
+span.refs span.indirect {
+	font-style: italic;
+}
+
 span.refs span.ref {
 	background-color: #aaaaff;
 	border-color: #ccccff #0033cc #0033cc #ccccff;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a0d9272..028cb4b 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1202,7 +1202,11 @@ sub format_ref_marker {
 
 	if (defined $refs->{$id}) {
 		foreach my $ref (@{$refs->{$id}}) {
+			# this code exploits the fact that non-lightweight tags are the
+			# only indirect objects, and that they are the only objects for which
+			# we want to use tag instead of shortlog as action
 			my ($type, $name) = qw();
+			my $indirect = ($ref =~ s/\^\{\}$//);
 			# e.g. tags/v2.6.11 or heads/next
 			if ($ref =~ m!^(.*?)s?/(.*)$!) {
 				$type = $1;
@@ -1212,8 +1216,21 @@ sub format_ref_marker {
 				$name = $ref;
 			}
 
-			$markers .= " <span class=\"$type\" title=\"$ref\">" .
-			            esc_html($name) . "</span>";
+			my $class = $type;
+			$class .= " indirect" if $indirect;
+
+			my $dest = "";
+			$dest .= "refs/" unless $ref =~ s!^refs/!;
+			$dest .= $ref;
+
+			my $link = $cgi->a({
+				-href => href(
+					action=>($indirect ? "tag" : "shortlog"),
+					hash=>$dest
+				)}, $name);
+
+			$markers .= " <span class=\"$class\" title=\"$ref\">" .
+				$link . "</span>";
 		}
 	}
 
@@ -2035,7 +2052,7 @@ sub git_get_references {
 
 	while (my $line = <$fd>) {
 		chomp $line;
-		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) {
+		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type.*)$!) {
 			if (defined $refs{$1}) {
 				push @{$refs{$1}}, $2;
 			} else {
-- 
1.5.6.3
Giuseppe Bilotta· Aug 26, 2008, 13:09 UTC · re: Jakub Narebski · lore

[PATCH v7] gitweb: ref markers link to named shortlogs

This patch turns ref markers for tags and heads into links to appropriate views for the ref name, depending on current context.

For annotated tags, we link to the tag view, unless that's the current view, in which case we switch to shortlog. For other refs, we prefer the current view if it's history or (short)log, and default to shortlog otherwise.

Appropriate changes are made in the CSS to prevent ref markers from being annoyingly blue and underlined, unless hovered. A visual indication of the target view difference is also implemented by making annotated tags show up in italic.

Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
---

Famous last words. Version 6 of this patch had a horrible typo, so I'm taking advantage of the need for a resend to implement a feature suggested by Jakub: context-sensitive destination action.

See patch description and code comment for details.
 gitweb/gitweb.css  |   13 +++++++++++++
 gitweb/gitweb.perl |   37 ++++++++++++++++++++++++++++++++++---
 2 files changed, 47 insertions(+), 3 deletions(-)
Show changes to 2 files +47 −3

gitweb/gitweb.css, gitweb/gitweb.perl

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 5f4a4b8..3e50060 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -491,6 +491,19 @@ span.refs span {
 	border-color: #ffccff #ff00ee #ff00ee #ffccff;
 }
 
+span.refs span a {
+	text-decoration: none;
+	color: inherit;
+}
+
+span.refs span a:hover {
+	text-decoration: underline;
+}
+
+span.refs span.indirect {
+	font-style: italic;
+}
+
 span.refs span.ref {
 	background-color: #aaaaff;
 	border-color: #ccccff #0033cc #0033cc #ccccff;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index a0d9272..7536fc8 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1196,13 +1196,23 @@ sub format_log_line_html {
 }
 
 # format marker of refs pointing to given object
+
+# the destination action is chosen based on object type and current context:
+# - for annotated tags, we choose the tag view unless it's the current view
+#   already, in which case we go to shortlog view
+# - for other refs, we keep the current view if we're in history, shortlog or
+#   log view, and select shortlog otherwise
 sub format_ref_marker {
 	my ($refs, $id) = @_;
 	my $markers = '';
 
 	if (defined $refs->{$id}) {
 		foreach my $ref (@{$refs->{$id}}) {
+			# this code exploits the fact that non-lightweight tags are the
+			# only indirect objects, and that they are the only objects for which
+			# we want to use tag instead of shortlog as action
 			my ($type, $name) = qw();
+			my $indirect = ($ref =~ s/\^\{\}$//);
 			# e.g. tags/v2.6.11 or heads/next
 			if ($ref =~ m!^(.*?)s?/(.*)$!) {
 				$type = $1;
@@ -1212,8 +1222,29 @@ sub format_ref_marker {
 				$name = $ref;
 			}
 
-			$markers .= " <span class=\"$type\" title=\"$ref\">" .
-			            esc_html($name) . "</span>";
+			my $class = $type;
+			$class .= " indirect" if $indirect;
+
+			my $dest_action = "shortlog";
+
+			if ($indirect) {
+				$dest_action = "tag" unless $action eq "tag";
+			} elsif ($action =~ /^(history|(short)?log)$/) {
+				$dest_action = $action;
+			}
+
+			my $dest = "";
+			$dest .= "refs/" unless $ref =~ m!^refs/!;
+			$dest .= $ref;
+
+			my $link = $cgi->a({
+				-href => href(
+					action=>$dest_action,
+					hash=>$dest
+				)}, $name);
+
+			$markers .= " <span class=\"$class\" title=\"$ref\">" .
+				$link . "</span>";
 		}
 	}
 
@@ -2035,7 +2066,7 @@ sub git_get_references {
 
 	while (my $line = <$fd>) {
 		chomp $line;
-		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) {
+		if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type.*)$!) {
 			if (defined $refs{$1}) {
 				push @{$refs{$1}}, $2;
 			} else {
-- 
1.5.6.3

← back to recent threads