threads / patch / 5209

patchgitweb: Different colours for tags and heads

Subject: [PATCH] gitweb: Different colours for tags and heads

## tl;dr

6 messages between Aug 11, 2006 and Aug 14, 2006. Diffs are folded; open one to read it.

replies: 5people: 4as markdown or json

Thomas Kolejka· Aug 11, 2006, 15:12 UTC · lore
Hello,

with the following patch there are different colours for tags and heads in gitweb. So you can easily differentiate between them.

Commit ca9e3b124f6313187da641b5cd55100c4ade6a9a
----
Show changes to 2 files +49 −27

gitweb/gitweb.css, gitweb/gitweb.perl

diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 47c1ade..c47cbf4 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -330,6 +330,15 @@ span.tag {
 	border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
 }
 
+span.head {
+	padding: 0px 4px;
+	font-size: 10px;
+	font-weight: normal;
+	background-color: #aaaaff;
+	border: 1px solid;
+	border-color: #ccccff #0033cc #0033cc #ccccff;
+}
+
 span.atnight {
 	color: #cc0000;
 }
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 626fcc9..755b0b1 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -363,10 +363,10 @@ sub format_log_line_html {
 
 # format marker of refs pointing to given object
 sub git_get_referencing {
-	my ($refs, $id) = @_;
+	my ($refs, $id, $class) = @_;
 
 	if (defined $refs->{$id}) {
-		return ' <span class="tag">' . esc_html($refs->{$id}) . '</span>';
+		return " <span class=\"$class\">" . esc_html($refs->{$id}) . "</span>";
 	} else {
 		return "";
 	}
@@ -1054,7 +1054,7 @@ ## functions printing large fragments of
 
 sub git_shortlog_body {
 	# uses global variable $project
-	my ($revlist, $from, $to, $refs, $extra) = @_;
+	my ($revlist, $from, $to, $refs, $heads, $extra) = @_;
 	$from = 0 unless defined $from;
 	$to = $#{$revlist} if (!defined $to || $#{$revlist} < $to);
 
@@ -1062,8 +1062,9 @@ sub git_shortlog_body {
 	my $alternate = 0;
 	for (my $i = $from; $i <= $to; $i++) {
 		my $commit = $revlist->[$i];
-		#my $ref = defined $refs ? git_get_referencing($refs, $commit) : '';
-		my $ref = git_get_referencing($refs, $commit);
+		#my $ref = defined $refs ? git_get_referencing($refs, $commit, "tag") : '';
+		my $ref = git_get_referencing($refs, $commit, "tag");
+		my $head = git_get_referencing($heads, $commit, "head");
 		my %co = git_read_commit($commit);
 		if ($alternate) {
 			print "<tr class=\"dark\">\n";
@@ -1078,11 +1079,11 @@ sub git_shortlog_body {
 		if (length($co{'title_short'}) < length($co{'title'})) {
 			print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"),
 			               -class => "list", -title => "$co{'title'}"},
-			      "<b>" . esc_html($co{'title_short'}) . "$ref</b>");
+			      "<b>" . esc_html($co{'title_short'}) . "$ref $head</b>");
 		} else {
 			print $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"),
 			               -class => "list"},
-			      "<b>" . esc_html($co{'title'}) . "$ref</b>");
+			      "<b>" . esc_html($co{'title'}) . "$ref $head</b>");
 		}
 		print "</td>\n" .
 		      "<td class=\"link\">" .
@@ -1407,7 +1408,8 @@ sub git_summary {
 		$owner = get_file_owner("$projectroot/$project");
 	}
 
-	my $refs = read_info_ref();
+	my $refs = read_info_ref("tags");
+	my $heads = read_info_ref("heads");
 	git_header_html();
 	git_page_nav('summary','', $head);
 
@@ -1423,7 +1425,7 @@ sub git_summary {
 	my @revlist = map { chomp; $_ } <$fd>;
 	close $fd;
 	git_header_div('shortlog');
-	git_shortlog_body(\@revlist, 0, 15, $refs,
+	git_shortlog_body(\@revlist, 0, 15, $refs, $heads,
 	                  $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=shortlog")}, "..."));
 
 	my $taglist = git_read_refs("refs/tags");
@@ -1746,8 +1748,10 @@ sub git_tree {
 	close $fd or die_error(undef, "Reading tree failed");
 	$/ = "\n";
 
-	my $refs = read_info_ref();
-	my $ref = git_get_referencing($refs, $hash_base);
+	my $refs = read_info_ref("tags");
+	my $heads = read_info_ref("heads");
+	my $ref = git_get_referencing($refs, $hash_base, "tag");
+	my $head = git_get_referencing($heads, $hash_base, "head");
 	git_header_html();
 	my $base_key = "";
 	my $base = "";
@@ -1755,7 +1759,7 @@ sub git_tree {
 	if (defined $hash_base && (my %co = git_read_commit($hash_base))) {
 		$base_key = ";hb=$hash_base";
 		git_page_nav('tree','', $hash_base);
-		git_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base);
+		git_header_div('commit', esc_html($co{'title'}) . $ref . $head, $hash_base);
 	} else {
 		print "<div class=\"page_nav\">\n";
 		print "<br/><br/></div>\n";
@@ -1818,7 +1822,8 @@ sub git_log {
 	if (!defined $page) {
 		$page = 0;
 	}
-	my $refs = read_info_ref();
+	my $refs = read_info_ref("tags");
+	my $heads = read_info_ref("heads");
 
 	my $limit = sprintf("--max-count=%i", (100 * ($page+1)));
 	open my $fd, "-|", $GIT, "rev-list", $limit, $hash
@@ -1839,13 +1844,14 @@ sub git_log {
 	}
 	for (my $i = ($page * 100); $i <= $#revlist; $i++) {
 		my $commit = $revlist[$i];
-		my $ref = git_get_referencing($refs, $commit);
+		my $ref = git_get_referencing($refs, $commit, "tag");
+		my $head = git_get_referencing($heads, $commit, "head");
 		my %co = git_read_commit($commit);
 		next if !%co;
 		my %ad = date_str($co{'author_epoch'});
 		git_header_div('commit',
 		               "<span class=\"age\">$co{'age_string'}</span>" .
-		               esc_html($co{'title'}) . $ref,
+		               esc_html($co{'title'}) . $ref . $head,
 		               $commit);
 		print "<div class=\"title_text\">\n" .
 		      "<div class=\"log_link\">\n" .
@@ -1902,8 +1908,10 @@ sub git_commit {
 	if ($hash =~ m/^[0-9a-fA-F]{40}$/) {
 		$expires = "+1d";
 	}
-	my $refs = read_info_ref();
-	my $ref = git_get_referencing($refs, $co{'id'});
+	my $refs = read_info_ref("tags");
+	my $heads = read_info_ref("heads");
+	my $ref = git_get_referencing($refs, $co{'id'}, "tag");
+	my $head = git_get_referencing($heads, $co{'id'}, "head");
 	my $formats_nav = '';
 	if (defined $file_name && defined $co{'parent'}) {
 		my $parent = $co{'parent'};
@@ -1915,9 +1923,9 @@ sub git_commit {
 	             $formats_nav);
 
 	if (defined $co{'parent'}) {
-		git_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash);
+		git_header_div('commitdiff', esc_html($co{'title'}) . $ref . $head, $hash);
 	} else {
-		git_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash);
+		git_header_div('tree', esc_html($co{'title'}) . $ref . $head, $co{'tree'}, $hash);
 	}
 	print "<div class=\"title_text\">\n" .
 	      "<table cellspacing=\"0\">\n";
@@ -2126,13 +2134,15 @@ sub git_commitdiff {
 	if ($hash =~ m/^[0-9a-fA-F]{40}$/) {
 		$expires = "+1d";
 	}
-	my $refs = read_info_ref();
-	my $ref = git_get_referencing($refs, $co{'id'});
+	my $refs = read_info_ref("tags");
+	my $heads = read_info_ref("heads");
+	my $ref = git_get_referencing($refs, $co{'id'}, "tag");
+	my $head = git_get_referencing($heads, $co{'id'}, "head");
 	my $formats_nav =
 		$cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent")}, "plain");
 	git_header_html(undef, $expires);
 	git_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);
-	git_header_div('commit', esc_html($co{'title'}) . $ref, $hash);
+	git_header_div('commit', esc_html($co{'title'}) . $ref . $head, $hash);
 	print "<div class=\"page_body\">\n";
 	my $comment = $co{'comment'};
 	my $empty = 0;
@@ -2271,7 +2281,8 @@ sub git_history {
 	if (!%co) {
 		die_error(undef, "Unknown commit object");
 	}
-	my $refs = read_info_ref();
+	my $refs = read_info_ref("tags");
+	my $heads = read_info_ref("heads");
 	git_header_html();
 	git_page_nav('','', $hash_base,$co{'tree'},$hash_base);
 	git_header_div('commit', esc_html($co{'title'}), $hash_base);
@@ -2294,7 +2305,8 @@ sub git_history {
 			if (!%co) {
 				next;
 			}
-			my $ref = git_get_referencing($refs, $commit);
+			my $ref = git_get_referencing($refs, $commit, "tag");
+			my $head = git_get_referencing($heads, $commit, "head");
 			if ($alternate) {
 				print "<tr class=\"dark\">\n";
 			} else {
@@ -2304,7 +2316,7 @@ sub git_history {
 			print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
 			      "<td><i>" . esc_html(chop_str($co{'author_name'}, 15, 3)) . "</i></td>\n" .
 			      "<td>" . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit"), -class => "list"}, "<b>" .
-			      esc_html(chop_str($co{'title'}, 50)) . "$ref</b>") . "</td>\n" .
+			      esc_html(chop_str($co{'title'}, 50)) . $ref . $head . "</b>") . "</td>\n" .
 			      "<td class=\"link\">" .
 			      $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commit;h=$commit")}, "commit") .
 			      " | " . $cgi->a({-href => "$my_uri?" . esc_param("p=$project;a=commitdiff;h=$commit")}, "commitdiff") .
@@ -2468,7 +2480,8 @@ sub git_shortlog {
 	if (!defined $page) {
 		$page = 0;
 	}
-	my $refs = read_info_ref();
+	my $refs = read_info_ref("tags");
+	my $heads = read_info_ref("heads");
 
 	my $limit = sprintf("--max-count=%i", (100 * ($page+1)));
 	open my $fd, "-|", $GIT, "rev-list", $limit, $hash
@@ -2489,7 +2502,7 @@ sub git_shortlog {
 	git_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav);
 	git_header_div('summary', $project);
 
-	git_shortlog_body(\@revlist, ($page * 100), $#revlist, $refs, $next_link);
+	git_shortlog_body(\@revlist, ($page * 100), $#revlist, $refs, $heads, $next_link);
 
 	git_footer_html();
 }

----


Bye,
Thomas
-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
Jakub Narebski· Aug 11, 2006, 15:34 UTC · re: Thomas Kolejka · lore

Re: [PATCH] gitweb: Different colours for tags and heads

Thomas Kolejka wrote:
Show 7 quoted lines
> Hello,
> 
> with the following patch there are different colours for tags
> and heads in gitweb. So you can easily differentiate between 
> them.
> 
> Commit ca9e3b124f6313187da641b5cd55100c4ade6a9a
Based on which branch? Master, next? Which commit?

By the way, please do not put "Hello," in the commit message part of patch. You can put your comments (like which branch and/or commit is the batch based on) either after "---" and before the patch itself, or at the beginning and separate them from the commit message by "+++" (this separator is supported by git tools, but some people use "-- >8 --" 'scissors' separator). git-format-patch helps in correct formatting, and adds diffstat.

You would also be most probably asked to sign your patches, i.e.
add
  Signed-off-by: Thomas Kolejka <Thomas.Kolejka@gmx.at>
line at the end of commit message.
I have send patch of similar nature:
  "[PATCH 5/5] gitweb: Change appereance of marker of refs pointing to given object"
  http://permalink.gmane.org/gmane.comp.version-control.git/24860
in which I split marker for refs poining to given object into
separate span elements. The patch was dropped because it followed
first version of "Great subroutine renames" patch.

I've planned on patch which does something similar to yours, but in slightly different way: instead of two calls to git_get_referencing (format_mark_referencing[*1*] after rename) and two calls to read_info_ref (git_get_references after rename) in your patch, read_info_ref would always add full name, of which first component is the type of the tag.

I am wondering if to do this like in my abovementioned patch, putting references in single string, separated by ':' (':' cannot be part of valid ref name), or use array (anonymous array reference to be more exact).

[*1*] Do you have better proposal for this name? Perhaps format_referencing_marker, or just format_marker?

---
Show 11 quoted lines
>  # format marker of refs pointing to given object
>  sub git_get_referencing {
> -     my ($refs, $id) = @_;
> +     my ($refs, $id, $class) = @_;
>  
>       if (defined $refs->{$id}) {
> -             return ' <span class="tag">' . esc_html($refs->{$id}) . '</span>';
> +             return " <span class=\"$class\">" . esc_html($refs->{$id}) . "</span>";
>       } else {
>               return "";
>       }
[...]
> -     my ($revlist, $from, $to, $refs, $extra) = @_;
> +     my ($revlist, $from, $to, $refs, $heads, $extra) = @_;
[...]
Show 5 quoted lines
> -             #my $ref = defined $refs ? git_get_referencing($refs, $commit) : '';
> -             my $ref = git_get_referencing($refs, $commit);
> +             #my $ref = defined $refs ? git_get_referencing($refs, $commit, "tag") : '';
> +             my $ref = git_get_referencing($refs, $commit, "tag");
> +             my $head = git_get_referencing($heads, $commit, "head");
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Junio C Hamano· Aug 11, 2006, 21:50 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: Different colours for tags and heads

Jakub Narebski <jnareb@gmail.com> writes:
Show 6 quoted lines
> By the way, please do not put "Hello," in the commit message
> part of patch. You can put your comments (like which branch
> and/or commit is the batch based on) either after "---" and
> before the patch itself, or at the beginning and separate them
> from the commit message by "+++" (this separator is supported
> by git tools,...
???
Show 6 quoted lines
> I've planned on patch which does something similar to
> yours, but in slightly different way: instead of two calls 
> to git_get_referencing (format_mark_referencing[*1*] after rename)
> and two calls to read_info_ref (git_get_references after rename)
> in your patch, read_info_ref would always add full name, of
> which first component is the type of the tag.
get_referencing to get, and format_ref to format perhaps?
> I am wondering if to do this like in my abovementioned patch,
> putting references in single string, separated by ':' (':' cannot
> be part of valid ref name), or use array (anonymous array reference
> to be more exact). 
Two things and half come to mind.

get_referencing could get and return the full refname without abbreviation ('heads/jn/web' or 'tags/v1.0'), and the caller can do whatever with them (e.g. see what the name begins with to tell heads and tags apart). This is probably the most flexible if we do not want to cast the categorization of refs in stone.

Otherwise, return an arrayref, like ['tag', 'v1.0', 'v1.0'] or ['head', 'web', 'jn/web'], to say what kind, short name and full name.

I've always wondered if the span that shows the short refname could have an on-hover pop-up (title attribute is often shown that way) to show the full name. Then you could do something like:

    $long_name = 'heads/jn/web'; # or 'tags/v1.0'
    $kind = ($long_name =~ /^heads/) ? 'head' : 'tag';
    $long_name = s|^[^/]*/||;
    ($short_name = $long_name) =~ s|.*/||;
    $long_name = esc_html($long_name);
    $short_name = esc_html($short_name);
    return " <span class='$kind' title='$long_name'>$short_name</span>";
Jakub Narebski· Aug 12, 2006, 00:12 UTC · re: Junio C Hamano · lore

Re: [PATCH] gitweb: Different colours for tags and heads

Junio C Hamano wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
Show 8 quoted lines
>> I've planned on patch which does something similar to
>> yours, but in slightly different way: instead of two calls 
>> to git_get_referencing (format_mark_referencing[*1*] after rename)
>> and two calls to read_info_ref (git_get_references after rename)
>> in your patch, read_info_ref would always add full name, of
>> which first component is the type of the tag.
> 
> get_referencing to get, and format_ref to format perhaps?
Thanks for a suggestion. I've decided on git_get_references, and
format_ref_marker,but it isn't cast in stone.
 
Show 16 quoted lines
>> I am wondering if to do this like in my abovementioned patch,
>> putting references in single string, separated by ':' (':' cannot
>> be part of valid ref name), or use array (anonymous array reference
>> to be more exact). 
> 
> Two things and half come to mind.
> 
> get_referencing could get and return the full refname without
> abbreviation ('heads/jn/web' or 'tags/v1.0'), and the caller can
> do whatever with them (e.g. see what the name begins with to
> tell heads and tags apart).  This is probably the most flexible
> if we do not want to cast the categorization of refs in stone.
> 
> Otherwise, return an arrayref, like ['tag', 'v1.0', 'v1.0'] or
> ['head', 'web', 'jn/web'], to say what kind, short name and full
> name.

Perhaps I have not said things clearly. The problem I meant to solve is the fact that there might be more than one ref pointing to a given object. Currently read_info_ref does not its job joining references pointing to given object (referenced object is key of a hash) using " / ", i.e. creating the "joined tag".

In dropped patch I've mentioned I joined references using ':' as it can't be part of valid ref name, then split it on ':' on formatting.

But they can be put into anonymous arrayref (e.g. ['heads/next', 'heads/autoconf'] at the start of 'autoconf' branch, or ['heads/master', 'heads/next', 'tags/v1.4.2'], not 'heads/master:heads/next:tags/v1.4.2' my patch did.

Show 12 quoted lines
> I've always wondered if the span that shows the short refname
> could have an on-hover pop-up (title attribute is often shown
> that way) to show the full name.  Then you could do something
> like:
> 
>     $long_name = 'heads/jn/web'; # or 'tags/v1.0'
>     $kind = ($long_name =~ /^heads/) ? 'head' : 'tag';
>     $long_name = s|^[^/]*/||;
>     ($short_name = $long_name) =~ s|.*/||;
>     $long_name = esc_html($long_name);
>     $short_name = esc_html($short_name);
>     return " <span class='$kind' title='$long_name'>$short_name</span>";
Currently (in core-git) besides 'heads' and 'tags' there might be
'remotes' (when using --use-separate-remote' option of git-clone), all
following the rule of being plural (in English) to the type of tag, so one
could use
        $ref =~ m|(^[^/])*s?/|;
        $kind = $1;
for kind.

By the way, is it really usefull to have shortened ref name, e.g. 'web' for 'jn/web'? That is what gitweb does currently (only without giving ling name at all). It is probably bad practice, but I've had branches ab/sth and zz/sth, with the same shortname.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Junio C Hamano· Aug 12, 2006, 00:58 UTC · re: Jakub Narebski · lore

Re: [PATCH] gitweb: Different colours for tags and heads

Jakub Narebski <jnareb@gmail.com> writes:
> But they can be put into anonymous arrayref (e.g. ['heads/next',
> 'heads/autoconf'] at the start of 'autoconf' branch, or ['heads/master',
> 'heads/next', 'tags/v1.4.2'], not 'heads/master:heads/next:tags/v1.4.2'
> my patch did.

Concatenating them with ':' into a single string, only to later split it, sounds simply stupid; I'd go for arrayref if I were you.

> By the way, is it really usefull to have shortened ref name, e.g. 'web' for
> 'jn/web'? That is what gitweb does currently (only without giving ling name
> at all). It is probably bad practice, but I've had branches ab/sth and
> zz/sth, with the same shortname.

I think most people tend to use unique refs, so maybe showing the shortname by default and unique suffix when ambiguous (that would end up always showing minimal unique suffix) would be reasonable.

Martin Waitz· Aug 14, 2006, 05:22 UTC · re: Junio C Hamano · lore

Re: [PATCH] gitweb: Different colours for tags and heads

hoi :)
On Fri, Aug 11, 2006 at 02:50:31PM -0700, Junio C Hamano wrote:
Show 9 quoted lines
> Jakub Narebski <jnareb@gmail.com> writes:
> > By the way, please do not put "Hello," in the commit message
> > part of patch. You can put your comments (like which branch
> > and/or commit is the batch based on) either after "---" and
> > before the patch itself, or at the beginning and separate them
> > from the commit message by "+++" (this separator is supported
> > by git tools,...
> 
> ???
the +++ feature has never been accepted for GIT.
-- 
Martin Waitz

← back to recent threads