Git development
 help / color / mirror / Atom feed
* Re: [PATCH] gitweb: bugfix: a.list formatting regression
From: Jakub Narebski @ 2006-08-22 22:46 UTC (permalink / raw)
  To: git
In-Reply-To: <7vr6z8mmb7.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:

> Jakub Narebski <jnareb@git.vger.kernel.org> writes:
(the above is result of paste in wrong place in git-send-email invocation)
[...]
>> The fix is to add "subject" class and use this class
>> to replace pre-format_subject_html formatting of subject
>> (comment) via using (or not) <b>...</b> element. This
>> should go back to the pre-17d0744318... style.
[...]
> 
> I haven't seen an Ack from Luben for the proposed renaming of
> the class, although I very much like naming things for what they
> mean (i.e. "subject"), not what they do (i.e. "bold") myself.
> 
> It might be worthwhile to do a full sweep of the pages we
> generate and identify what classes we would want.  I have a
> feeling that we overuse a.list for example -- they are all in
> some form of list alright but they might benefit from a bit
> finer logical separatoin.  One list is enumaration of refs and
> another is a chronological sequence of commits.
> 
> Then people who would want to tweak the presentation would have
> an easier time changing only gitweb.css.

Next patch in this series of patches 
   [PATCH] gitweb: Replace some presentational HTML by CSS
   Message-Id: <11562431392439-git-send-email-jnareb@git.vger.kernel.org>
adds "name" subclass (a.list.name) for ref names. (I think
subclasses/multiple classes is the way to do it, as all a.list
elements have something in common: use next class to divide).

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [RFD] gitweb: href() function to generate URLs for CGI
From: Jakub Narebski @ 2006-08-22 22:39 UTC (permalink / raw)
  To: git
In-Reply-To: <7vveokmmpr.fsf@assigned-by-dhcp.cox.net>

Junio C Hamano wrote:

> Jakub Narebski <jnareb@gmail.com> writes:
> 
>> URL for search is created and encoded by browser I think, so search
>> for "a = b" generates
>>
>>         gitweb.cgi?p=git.git&a=search&h=HEAD&s=a+%3D+b
> 
> which means href() should generate something similar when it
> wants to reproduce what the user queried, doesn't it?  I do not
> think quoting after joining does, and that is why I asked that
> question.

Yes, ot should... but first we would have to convert all the
cases of generating URI via esc_param(...) to using href().
That means to extend href() somewhat (-absolute=>1 as special
value in href() parameters, or changing href(%) to href(\%;$)?)
to be able to generate absolute URI (for example for RSS/OPML).

And the case is not that inconceivable: $project can be anything,
and can have ';' and '=' inside. I'm not sure about valid symbolic refs...

Usage of '&' as query parameters separator instead of ';' probably
depend on the browser...
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH] gitweb: bugfix: a.list formatting regression
From: Junio C Hamano @ 2006-08-22 22:34 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git, Luben Tuikov
In-Reply-To: <11562409683011-git-send-email-jnareb@git.vger.kernel.org>

Jakub Narebski <jnareb@git.vger.kernel.org> writes:

> From: Jakub Narebski <jnareb@gmail.com>
>
> Fix regression introduced by
> commit 17d07443188909ef5f8b8c24043cb6d9fef51bca.
>
> "a.list" being "bold", makes a myriad of things shown by
> gitweb in bold font-weight, which is a regression from
> pre-17d07443188909ef5f8b8c24043cb6d9fef51bca behavior.
>
> The fix is to add "subject" class and use this class
> to replace pre-format_subject_html formatting of subject
> (comment) via using (or not) <b>...</b> element. This
> should go back to the pre-17d0744318... style.
>
> Regression noticed by Luben Tuikov.
>
> Signed-off-by: Jakub Narebski <jnareb@gmail.com>
> Signed-off-by: Luben Tuikov <ltuikov@yahoo.com>
> ---

I haven't seen an Ack from Luben for the proposed renaming of
the class, although I very much like naming things for what they
mean (i.e. "subject"), not what they do (i.e. "bold") myself.

It might be worthwhile to do a full sweep of the pages we
generate and identify what classes we would want.  I have a
feeling that we overuse a.list for example -- they are all in
some form of list alright but they might benefit from a bit
finer logical separatoin.  One list is enumaration of refs and
another is a chronological sequence of commits.

Then people who would want to tweak the presentation would have
an easier time changing only gitweb.css.

^ permalink raw reply

* Re: [RFD] gitweb: href() function to generate URLs for CGI
From: Junio C Hamano @ 2006-08-22 22:26 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <ecenc1$b5o$1@sea.gmane.org>

Jakub Narebski <jnareb@gmail.com> writes:

> URL for search is created and encoded by browser I think, so search
> for "a = b" generates
>
>         gitweb.cgi?p=git.git&a=search&h=HEAD&s=a+%3D+b

which means href() should generate something similar when it
wants to reproduce what the user queried, doesn't it?  I do not
think quoting after joining does, and that is why I asked that
question.

^ permalink raw reply

* Re: [RFD] gitweb: href() function to generate URLs for CGI
From: Junio C Hamano @ 2006-08-22 22:21 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: git
In-Reply-To: <ecfnqj$5m9$1@sea.gmane.org>

Jakub Narebski <jnareb@gmail.com> writes:

> Third, read comment to esc_param:
>
>         # quote unsafe chars, but keep the slash, even when it's not
>         # correct, but quoted slashes look too horrible in bookmarks
>
> I assume that URI module methods do not keep slash...

I do not think so either but I do not necessarily agree with
that comment ;-).

^ permalink raw reply

* Re: [PATCH 4/3] gitweb: Use here-doc
From: Jakub Narebski @ 2006-08-22 21:54 UTC (permalink / raw)
  To: git
In-Reply-To: <200608222342.53861.jnareb@gmail.com>

Jakub Narebski wrote:

> This patch uses undocumented, at least in perlop(1), trick in
> interpolation that allows calling function from interpolated string,
> using ${\subroutine_name(parameters...)}, found in git_blame,
> and used in git_rss here-doc in this patch.

It is trick, using ${...} syntax described in perlref(1), where ... is a
expression returning reference (in our case scalar reference).
${\...} is similar to @{[...]} trick, dereference(reference(value)), where
dereference is only to have interpolation.  

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* [PATCH 4/3] gitweb: Use here-doc
From: Jakub Narebski @ 2006-08-22 21:42 UTC (permalink / raw)
  To: git
In-Reply-To: <200608221651.19629.jnareb@gmail.com>

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This patch uses undocumented, at least in perlop(1), trick in
interpolation that allows calling function from interpolated string,
using ${\subroutine_name(parameters...)}, found in git_blame,
and used in git_rss here-doc in this patch.

This patch is part of "[PATCH 0/3] gitweb: Yet another cleanup series"
series.

 gitweb/gitweb.perl |   75 
+++++++++++++++++++++++++++++++---------------------
 1 files changed, 44 insertions(+), 31 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index e09204d..5301213 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1185,11 +1185,13 @@ sub die_error {
 	my $error = shift || "Malformed query, file missing or permission 
denied";
 
 	git_header_html($status);
-	print "<div class=\"page_body\">\n" .
-	      "<br/><br/>\n" .
-	      "$status - $error\n" .
-	      "<br/>\n" .
-	      "</div>\n";
+	print <<EOF;
+<div class="page_body">
+<br /><br />
+$status - $error
+<br />
+</div>
+EOF
 	git_footer_html();
 	exit;
 }
@@ -2026,9 +2028,11 @@ sub git_blame2 {
 	my $num_colors = scalar(@rev_color);
 	my $current_color = 0;
 	my $last_rev;
-	print "<div class=\"page_body\">\n";
-	print "<table class=\"blame\">\n";
-	print "<tr><th>Commit</th><th>Line</th><th>Data</th></tr>\n";
+	print <<HTML;
+<div class="page_body">
+<table class="blame">
+<tr><th>Commit</th><th>Line</th><th>Data</th></tr>
+HTML
 	while (<$fd>) {
 		/^([0-9a-fA-F]{40}).*?(\d+)\)\s{1}(\s*.*)/;
 		my $full_rev = $1;
@@ -2570,9 +2574,10 @@ sub git_blobdiff {
 		git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, 
$formats_nav);
 		git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
 	} else {
-		print "<div class=\"page_nav\">\n" .
-		      "<br/><br/></div>\n" .
-		      "<div class=\"title\">$hash vs $hash_parent</div>\n";
+		print <<HTML;
+<div class="page_nav"><br/><br/></div>
+<div class="title">$hash vs $hash_parent</div>
+HTML
 	}
 	git_print_page_path($file_name, "blob", $hash_base);
 	print "<div class=\"page_body\">\n" .
@@ -2708,9 +2713,11 @@ sub git_commitdiff_plain {
 	                   -content_disposition => "inline; 
filename=\"git-$hash.patch\"");
 	my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});
 	my $comment = $co{'comment'};
-	print "From: $co{'author'}\n" .
-	      "Date: $ad{'rfc2822'} ($ad{'tz_local'})\n".
-	      "Subject: $co{'title'}\n";
+	print <<TEXT;
+From: $co{'author'}
+Date: $ad{'rfc2822'} ($ad{'tz_local'})
+Subject: $co{'title'}
+TEXT
 	if (defined $tagname) {
 		print "X-Git-Tag: $tagname\n";
 	}
@@ -2995,13 +3002,15 @@ sub git_rss {
 	my @revlist = map { chomp; $_ } <$fd>;
 	close $fd or die_error(undef, "Reading git-rev-list failed");
 	print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
-	print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".
-	      "<rss version=\"2.0\" 
xmlns:content=\"http://purl.org/rss/1.0/modules/content/\">\n";
-	print "<channel>\n";
-	print "<title>$project</title>\n".
-	      "<link>" . esc_html("$my_url?p=$project;a=summary") . 
"</link>\n".
-	      "<description>$project log</description>\n".
-	      "<language>en</language>\n";
+	print <<XML;
+<?xml version="1.0" encoding="utf-8"?>
+<rss version="2.0" 
xmlns:content="http://purl.org/rss/1.0/modules/content/">
+<channel>
+<title>$project $my_uri $my_url</title>
+<link>${\esc_html("$my_url?p=$project;a=summary")}</link>
+<description>$project log</description>
+<language>en</language>
+XML
 
 	for (my $i = 0; $i <= $#revlist; $i++) {
 		my $commit = $revlist[$i];
@@ -3050,13 +3059,15 @@ sub git_opml {
 	my @list = git_get_projects_list();
 
 	print $cgi->header(-type => 'text/xml', -charset => 'utf-8');
-	print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n".
-	      "<opml version=\"1.0\">\n".
-	      "<head>".
-	      "  <title>$site_name Git OPML Export</title>\n".
-	      "</head>\n".
-	      "<body>\n".
-	      "<outline text=\"git RSS feeds\">\n";
+	print <<XML;
+<?xml version="1.0" encoding="utf-8"?>
+<opml version="1.0">
+<head>
+  <title>$site_name Git OPML Export</title>
+</head>
+<body>
+<outline text="git RSS feeds">
+XML
 
 	foreach my $pr (@list) {
 		my %proj = %$pr;
@@ -3075,7 +3086,9 @@ sub git_opml {
 		my $html = "$my_url?p=$proj{'path'};a=summary";
 		print "<outline type=\"rss\" text=\"$path\" title=\"$path\" 
xmlUrl=\"$rss\" htmlUrl=\"$html\"/>\n";
 	}
-	print "</outline>\n".
-	      "</body>\n".
-	      "</opml>\n";
+	print <<XML;
+</outline>
+</body>
+</opml>
+XML
 }
-- 
1.4.1.1

^ permalink raw reply related

* Re: HELP: GIT Cloning failed
From: Phillip Susi @ 2006-08-22 21:08 UTC (permalink / raw)
  To: Ju, Seokmann; +Cc: git, Patro, Sumant, linux-kernel
In-Reply-To: <890BF3111FB9484E9526987D912B261932E35B@NAMAIL3.ad.lsil.com>

Is there a reason that you regularly delete and re-download the entire 
repository, rather than simply doing a git pull to update your existing 
clone?

Ju, Seokmann wrote:
> Hi,
> 
> Recently, I found that cloning from GIT server has been failed.
> I'm using following script for it.
> ---
> ...
> rm -r /home/git/kernels/2.4/linux-2.4.git
> cg-clone
> http://www.kernel.org/pub/scm/linux/kernel/git/marcelo/linux-2.4.git/
> /home/git/kernels/2.4/linux-2.4.git/
> sync
> rm -r /home/git/kernels/2.4/linux-2.6.git
> cg-clone
> http://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/
> /home/git/kernels/2.4/linux-2.6.git/
> sync
> rm -r /home/git/kernels/2.4/scsi-misc-2.6.git
> cg-clone
> http://www.kernel.org/pub/scm/linux/kernel/git/marcelo/scsi-misc-2.6.git
> /home/git/kernels/2.4/scsi-misc-2.6.git
> sync
> ...
> ---
> 
> In the script, I'm cloning 3 different sources. First two sources
> getting successfully cloned, however, last one is getting failed with
> following error messages,
> ---
> Fetching head...
> Fetching objects...
> Getting alternates list for
> http://www.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
> Also look at http://www.kernel.or
> Error: The requested URL returned error: 502 (curl_result = 22,
> http_code = 502, sha1 = 1039f0760e...)
> Getting pack list for
> http://www.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git/
> Getting pack list for http://www.kernel.or
> Error: The requested URL returned error: 502
> Error: Unable to find 27fd37621... Under
> http://www.kernel.org/pub/scsm/linux/kernel/git/jejb/scsi-misc-2.6.git/
> Cannot obtain needed blob 27fd37621...
> While processing commit 4041b9cd87...
> Progress: 8 objects, 13120 bytes
> Cg-fetch: objects fetch failed
> ---
> 
> Above script worked without any problem when I started several months
> ago and I'm not sure when did it stop working.
> I'm using _cron_ utility on my Linux box for scheduled execution of the
> script.
> 
> Any comment would be appreciated.
> 
> Thank you,
> 
> Seokmann

^ permalink raw reply

* RE: HELP: GIT Cloning failed
From: Ju, Seokmann @ 2006-08-22 20:24 UTC (permalink / raw)
  To: Sean; +Cc: git, Patro, Sumant, linux-kernel

Hi,
On Tuesday, August 22, 2006 4:08 PM, Sean  wrote:
> It looks like the jejb scsi-misc archive might not have been
> configured properly for http transfers.  There's a script below
> which just uses git commands (not cogito) and the native git
> protocol which tests out okay here.
I will try with the script and rest of your comments as well.
Thank you for your guidence.

Regards,

Seokmann


> -----Original Message-----
> From: Sean [mailto:seanlkml@sympatico.ca] 
> Sent: Tuesday, August 22, 2006 4:08 PM
> To: Ju, Seokmann
> Cc: git@vger.kernel.org; Patro, Sumant; linux-kernel@vger.kernel.org
> Subject: Re: HELP: GIT Cloning failed
> 
> On Tue, 22 Aug 2006 13:25:23 -0600
> "Ju, Seokmann" <Seokmann.Ju@lsil.com> wrote:
> 
> Ju,
> 
> > Above script worked without any problem when I started 
> several months
> > ago and I'm not sure when did it stop working.
> > I'm using _cron_ utility on my Linux box for scheduled 
> execution of the
> > script.
> > 
> > Any comment would be appreciated.
> 
> It looks like the jejb scsi-misc archive might not have been
> configured properly for http transfers.  There's a script below
> which just uses git commands (not cogito) and the native git
> protocol which tests out okay here.
> 
> A few comments though:
> 
>  - Apparently the scsi misc tree you want is actually under "jejb"
>    rather than "marcelo" which you had in your script.
> 
>  - It's better to use the native git protocol when possible
>    (well, the benefits are less on initial clone, but it's still
>    a good practice)
> 
>  - You're causing a lot of unnecessary traffic for kernel.org by
>    cloning a fresh copy of all these trees, it would be much better
>    to clone just _once_ and then simply "git pull" in any updates.
> 
>  - Two of the trees you're cloning are very close in content to
>    each other (linux-2.6 & scsi-misc-2.6) so you can use the git
>    "--reference" option to share local objects saving disk space
>    (and reducing bandwidth needs even further)
> 
> Cheers,
> Sean
> 
> #!/bin/sh
> cd /home/git/kernels/2.4 || exit
> BASE="git://www.kernel.org/pub/scm/linux/kernel/git"
> rm -rf linux-2.4 linux-2.6 scsi-misc-2.6
> git clone $BASE/marcelo/linux-2.4
> git clone $BASE/torvalds/linux-2.6
> git clone --reference linux-2.6 $BASE/jejb/scsi-misc-2.6
> 
> 
> 
> 

^ permalink raw reply

* Re: HELP: GIT Cloning failed
From: Sean @ 2006-08-22 20:08 UTC (permalink / raw)
  To: Ju, Seokmann; +Cc: git, Patro, Sumant, linux-kernel
In-Reply-To: <890BF3111FB9484E9526987D912B261932E35B@NAMAIL3.ad.lsil.com>

On Tue, 22 Aug 2006 13:25:23 -0600
"Ju, Seokmann" <Seokmann.Ju@lsil.com> wrote:

Ju,

> Above script worked without any problem when I started several months
> ago and I'm not sure when did it stop working.
> I'm using _cron_ utility on my Linux box for scheduled execution of the
> script.
> 
> Any comment would be appreciated.

It looks like the jejb scsi-misc archive might not have been
configured properly for http transfers.  There's a script below
which just uses git commands (not cogito) and the native git
protocol which tests out okay here.

A few comments though:

 - Apparently the scsi misc tree you want is actually under "jejb"
   rather than "marcelo" which you had in your script.

 - It's better to use the native git protocol when possible
   (well, the benefits are less on initial clone, but it's still
   a good practice)

 - You're causing a lot of unnecessary traffic for kernel.org by
   cloning a fresh copy of all these trees, it would be much better
   to clone just _once_ and then simply "git pull" in any updates.

 - Two of the trees you're cloning are very close in content to
   each other (linux-2.6 & scsi-misc-2.6) so you can use the git
   "--reference" option to share local objects saving disk space
   (and reducing bandwidth needs even further)

Cheers,
Sean

#!/bin/sh
cd /home/git/kernels/2.4 || exit
BASE="git://www.kernel.org/pub/scm/linux/kernel/git"
rm -rf linux-2.4 linux-2.6 scsi-misc-2.6
git clone $BASE/marcelo/linux-2.4
git clone $BASE/torvalds/linux-2.6
git clone --reference linux-2.6 $BASE/jejb/scsi-misc-2.6

^ permalink raw reply

* Re: HELP: GIT Cloning failed
From: Sean @ 2006-08-22 20:08 UTC (permalink / raw)
  To: Ju, Seokmann; +Cc: git, Patro, Sumant, linux-kernel
In-Reply-To: <890BF3111FB9484E9526987D912B261932E35B@NAMAIL3.ad.lsil.com>

On Tue, 22 Aug 2006 13:25:23 -0600
"Ju, Seokmann" <Seokmann.Ju@lsil.com> wrote:

Ju,

> Above script worked without any problem when I started several months
> ago and I'm not sure when did it stop working.
> I'm using _cron_ utility on my Linux box for scheduled execution of the
> script.
> 
> Any comment would be appreciated.

It looks like the jejb scsi-misc archive might not have been
configured properly for http transfers.  There's a script below
which just uses git commands (not cogito) and the native git
protocol which tests out okay here.

A few comments though:

 - Apparently the scsi misc tree you want is actually under "jejb"
   rather than "marcelo" which you had in your script.

 - It's better to use the native git protocol when possible
   (well, the benefits are less on initial clone, but it's still
   a good practice)

 - You're causing a lot of unnecessary traffic for kernel.org by
   cloning a fresh copy of all these trees, it would be much better
   to clone just _once_ and then simply "git pull" in any updates.

 - Two of the trees you're cloning are very close in content to
   each other (linux-2.6 & scsi-misc-2.6) so you can use the git
   "--reference" option to share local objects saving disk space
   (and reducing bandwidth needs even further)

Cheers,
Sean

#!/bin/sh
cd /home/git/kernels/2.4 || exit
BASE="git://www.kernel.org/pub/scm/linux/kernel/git"
rm -rf linux-2.4 linux-2.6 scsi-misc-2.6
git clone $BASE/marcelo/linux-2.4
git clone $BASE/torvalds/linux-2.6
git clone --reference linux-2.6 $BASE/jejb/scsi-misc-2.6

^ permalink raw reply

* Re: [RFD] gitweb: href() function to generate URLs for CGI
From: Jakub Narebski @ 2006-08-22 20:01 UTC (permalink / raw)
  To: git
In-Reply-To: <ecfnf0$4bg$1@sea.gmane.org>

<opublikowany i wysłany>

Jakub Narebski wrote:

> Randal L. Schwartz wrote:
> 
>>>>>>> "Junio" == Junio C Hamano <junkio@cox.net> writes:
>> 
>> Junio>        my @result = (); 
>> Junio>         for (my $i = 0; $i < @mapping; $i += 2) {
>> Junio>                my ($name, $symbol) = ($mapping[$i], $mapping[$i+1]);
>> Junio>                if (defined $params{$name}) {
>> Junio>                        push @result, "$symbol=$params{$name}";
>> Junio>                }
>> Junio>        }
>> Junio>         return "$my_uri?" . esc_param(join(';', @result));
>> Junio> }
>> 
>> If you already depend on the LWP package, then the "URI" module
>> does precisely what you're reinventing.
>> 
>> my $uri = URI->new("http://host/base/path")
>> $uri->query_form(\%params);
>> my $result = $uri->as_string;
>> 
>> And I'd rely on Gisle Aas's experience about constructing these things
>> far more than the thread I've just witnessed here. :)
> 
> First, I'd rather not introduce new dependency to git (and I think Junio
> would agree). Second, more important, we do _parameters processing_,
> it means renaming parameters (e.g. 'file_name' in params is 'p' in CGI URI),
> in the future perhaps passing project via PATH_INFO not in query string,
> and sorting the CGI parameters.
> 
> So it wouldn't be as easy as writing 
>         $uri->query_form(\%params); 
>         return $uri->as_string;
> or as 
>         return "$my_uri?" . esc_param(join(";", "$_=$params{$_}") keys %params)'.

Third, read comment to esc_param:

        # quote unsafe chars, but keep the slash, even when it's not
        # correct, but quoted slashes look too horrible in bookmarks

I assume that URI module methods do not keep slash...
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [RFD] gitweb: href() function to generate URLs for CGI
From: Jakub Narebski @ 2006-08-22 19:55 UTC (permalink / raw)
  To: git
In-Reply-To: <86fyfohb4v.fsf@blue.stonehenge.com>

Randal L. Schwartz wrote:

>>>>>> "Junio" == Junio C Hamano <junkio@cox.net> writes:
> 
> Junio>        my @result = (); 
> Junio>         for (my $i = 0; $i < @mapping; $i += 2) {
> Junio>                my ($name, $symbol) = ($mapping[$i], $mapping[$i+1]);
> Junio>                if (defined $params{$name}) {
> Junio>                        push @result, "$symbol=$params{$name}";
> Junio>                }
> Junio>        }
> Junio>         return "$my_uri?" . esc_param(join(';', @result));
> Junio> }
> 
> If you already depend on the LWP package, then the "URI" module
> does precisely what you're reinventing.
> 
> my $uri = URI->new("http://host/base/path")
> $uri->query_form(\%params);
> my $result = $uri->as_string;
> 
> And I'd rely on Gisle Aas's experience about constructing these things
> far more than the thread I've just witnessed here. :)

First, I'd rather not introduce new dependency to git (and I think Junio
would agree). Second, more important, we do _parameters processing_,
it means renaming parameters (e.g. 'file_name' in params is 'p' in CGI URI),
in the future perhaps passing project via PATH_INFO not in query string,
and sorting the CGI parameters.

So it wouldn't be as easy as writing 
        $uri->query_form(\%params); 
        return $uri->as_string;
or as 
        return "$my_uri?" . esc_param(join(";", "$_=$params{$_}") keys %params)'.
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* HELP: GIT Cloning failed
From: Ju, Seokmann @ 2006-08-22 19:25 UTC (permalink / raw)
  To: git; +Cc: Patro, Sumant, linux-kernel

Hi,

Recently, I found that cloning from GIT server has been failed.
I'm using following script for it.
---
...
rm -r /home/git/kernels/2.4/linux-2.4.git
cg-clone
http://www.kernel.org/pub/scm/linux/kernel/git/marcelo/linux-2.4.git/
/home/git/kernels/2.4/linux-2.4.git/
sync
rm -r /home/git/kernels/2.4/linux-2.6.git
cg-clone
http://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/
/home/git/kernels/2.4/linux-2.6.git/
sync
rm -r /home/git/kernels/2.4/scsi-misc-2.6.git
cg-clone
http://www.kernel.org/pub/scm/linux/kernel/git/marcelo/scsi-misc-2.6.git
/home/git/kernels/2.4/scsi-misc-2.6.git
sync
...
---

In the script, I'm cloning 3 different sources. First two sources
getting successfully cloned, however, last one is getting failed with
following error messages,
---
Fetching head...
Fetching objects...
Getting alternates list for
http://www.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
Also look at http://www.kernel.or
Error: The requested URL returned error: 502 (curl_result = 22,
http_code = 502, sha1 = 1039f0760e...)
Getting pack list for
http://www.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git/
Getting pack list for http://www.kernel.or
Error: The requested URL returned error: 502
Error: Unable to find 27fd37621... Under
http://www.kernel.org/pub/scsm/linux/kernel/git/jejb/scsi-misc-2.6.git/
Cannot obtain needed blob 27fd37621...
While processing commit 4041b9cd87...
Progress: 8 objects, 13120 bytes
Cg-fetch: objects fetch failed
---

Above script worked without any problem when I started several months
ago and I'm not sure when did it stop working.
I'm using _cron_ utility on my Linux box for scheduled execution of the
script.

Any comment would be appreciated.

Thank you,

Seokmann

^ permalink raw reply

* Re: [RFD] gitweb: href() function to generate URLs for CGI
From: Randal L. Schwartz @ 2006-08-22 18:35 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jakub Narebski, git
In-Reply-To: <7vodudno88.fsf@assigned-by-dhcp.cox.net>

>>>>> "Junio" == Junio C Hamano <junkio@cox.net> writes:

Junio> 	my @result = (); 
Junio>         for (my $i = 0; $i < @mapping; $i += 2) {
Junio>         	my ($name, $symbol) = ($mapping[$i], $mapping[$i+1]);
Junio> 		if (defined $params{$name}) {
Junio> 			push @result, "$symbol=$params{$name}";
Junio> 		}
Junio> 	}
Junio>         return "$my_uri?" . esc_param(join(';', @result));
Junio> }

If you already depend on the LWP package, then the "URI" module
does precisely what you're reinventing.

my $uri = URI->new("http://host/base/path")
$uri->query_form(\%params);
my $result = $uri->as_string;

And I'd rely on Gisle Aas's experience about constructing these things
far more than the thread I've just witnessed here. :)

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

^ permalink raw reply

* Source highlight in qgit
From: Marco Costalba @ 2006-08-22 17:52 UTC (permalink / raw)
  To: GIT list; +Cc: Lorenzo Bettini

Thanks to the nice and powerful tool  GNU Source-highlight
(http://www.gnu.org/software/src-highlite/) qgit now supports file
viewer with syntax highlight.

Advertising screenshot: http://digilander.libero.it/mcostalba/src_hlt_3.png

I've found GNU Source-highlight quite easy to integrate so I post this
as an info/hint for people that could be interested (read gitweb
team).

A patch as been pushed to git://git.kernel.org/pub/scm/qgit/qgit.git

Thanks
Marco

^ permalink raw reply

* [PATCH] Added support for dropping privileges to git-daemon.
From: Tilman Sauerbeck @ 2006-08-22 17:37 UTC (permalink / raw)
  To: git
In-Reply-To: <7vhd05s2b5.fsf@assigned-by-dhcp.cox.net>

Signed-off-by: Tilman Sauerbeck <tilman@code-monkey.de>
---

 This one got the changes you proposed.

 Not sure whether the documentation is good enough, I'm not that good at
 writing tech docs in english :(


 Documentation/git-daemon.txt |   18 ++++++++++++++++
 daemon.c                     |   46 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index 0f7d274..b591895 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -11,7 +11,8 @@ SYNOPSIS
 'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
              [--timeout=n] [--init-timeout=n] [--strict-paths]
              [--base-path=path] [--user-path | --user-path=path]
-	     [--reuseaddr] [--detach] [--pid-file=file] [directory...]
+	     [--reuseaddr] [--detach] [--pid-file=file]
+	     [--user=user [--group=group]] [directory...]
 
 DESCRIPTION
 -----------
@@ -93,6 +94,21 @@ OPTIONS
 --pid-file=file::
 	Save the process id in 'file'.
 
+--user=user::
+--group=group::
+	These two options may be used to make `git-daemon` change its uid and
+	gid	before entering the server loop.
+	The uid that's used is the one of 'user'. If `group` is specified,
+	the gid is set to the one of 'group', otherwise, the default gid
+	of 'user' is used.
+
+	Both `group` and `user` need to be passed as the name of the resp of
+	the group, ie you'll get unexpected results if you pass an uid/a gid.
+
+	Note that you probably don't want to use these options if you run
+	git-daemon in inetd mode, since inetd can do the privilege dropping
+	for you.
+
 <directory>::
 	A directory to add to the whitelist of allowed directories. Unless
 	--strict-paths is specified this will also include subdirectories
diff --git a/daemon.c b/daemon.c
index 012936f..4e94210 100644
--- a/daemon.c
+++ b/daemon.c
@@ -7,6 +7,8 @@ #include <netdb.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <syslog.h>
+#include <pwd.h>
+#include <grp.h>
 #include "pkt-line.h"
 #include "cache.h"
 #include "exec_cmd.h"
@@ -19,7 +21,8 @@ static const char daemon_usage[] =
 "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
 "           [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
 "           [--base-path=path] [--user-path | --user-path=path]\n"
-"           [--reuseaddr] [--detach] [--pid-file=file] [directory...]";
+"           [--reuseaddr] [--detach] [--pid-file=file]\n"
+"           [--user=user [[--group=group]] [directory...]";
 
 /* List of acceptable pathname prefixes */
 static char **ok_paths;
@@ -701,7 +704,7 @@ static void store_pid(const char *path)
 	fclose(f);
 }
 
-static int serve(int port)
+static int serve(int port, struct passwd *pass, gid_t gid)
 {
 	int socknum, *socklist;
 
@@ -709,6 +712,11 @@ static int serve(int port)
 	if (socknum == 0)
 		die("unable to allocate any listen sockets on port %u", port);
 
+	if (pass && gid &&
+	    (initgroups(pass->pw_name, gid) || setgid (gid) ||
+	     setuid(pass->pw_uid)))
+		die("cannot drop privileges");
+
 	return service_loop(socknum, socklist);
 }
 
@@ -716,8 +724,11 @@ int main(int argc, char **argv)
 {
 	int port = DEFAULT_GIT_PORT;
 	int inetd_mode = 0;
-	const char *pid_file = NULL;
+	const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
 	int detach = 0;
+	struct passwd *pass = NULL;
+	struct group *group;
+	gid_t gid = 0;
 	int i;
 
 	/* Without this we cannot rely on waitpid() to tell
@@ -791,6 +802,14 @@ int main(int argc, char **argv)
 			log_syslog = 1;
 			continue;
 		}
+		if (!strncmp(arg, "--user=", 7)) {
+			user_name = arg + 7;
+			continue;
+		}
+		if (!strncmp(arg, "--group=", 8)) {
+			group_name = arg + 8;
+			continue;
+		}
 		if (!strcmp(arg, "--")) {
 			ok_paths = &argv[i+1];
 			break;
@@ -802,6 +821,25 @@ int main(int argc, char **argv)
 		usage(daemon_usage);
 	}
 
+	if (group_name && !user_name)
+		die("--group supplied without --user");
+
+	if (user_name) {
+		pass = getpwnam(user_name);
+		if (!pass)
+			die("user not found - %s", user_name);
+
+		if (!group_name)
+			gid = pass->pw_gid;
+		else {
+			group = getgrnam(group_name);
+			if (!group)
+				die("group not found - %s", group_name);
+
+			gid = group->gr_gid;
+		}
+	}
+
 	if (log_syslog) {
 		openlog("git-daemon", 0, LOG_DAEMON);
 		set_die_routine(daemon_die);
@@ -831,5 +869,5 @@ int main(int argc, char **argv)
 	if (pid_file)
 		store_pid(pid_file);
 
-	return serve(port);
+	return serve(port, pass, gid);
 }
-- 
1.4.2

^ permalink raw reply related

* Re: stgit: deleting a branch doesn't seem to work
From: Torgil Svensson @ 2006-08-22 17:12 UTC (permalink / raw)
  To: Catalin Marinas, git
In-Reply-To: <tnxd5attbhq.fsf@arm.com>

Which option you choose doesn't really matter to me, I easily deleted
the master-branch (with rm). If you choose to stay with the current
situation the message should be changed to something like "stgit
patches succesfully deleted from branch xxx" and "branch xxx is not
controlled by stgit, nothing is done."

It also would be helpful to new users if "stg refresh -e" is mentioned
in the tutorial. Refresh isn't obvious to test if you want to edit
description.

Otherwise I had no problem in my first stgit experience. I first took
a chance that "stgit import" recognized patches saved by
"format-patch", but this was easily solved with "stg refresh -e" once
I found it (thanks #git).

I've never worked with quilt before so i'm new to this style of
development. My experiece so far is that I find stgit to be very
useful.  Thanks!

//Torgil

On 8/22/06, Catalin Marinas <catalin.marinas@arm.com> wrote:
> "Torgil Svensson" <torgil.svensson@gmail.com> wrote:
> > I have three branches and want my "gst10" to be "master" instead
> >
> > $ stg branch --delete master
> > Deleting branch "master"... done
> > $ stg branch -l
> > Available branches:
> >   s     gst10   |
> >         master  |
> >>       origin  |
> > $ stg branch --delete master
> > Deleting branch "master"... done
> > $ stg branch -r gst10 master
> > stg branch: Branch "master" already exists
> >
> > Is there something i'm missing in my logic?
>
> It's not actually documented but it looks like the master branch is
> not completely deleted by StGIT. If you have StGIT-managed patches in
> "master", they are removed but the GIT branch is kept as this is
> usually the default branch.
>
> You could do a "git branch -d master" but maybe I should change StGIT
> to fully delete the "master" branch as well.
>
> --
> Catalin
>

^ permalink raw reply

* [PATCH 2/2] gitweb: Sort CGI parameters returned by href()
From: Jakub Narebski @ 2006-08-22 17:05 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski, Junio C Hamano
In-Reply-To: <200608211739.32993.jnareb@gmail.com>

Restore pre-1c2a4f5addce479c619057c6cdc841802139982f
ordering of CGI parameters.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 gitweb/gitweb.perl |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 89ef5e7..da0630e 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -260,7 +260,9 @@ ## =====================================
 ## action links
 
 sub href(%) {
-	my %mapping = (
+	my %params = @_;
+
+	my @mapping = (
 		action => "a",
 		project => "p",
 		file_name => "f",
@@ -271,18 +273,18 @@ sub href(%) {
 		page => "pg",
 		searchtext => "s",
 	);
+	my %mapping = @mapping;
 
-	my %params = @_;
 	$params{"project"} ||= $project;
 
-	my $href = "$my_uri?";
-	$href .= esc_param( join(";",
-		map {
-			defined $params{$_} ? "$mapping{$_}=$params{$_}" : ()
-		} keys %params
-	) );
-
-	return $href;
+	my @result = ();
+	for (my $i = 0; $i < @mapping; $i += 2) {
+		my ($name, $symbol) = ($mapping[$i], $mapping[$i+1]);
+		if (defined $params{$name}) {
+			push @result, $symbol . "=" . esc_param($params{$name});
+		}
+	}
+	return "$my_uri?" . join(';', @result);
 }
 
 
-- 
1.4.1.1

^ permalink raw reply related

* [PATCH 1/2] gitweb: Drop the href() params which keys are not in %mapping
From: Jakub Narebski @ 2006-08-22 17:05 UTC (permalink / raw)
  To: git; +Cc: Jakub Narebski, Junio C Hamano
In-Reply-To: <200608211739.32993.jnareb@gmail.com>

If someone would enter parameter name incorrectly, and some key of
%params is not found in %mapping hash, the parameter is now
ignored. Change introduced by Martin Waitz in commit
  756d2f064b2419fcdf9cd9c851f352e2a4f75103
tried to do that, but it left empty value and there was doubled ";;"
in returned string.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 gitweb/gitweb.perl |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 063735d..89ef5e7 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -278,7 +278,7 @@ sub href(%) {
 	my $href = "$my_uri?";
 	$href .= esc_param( join(";",
 		map {
-			"$mapping{$_}=$params{$_}" if defined $params{$_}
+			defined $params{$_} ? "$mapping{$_}=$params{$_}" : ()
 		} keys %params
 	) );
 
-- 
1.4.1.1

^ permalink raw reply related

* [PATCH repost] Multiple refs from the same remote in one git fetch
From: Michael S. Tsirkin @ 2006-08-22 15:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <20060814051302.GB21963@mellanox.co.il>

Hi, Junio!
Is the following likely to get merged eventually?
It was pointed out that I can work-around the limitation
by using softlinks, so it's not a show-stopper for me.

---

Fix git fetch for when multiple refspecs reference the same remote head.

Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>

diff --git a/connect.c b/connect.c
index 4422a0d..3880191 100644
--- a/connect.c
+++ b/connect.c
@@ -115,6 +115,7 @@ int get_ack(int fd, unsigned char *resul
 int path_match(const char *path, int nr, char **match)
 {
 	int i;
+	int found = 0;
 	int pathlen = strlen(path);
 
 	for (i = 0; i < nr; i++) {
@@ -128,9 +129,9 @@ int path_match(const char *path, int nr,
 		if (pathlen > len && path[pathlen - len - 1] != '/')
 			continue;
 		*s = 0;
-		return (i + 1);
+		found = i + 1;
 	}
-	return 0;
+	return found;
 }
 
 struct refspec {
diff --git a/git-fetch.sh b/git-fetch.sh
index c2eebee..328168b 100755
--- a/git-fetch.sh
+++ b/git-fetch.sh
@@ -366,33 +366,44 @@ fetch_main () {
 		  exit 1 ;;
 	  esac
 	  found=
-	  single_force=
+	  found_any=
 	  for ref in $refs
 	  do
 	      case "$ref" in
 	      +$remote_name:*)
 		  single_force=t
 		  not_for_merge=
-		  found="$ref"
-		  break ;;
+		  found="$ref";;
 	      .+$remote_name:*)
 		  single_force=t
 		  not_for_merge=t
-		  found="$ref"
-		  break ;;
+		  found="$ref";;
 	      .$remote_name:*)
+		  single_force=
 		  not_for_merge=t
-		  found="$ref"
-		  break ;;
+		  found="$ref";;
 	      $remote_name:*)
+		  single_force=
+		  not_for_merge=
+		  found="$ref";;
+	      *)
+		  single_force=
 		  not_for_merge=
-		  found="$ref"
-		  break ;;
+		  found=;;
 	      esac
+	      if test "$found" != ""
+	      then
+		  found_any=1
+		  local_name=$(expr "z$found" : 'z[^:]*:\(.*\)')
+		  append_fetch_head "$sha1" "$remote" "$remote_name" \
+		      "$remote_nick" "$local_name" "$not_for_merge"
+	      fi
 	  done
-	  local_name=$(expr "z$found" : 'z[^:]*:\(.*\)')
-	  append_fetch_head "$sha1" "$remote" \
-		  "$remote_name" "$remote_nick" "$local_name" "$not_for_merge"
+	  if test "$found_any" == ""
+	  then
+	      append_fetch_head "$sha1" "$remote" "$remote_name" \
+	          "$remote_nick" "" ""
+	  fi
       done
     ) || exit ;;
   esac

-- 
MST

^ permalink raw reply related

* Re: [PATCH 0/3] gitweb: Yet another cleanup series
From: Jakub Narebski @ 2006-08-22 15:03 UTC (permalink / raw)
  To: git
In-Reply-To: <200608221651.19629.jnareb@gmail.com>

Jakub Narebski wrote:

> This series of patches commences further gitweb cleanup.
> It is based on earlier series of patches:
> * gitweb: Added parse_difftree_raw_line function for later use
> * gitweb: Use parse_difftree_raw_line in git_difftree_body

Actually, I think that only first patch in this series needs
"parse_difftree_raw_line" series.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

^ permalink raw reply

* [PATCH 3/3] gitweb: Route rest of action subroutines through %actions
From: Jakub Narebski @ 2006-08-22 14:59 UTC (permalink / raw)
  To: git
In-Reply-To: <200608221651.19629.jnareb@gmail.com>

Route rest of action subroutines, namely git_project_list and git_opml
(both of which doesn't need $project) through %actions hash.

This has disadvantage that all parameters are read and validated;
earlier git_opml was called as soon as $action was parsed and
validated, git_project_list was called as soon as $project was parsed
and validated.  This has advantage that all action dispatch is grouped
in one place.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This is an alternative to (not accepted) patch by Martin Waitz from
in http://permalink.gmane.org/gmane.comp.version-control.git/25535
Message-Id: <11557673281583-git-send-email-tali@admingilde.org>

  gitweb: use action dispatcher for non-project actions, too.


 gitweb/gitweb.perl |   17 ++++++++---------
 1 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index f59213e..e09204d 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -155,11 +155,6 @@ if (defined $action) {
 	if ($action =~ m/[^0-9a-zA-Z\.\-_]/) {
 		die_error(undef, "Invalid action parameter");
 	}
-	# action which does not check rest of parameters
-	if ($action eq "opml") {
-		git_opml();
-		exit;
-	}
 }
 
 our $project = ($cgi->param('p') || $ENV{'PATH_INFO'});
@@ -179,9 +174,6 @@ if (defined $project) {
 		die_error(undef, "No such project");
 	}
 	$ENV{'GIT_DIR'} = "$projectroot/$project";
-} else {
-	git_project_list();
-	exit;
 }
 
 our $file_name = $cgi->param('f');
@@ -255,9 +247,16 @@ my %actions = (
 	"tags" => \&git_tags,
 	"tree" => \&git_tree,
 	"snapshot" => \&git_snapshot,
+	# those below don't need $project
+	"opml" => \&git_opml,
+	"project_list" => \&git_project_list,
 );
 
-$action = 'summary' if (!defined($action));
+if (defined $project) {
+	$action ||= 'summary';
+} else {
+	$action ||= 'project_list';
+}
 if (!defined($actions{$action})) {
 	die_error(undef, "Unknown action");
 }
-- 
1.4.1.1

^ permalink raw reply related

* [PATCH 0/3] gitweb: Yet another cleanup series
From: Jakub Narebski @ 2006-08-22 14:51 UTC (permalink / raw)
  To: git

This series of patches commences further gitweb cleanup.
It is based on earlier series of patches:
* gitweb: Added parse_difftree_raw_line function for later use
* gitweb: Use parse_difftree_raw_line in git_difftree_body

---
 gitweb/gitweb.perl |  277 +++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 188 insertions(+), 89 deletions(-)

* gitweb: Whitespace cleanup: realign, reindent
* gitweb: Use underscore instead of hyphen to separate words
  in HTTP headers names
* gitweb: Route rest of action subroutines through %actions

-- 
Jakub Narebski
Poland

^ permalink raw reply

* [PATCH 1/3] gitweb: Whitespace cleanup: realign, reindent
From: Jakub Narebski @ 2006-08-22 14:52 UTC (permalink / raw)
  To: git
In-Reply-To: <200608221651.19629.jnareb@gmail.com>

This patch tries (but no too hard) to fit gitweb source in 80 columns,
for 2 columns wide tabs, and indent and align source for better
readibility.

While at it added comment to 'snapshot' entry defaults for %feature
hash, corrected "blobl" action in git_blame2 and git_blame to "blob",
key of argument to $cgi->a from 'class' to '-class'.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
Quite a large patch, but it doesn't change much.

 gitweb/gitweb.perl |  257 ++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 178 insertions(+), 79 deletions(-)

diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 607b8b7..182fe33 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -69,22 +69,30 @@ our $mimetypes_file = undef;
 
 # You define site-wide feature defaults here; override them with
 # $GITWEB_CONFIG as necessary.
-our %feature =
-(
-
-# feature  => {'sub' => feature-sub, 'override' => allow-override, 'default' => [ default options...]
-
-'blame'         => {'sub' => \&feature_blame, 'override' => 0, 'default' => [0]},
-'snapshot'      => {'sub' => \&feature_snapshot, 'override' => 0, 'default' => ['x-gzip', 'gz', 'gzip']},
-
+our %feature = (
+	# feature => {'sub' => feature-sub, 'override' => allow-override, 'default' => [ default options...]
+	# if feature is overridable, feature-sub will be called with default options;
+	# return value indicates if to enable specified feature
+
+	'blame' => {
+		'sub' => \&feature_blame,
+		'override' => 0,
+		'default' => [0]},
+
+	'snapshot' => {
+		'sub' => \&feature_snapshot,
+		'override' => 0,
+		#         => [content-encoding, suffix, program]
+		'default' => ['x-gzip', 'gz', 'gzip']},
 );
 
 sub gitweb_check_feature {
 	my ($name) = @_;
 	return undef unless exists $feature{$name};
-	my ($sub, $override, @defaults) = ($feature{$name}{'sub'},
-						$feature{$name}{'override'},
-						@{$feature{$name}{'default'}});
+	my ($sub, $override, @defaults) = (
+		$feature{$name}{'sub'},
+		$feature{$name}{'override'},
+		@{$feature{$name}{'default'}});
 	if (!$override) { return @defaults; }
 	return $sub->(@defaults);
 }
@@ -463,7 +471,9 @@ sub format_log_line_html {
 	if ($line =~ m/([0-9a-fA-F]{40})/) {
 		my $hash_text = $1;
 		if (git_get_type($hash_text) eq "commit") {
-			my $link = $cgi->a({-class => "text", -href => href(action=>"commit", hash=>$hash_text)}, $hash_text);
+			my $link =
+				$cgi->a({-href => href(action=>"commit", hash=>$hash_text),
+				        -class => "text"}, $hash_text);
 			$line =~ s/$hash_text/$link/;
 		}
 	}
@@ -734,8 +744,10 @@ sub parse_date {
 	$date{'mday'} = $mday;
 	$date{'day'} = $days[$wday];
 	$date{'month'} = $months[$mon];
-	$date{'rfc2822'} = sprintf "%s, %d %s %4d %02d:%02d:%02d +0000", $days[$wday], $mday, $months[$mon], 1900+$year, $hour ,$min, $sec;
-	$date{'mday-time'} = sprintf "%d %s %02d:%02d", $mday, $months[$mon], $hour ,$min;
+	$date{'rfc2822'} = sprintf "%s, %d %s %4d %02d:%02d:%02d +0000",
+	                   $days[$wday], $mday, $months[$mon], 1900+$year, $hour ,$min, $sec;
+	$date{'mday-time'} = sprintf "%d %s %02d:%02d",
+	                     $mday, $months[$mon], $hour ,$min;
 
 	$tz =~ m/^([+\-][0-9][0-9])([0-9][0-9])$/;
 	my $local = $epoch + ((int $1 + ($2/60)) * 3600);
@@ -792,7 +804,8 @@ sub parse_commit {
 		@commit_lines = @$commit_text;
 	} else {
 		$/ = "\0";
-		open my $fd, "-|", $GIT, "rev-list", "--header", "--parents", "--max-count=1", $commit_id or return;
+		open my $fd, "-|", $GIT, "rev-list", "--header", "--parents", "--max-count=1", $commit_id
+			or return;
 		@commit_lines = split '\n', <$fd>;
 		close $fd or return;
 		$/ = "\n";
@@ -1086,12 +1099,15 @@ sub git_header_html {
 	# 'application/xhtml+xml', otherwise send it as plain old 'text/html'.
 	# we have to do this because MSIE sometimes globs '*/*', pretending to
 	# support xhtml+xml but choking when it gets what it asked for.
-	if (defined $cgi->http('HTTP_ACCEPT') && $cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ && $cgi->Accept('application/xhtml+xml') != 0) {
+	if (defined $cgi->http('HTTP_ACCEPT') &&
+	    $cgi->http('HTTP_ACCEPT') =~ m/(,|;|\s|^)application\/xhtml\+xml(,|;|\s|$)/ &&
+	    $cgi->Accept('application/xhtml+xml') != 0) {
 		$content_type = 'application/xhtml+xml';
 	} else {
 		$content_type = 'text/html';
 	}
-	print $cgi->header(-type=>$content_type, -charset => 'utf-8', -status=> $status, -expires => $expires);
+	print $cgi->header(-type=>$content_type, -charset => 'utf-8',
+	                   -status=> $status, -expires => $expires);
 	print <<EOF;
 <?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
@@ -1271,9 +1287,12 @@ sub git_print_page_path {
 	} elsif (defined $type && $type eq 'blob') {
 		print "<div class=\"page_path\">";
 		if (defined $hb) {
-			print $cgi->a({-href => href(action=>"blob_plain", hash_base=>$hb, file_name=>$file_name)}, esc_html($name));
+			print $cgi->a({-href => href(action=>"blob_plain", file_name=>$file_name,
+			                             hash_base=>$hb)},
+			              esc_html($name));
 		} else {
-			print $cgi->a({-href => href(action=>"blob_plain", file_name=>$file_name)}, esc_html($name));
+			print $cgi->a({-href => href(action=>"blob_plain", file_name=>$file_name)},
+			              esc_html($name));
 		}
 		print "<br/></div>\n";
 	} else {
@@ -1523,7 +1542,8 @@ sub git_shortlog_body {
 		print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
 		      "<td><i>" . esc_html(chop_str($co{'author_name'}, 10)) . "</i></td>\n" .
 		      "<td>";
-		print format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref);
+		print format_subject_html($co{'title'}, $co{'title_short'},
+		                          href(action=>"commit", hash=>$commit), $ref);
 		print "</td>\n" .
 		      "<td class=\"link\">" .
 		      $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " .
@@ -1576,7 +1596,8 @@ sub git_history_body {
 		      "<td><i>" . esc_html(chop_str($co{'author_name'}, 15, 3)) . "</i></td>\n" .
 		      "<td>";
 		# originally git_history used chop_str($co{'title'}, 50)
-		print format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref);
+		print format_subject_html($co{'title'}, $co{'title_short'},
+		                          href(action=>"commit", hash=>$commit), $ref);
 		print "</td>\n" .
 		      "<td class=\"link\">" .
 		      $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") . " | " .
@@ -1589,7 +1610,8 @@ sub git_history_body {
 			if (defined $blob_current && defined $blob_parent &&
 					$blob_current ne $blob_parent) {
 				print " | " .
-					$cgi->a({-href => href(action=>"blobdiff", hash=>$blob_current, hash_parent=>$blob_parent, hash_base=>$commit, file_name=>$file_name)},
+					$cgi->a({-href => href(action=>"blobdiff", hash=>$blob_current, hash_parent=>$blob_parent,
+					                       hash_base=>$commit, file_name=>$file_name)},
 					        "diff to current");
 			}
 		}
@@ -1634,7 +1656,8 @@ sub git_tags_body {
 		      "</td>\n" .
 		      "<td>";
 		if (defined $comment) {
-			print format_subject_html($comment, $comment_short, href(action=>"tag", hash=>$tag{'id'}));
+			print format_subject_html($comment, $comment_short,
+			                          href(action=>"tag", hash=>$tag{'id'}));
 		}
 		print "</td>\n" .
 		      "<td class=\"selflink\">";
@@ -1945,13 +1968,17 @@ sub git_tag {
 	      "<table cellspacing=\"0\">\n" .
 	      "<tr>\n" .
 	      "<td>object</td>\n" .
-	      "<td>" . $cgi->a({-class => "list", -href => href(action=>$tag{'type'}, hash=>$tag{'object'})}, $tag{'object'}) . "</td>\n" .
-	      "<td class=\"link\">" . $cgi->a({-href => href(action=>$tag{'type'}, hash=>$tag{'object'})}, $tag{'type'}) . "</td>\n" .
+	      "<td>" . $cgi->a({-class => "list", -href => href(action=>$tag{'type'}, hash=>$tag{'object'})},
+	                       $tag{'object'}) . "</td>\n" .
+	      "<td class=\"link\">" . $cgi->a({-href => href(action=>$tag{'type'}, hash=>$tag{'object'})},
+	                                      $tag{'type'}) . "</td>\n" .
 	      "</tr>\n";
 	if (defined($tag{'author'})) {
 		my %ad = parse_date($tag{'epoch'}, $tag{'tz'});
 		print "<tr><td>author</td><td>" . esc_html($tag{'author'}) . "</td></tr>\n";
-		print "<tr><td></td><td>" . $ad{'rfc2822'} . sprintf(" (%02d:%02d %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}) . "</td></tr>\n";
+		print "<tr><td></td><td>" . $ad{'rfc2822'} .
+			sprintf(" (%02d:%02d %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}) .
+			"</td></tr>\n";
 	}
 	print "</table>\n\n" .
 	      "</div>\n";
@@ -1988,8 +2015,11 @@ sub git_blame2 {
 		or die_error(undef, "Open git-blame failed");
 	git_header_html();
 	my $formats_nav =
-		$cgi->a({-href => href(action=>"blobl", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, "blob") .
-		" | " . $cgi->a({-href => href(action=>"blame", file_name=>$file_name)}, "head");
+		$cgi->a({-href => href(action=>"blob", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)},
+		        "blob") .
+		" | " .
+		$cgi->a({-href => href(action=>"blame", file_name=>$file_name)},
+		        "head");
 	git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
 	git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
 	git_print_page_path($file_name, $ftype, $hash_base);
@@ -2015,14 +2045,17 @@ sub git_blame2 {
 		}
 		print "<tr class=\"$rev_color[$current_color]\">\n";
 		print "<td class=\"sha1\">" .
-			$cgi->a({-href => href(action=>"commit", hash=>$full_rev, file_name=>$file_name)}, esc_html($rev)) . "</td>\n";
-		print "<td class=\"linenr\"><a id=\"l$lineno\" href=\"#l$lineno\" class=\"linenr\">" . esc_html($lineno) . "</a></td>\n";
+			$cgi->a({-href => href(action=>"commit", hash=>$full_rev, file_name=>$file_name)},
+			        esc_html($rev)) . "</td>\n";
+		print "<td class=\"linenr\"><a id=\"l$lineno\" href=\"#l$lineno\" class=\"linenr\">" .
+		      esc_html($lineno) . "</a></td>\n";
 		print "<td class=\"pre\">" . esc_html($data) . "</td>\n";
 		print "</tr>\n";
 	}
 	print "</table>\n";
 	print "</div>";
-	close $fd or print "Reading blob failed\n";
+	close $fd
+		or print "Reading blob failed\n";
 	git_footer_html();
 }
 
@@ -2045,8 +2078,11 @@ sub git_blame {
 		or die_error(undef, "Open git-annotate failed");
 	git_header_html();
 	my $formats_nav =
-		$cgi->a({-href => href(action=>"blobl", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, "blob") .
-		" | " . $cgi->a({-href => href(action=>"blame", file_name=>$file_name)}, "head");
+		$cgi->a({-href => href(action=>"blob", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)},
+		        "blob") .
+		" | " .
+		$cgi->a({-href => href(action=>"blame", file_name=>$file_name)},
+		        "head");
 	git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
 	git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
 	git_print_page_path($file_name, 'blob', $hash_base);
@@ -2110,7 +2146,8 @@ HTML
 HTML
 	} # while (my $line = <$fd>)
 	print "</table>\n\n";
-	close $fd or print "Reading blob failed.\n";
+	close $fd 
+		or print "Reading blob failed.\n";
 	print "</div>";
 	git_footer_html();
 }
@@ -2197,13 +2234,23 @@ sub git_blob {
 	if (defined $hash_base && (my %co = parse_commit($hash_base))) {
 		if (defined $file_name) {
 			if ($have_blame) {
-				$formats_nav .= $cgi->a({-href => href(action=>"blame", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, "blame") . " | ";
+				$formats_nav .=
+					$cgi->a({-href => href(action=>"blame", hash_base=>$hash_base,
+					                       hash=>$hash, file_name=>$file_name)},
+					        "blame") .
+					" | ";
 			}
 			$formats_nav .=
-				$cgi->a({-href => href(action=>"blob_plain", hash=>$hash, file_name=>$file_name)}, "plain") .
-				" | " . $cgi->a({-href => href(action=>"blob", hash_base=>"HEAD", file_name=>$file_name)}, "head");
+				$cgi->a({-href => href(action=>"blob_plain",
+				                       hash=>$hash, file_name=>$file_name)},
+				        "plain") .
+				" | " .
+				$cgi->a({-href => href(action=>"blob",
+				                       hash_base=>"HEAD", file_name=>$file_name)},
+				        "head");
 		} else {
-			$formats_nav .= $cgi->a({-href => href(action=>"blob_plain", hash=>$hash)}, "plain");
+			$formats_nav .=
+				$cgi->a({-href => href(action=>"blob_plain", hash=>$hash)}, "plain");
 		}
 		git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
 		git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
@@ -2219,9 +2266,11 @@ sub git_blob {
 		chomp $line;
 		$nr++;
 		$line = untabify($line);
-		printf "<div class=\"pre\"><a id=\"l%i\" href=\"#l%i\" class=\"linenr\">%4i</a> %s</div>\n", $nr, $nr, $nr, esc_html($line);
+		printf "<div class=\"pre\"><a id=\"l%i\" href=\"#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
+		       $nr, $nr, $nr, esc_html($line);
 	}
-	close $fd or print "Reading blob failed.\n";
+	close $fd 
+		or print "Reading blob failed.\n";
 	print "</div>";
 	git_footer_html();
 }
@@ -2282,23 +2331,37 @@ sub git_tree {
 		print "<td class=\"mode\">" . mode_str($t_mode) . "</td>\n";
 		if ($t_type eq "blob") {
 			print "<td class=\"list\">" .
-			      $cgi->a({-href => href(action=>"blob", hash=>$t_hash, file_name=>"$base$t_name", %base_key), -class => "list"}, esc_html($t_name)) .
+			      $cgi->a({-href => href(action=>"blob", hash=>$t_hash, file_name=>"$base$t_name", %base_key),
+			              -class => "list"}, esc_html($t_name)) .
 			      "</td>\n" .
 			      "<td class=\"link\">" .
-			      $cgi->a({-href => href(action=>"blob", hash=>$t_hash, file_name=>"$base$t_name", %base_key)}, "blob");
+			      $cgi->a({-href => href(action=>"blob", hash=>$t_hash, file_name=>"$base$t_name", %base_key)},
+			              "blob");
 			if ($have_blame) {
-				print " | " . $cgi->a({-href => href(action=>"blame", hash=>$t_hash, file_name=>"$base$t_name", %base_key)}, "blame");
+				print " | " .
+					$cgi->a({-href => href(action=>"blame", hash=>$t_hash, file_name=>"$base$t_name", %base_key)},
+					        "blame");
 			}
-			print " | " . $cgi->a({-href => href(action=>"history", hash=>$t_hash, hash_base=>$hash_base, file_name=>"$base$t_name")}, "history") .
-			      " | " . $cgi->a({-href => href(action=>"blob_plain", hash=>$t_hash, file_name=>"$base$t_name")}, "raw") .
+			print " | " .
+			      $cgi->a({-href => href(action=>"history", hash_base=>$hash_base,
+			                             hash=>$t_hash, file_name=>"$base$t_name")},
+			              "history") .
+			      " | " .
+			      $cgi->a({-href => href(action=>"blob_plain",
+			                             hash=>$t_hash, file_name=>"$base$t_name")},
+			              "raw") .
 			      "</td>\n";
 		} elsif ($t_type eq "tree") {
 			print "<td class=\"list\">" .
-			      $cgi->a({-href => href(action=>"tree", hash=>$t_hash, file_name=>"$base$t_name", %base_key)}, esc_html($t_name)) .
+			      $cgi->a({-href => href(action=>"tree", hash=>$t_hash, file_name=>"$base$t_name", %base_key)},
+			              esc_html($t_name)) .
 			      "</td>\n" .
 			      "<td class=\"link\">" .
-			      $cgi->a({-href => href(action=>"tree", hash=>$t_hash, file_name=>"$base$t_name", %base_key)}, "tree") .
-			      " | " . $cgi->a({-href => href(action=>"history", hash_base=>$hash_base, file_name=>"$base$t_name")}, "history") .
+			      $cgi->a({-href => href(action=>"tree", hash=>$t_hash, file_name=>"$base$t_name", %base_key)},
+			              "tree") .
+			      " | " .
+			      $cgi->a({-href => href(action=>"history", hash_base=>$hash_base, file_name=>"$base$t_name")},
+			              "history") .
 			      "</td>\n";
 		}
 		print "</tr>\n";
@@ -2323,10 +2386,9 @@ sub git_snapshot {
 	my $filename = basename($project) . "-$hash.tar.$suffix";
 
 	print $cgi->header(-type => 'application/x-tar',
-			   -content-encoding => $ctype,
-			   '-content-disposition' =>
-			   "inline; filename=\"$filename\"",
-			   -status => '200 OK');
+	                   -content-encoding => $ctype,
+	                  '-content-disposition' => "inline; filename=\"$filename\"",
+	                   -status => '200 OK');
 
 	open my $fd, "-|", "$GIT tar-tree $hash \'$project\' | $command" or
 		die_error(undef, "Execute git-tar-tree failed.");
@@ -2377,7 +2439,8 @@ sub git_log {
 		print "<div class=\"title_text\">\n" .
 		      "<div class=\"log_link\">\n" .
 		      $cgi->a({-href => href(action=>"commit", hash=>$commit)}, "commit") .
-		      " | " . $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") .
+		      " | " .
+		      $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff") .
 		      "<br/>\n" .
 		      "</div>\n" .
 		      "<i>" . esc_html($co{'author_name'}) .  " [$ad{'rfc2822'}]</i><br/>\n" .
@@ -2421,12 +2484,14 @@ sub git_commit {
 	my $formats_nav = '';
 	if (defined $file_name && defined $co{'parent'}) {
 		my $parent = $co{'parent'};
-		$formats_nav .= $cgi->a({-href => href(action=>"blame", hash_parent=>$parent, file_name=>$file_name)}, "blame");
+		$formats_nav .=
+			$cgi->a({-href => href(action=>"blame", hash_parent=>$parent, file_name=>$file_name)},
+			        "blame");
 	}
 	git_header_html(undef, $expires);
 	git_print_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff',
-	             $hash, $co{'tree'}, $hash,
-	             $formats_nav);
+	                   $hash, $co{'tree'}, $hash,
+	                   $formats_nav);
 
 	if (defined $co{'parent'}) {
 		git_print_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash);
@@ -2439,23 +2504,31 @@ sub git_commit {
 	      "<tr>" .
 	      "<td></td><td> $ad{'rfc2822'}";
 	if ($ad{'hour_local'} < 6) {
-		printf(" (<span class=\"atnight\">%02d:%02d</span> %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'});
+		printf(" (<span class=\"atnight\">%02d:%02d</span> %s)",
+		       $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'});
 	} else {
-		printf(" (%02d:%02d %s)", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'});
+		printf(" (%02d:%02d %s)",
+		       $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'});
 	}
 	print "</td>" .
 	      "</tr>\n";
 	print "<tr><td>committer</td><td>" . esc_html($co{'committer'}) . "</td></tr>\n";
-	print "<tr><td></td><td> $cd{'rfc2822'}" . sprintf(" (%02d:%02d %s)", $cd{'hour_local'}, $cd{'minute_local'}, $cd{'tz_local'}) . "</td></tr>\n";
+	print "<tr><td></td><td> $cd{'rfc2822'}" .
+	      sprintf(" (%02d:%02d %s)", $cd{'hour_local'}, $cd{'minute_local'}, $cd{'tz_local'}) .
+	      "</td></tr>\n";
 	print "<tr><td>commit</td><td class=\"sha1\">$co{'id'}</td></tr>\n";
 	print "<tr>" .
 	      "<td>tree</td>" .
 	      "<td class=\"sha1\">" .
-	      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash), class => "list"}, $co{'tree'}) .
+	      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash),
+	               class => "list"}, $co{'tree'}) .
 	      "</td>" .
-	      "<td class=\"link\">" . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash)}, "tree");
+	      "<td class=\"link\">" .
+	      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$hash)},
+	              "tree");
 	if ($have_snapshot) {
-		print " | " .  $cgi->a({-href => href(action=>"snapshot", hash=>$hash)}, "snapshot");
+		print " | " .
+		      $cgi->a({-href => href(action=>"snapshot", hash=>$hash)}, "snapshot");
 	}
 	print "</td>" .
 	      "</tr>\n";
@@ -2463,10 +2536,14 @@ sub git_commit {
 	foreach my $par (@$parents) {
 		print "<tr>" .
 		      "<td>parent</td>" .
-		      "<td class=\"sha1\">" . $cgi->a({-href => href(action=>"commit", hash=>$par), class => "list"}, $par) . "</td>" .
+		      "<td class=\"sha1\">" .
+		      $cgi->a({-href => href(action=>"commit", hash=>$par),
+		               class => "list"}, $par) .
+		      "</td>" .
 		      "<td class=\"link\">" .
 		      $cgi->a({-href => href(action=>"commit", hash=>$par)}, "commit") .
-		      " | " . $cgi->a({-href => href(action=>"commitdiff", hash=>$hash, hash_parent=>$par)}, "commitdiff") .
+		      " | " .
+		      $cgi->a({-href => href(action=>"commitdiff", hash=>$hash, hash_parent=>$par)}, "commitdiff") .
 		      "</td>" .
 		      "</tr>\n";
 	}
@@ -2487,7 +2564,9 @@ sub git_blobdiff {
 	git_header_html();
 	if (defined $hash_base && (my %co = parse_commit($hash_base))) {
 		my $formats_nav =
-			$cgi->a({-href => href(action=>"blobdiff_plain", hash=>$hash, hash_parent=>$hash_parent)}, "plain");
+			$cgi->a({-href => href(action=>"blobdiff_plain",
+			                       hash=>$hash, hash_parent=>$hash_parent)},
+			        "plain");
 		git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);
 		git_print_header_div('commit', esc_html($co{'title'}), $hash_base);
 	} else {
@@ -2498,12 +2577,16 @@ sub git_blobdiff {
 	git_print_page_path($file_name, "blob", $hash_base);
 	print "<div class=\"page_body\">\n" .
 	      "<div class=\"diff_info\">blob:" .
-	      $cgi->a({-href => href(action=>"blob", hash=>$hash_parent, hash_base=>$hash_base, file_name=>($file_parent || $file_name))}, $hash_parent) .
+	      $cgi->a({-href => href(action=>"blob", hash=>$hash_parent,
+	                             hash_base=>$hash_base, file_name=>($file_parent || $file_name))},
+	              $hash_parent) .
 	      " -> blob:" .
-	      $cgi->a({-href => href(action=>"blob", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, $hash) .
+	      $cgi->a({-href => href(action=>"blob", hash=>$hash,
+	                             hash_base=>$hash_base, file_name=>$file_name)},
+	              $hash) .
 	      "</div>\n";
 	git_diff_print($hash_parent, $file_name || $hash_parent, $hash, $file_name || $hash);
-	print "</div>";
+	print "</div>"; # page_body
 	git_footer_html();
 }
 
@@ -2535,7 +2618,8 @@ sub git_commitdiff {
 	my $refs = git_get_references();
 	my $ref = format_ref_marker($refs, $co{'id'});
 	my $formats_nav =
-		$cgi->a({-href => href(action=>"commitdiff_plain", hash=>$hash, hash_parent=>$hash_parent)}, "plain");
+		$cgi->a({-href => href(action=>"commitdiff_plain", hash=>$hash, hash_parent=>$hash_parent)},
+		        "plain");
 	git_header_html(undef, $expires);
 	git_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);
 	git_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash);
@@ -2556,22 +2640,30 @@ sub git_commitdiff {
 		my $file = validate_input(unquote($6));
 		if ($status eq "A") {
 			print "<div class=\"diff_info\">" . file_type($to_mode) . ":" .
-			      $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$file)}, $to_id) . "(new)" .
+			      $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
+			                             hash=>$to_id, file_name=>$file)},
+			              $to_id) . "(new)" .
 			      "</div>\n";
 			git_diff_print(undef, "/dev/null", $to_id, "b/$file");
 		} elsif ($status eq "D") {
 			print "<div class=\"diff_info\">" . file_type($from_mode) . ":" .
-			      $cgi->a({-href => href(action=>"blob", hash=>$from_id, hash_base=>$hash_parent, file_name=>$file)}, $from_id) . "(deleted)" .
+			      $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
+			                             hash=>$from_id, file_name=>$file)},
+			              $from_id) . "(deleted)" .
 			      "</div>\n";
 			git_diff_print($from_id, "a/$file", undef, "/dev/null");
 		} elsif ($status eq "M") {
 			if ($from_id ne $to_id) {
 				print "<div class=\"diff_info\">" .
 				      file_type($from_mode) . ":" .
-				      $cgi->a({-href => href(action=>"blob", hash=>$from_id, hash_base=>$hash_parent, file_name=>$file)}, $from_id) .
+				      $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
+				                             hash=>$from_id, file_name=>$file)},
+				              $from_id) .
 				      " -> " .
 				      file_type($to_mode) . ":" .
-				      $cgi->a({-href => href(action=>"blob", hash=>$to_id, hash_base=>$hash, file_name=>$file)}, $to_id);
+				      $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
+				                             hash=>$to_id, file_name=>$file)},
+				              $to_id);
 				print "</div>\n";
 				git_diff_print($from_id, "a/$file",  $to_id, "b/$file");
 			}
@@ -2611,7 +2703,9 @@ sub git_commitdiff_plain {
 		}
 	}
 
-	print $cgi->header(-type => "text/plain", -charset => 'utf-8', '-content-disposition' => "inline; filename=\"git-$hash.patch\"");
+	print $cgi->header(-type => "text/plain",
+	                   -charset => 'utf-8',
+	                  '-content-disposition' => "inline; filename=\"git-$hash.patch\"");
 	my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});
 	my $comment = $co{'comment'};
 	print "From: $co{'author'}\n" .
@@ -2791,7 +2885,8 @@ sub git_search {
 			print "</td>\n" .
 			      "<td class=\"link\">" .
 			      $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") .
-			      " | " . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree");
+			      " | " .
+			      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree");
 			print "</td>\n" .
 			      "</tr>\n";
 		}
@@ -2828,18 +2923,22 @@ sub git_search {
 					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, 5)) . "</i></td>\n" .
 					      "<td>" .
-					      $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}), -class => "list subject"},
+					      $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}),
+					              -class => "list subject"},
 					              esc_html(chop_str($co{'title'}, 50)) . "<br/>");
 					while (my $setref = shift @files) {
 						my %set = %$setref;
-						print $cgi->a({-href => href(action=>"blob", hash=>$set{'id'}, hash_base=>$co{'id'}, file_name=>$set{'file'}), class => "list"},
-						      "<span class=\"match\">" . esc_html($set{'file'}) . "</span>") .
+						print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'},
+						                             hash=>$set{'id'}, file_name=>$set{'file'}),
+						              -class => "list"},
+						              "<span class=\"match\">" . esc_html($set{'file'}) . "</span>") .
 						      "<br/>\n";
 					}
 					print "</td>\n" .
 					      "<td class=\"link\">" .
 					      $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") .
-					      " | " . $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree");
+					      " | " .
+					      $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree");
 					print "</td>\n" .
 					      "</tr>\n";
 				}
-- 
1.4.1.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox