apply changes and add README master
authorgit <redacted>
Mon, 13 Jul 2026 11:22:23 +0000 (07:22 -0400)
committergit <redacted>
Mon, 13 Jul 2026 11:22:23 +0000 (07:22 -0400)
README.md [new file with mode: 0644]
gitweb.perl

diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..4e96e08
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+## Changes: 
+* switched to `text/html` as the only content type, local XML `nbsp` and `sdot` definitions used to break quite often with caching enabled
+* stopped revealing the git version
+* fixed "Reading blob failed" error false positives
+* made file sizes be displayed in a human-readable format
+* added ZSTD-compressed tarball snapshot support
+* added snapshot links to the project index (requires at least two snapshot formats enabled)
+* added support for URIs with no ".git" in the project name
index fde804593b6ff388774754a24fe1e12d678dc9a4..118d1d7e949c216c598c22fd21cb815858c13ad1 100644 (file)
@@ -35,7 +35,7 @@ BEGIN {
        CGI->compile() if $ENV{'MOD_PERL'};
 }
 
-our $version = "@GIT_VERSION@";
+our $version = "x.x.x";
 
 our ($my_url, $my_uri, $base_url, $path_info, $home_link);
 sub evaluate_uri {
@@ -235,6 +235,14 @@ our %known_snapshot_formats = (
                'compressor' => ['xz'],
                'disabled' => 1},
 
+       'tzs' => {
+               'display' => 'tar.zst',
+               'type' => 'application/x-zstd',
+               'suffix' => '.tar.zst',
+               'format' => 'tar',
+               'compressor' => ['zstd'],
+               'disabled' => 1},
+
        'zip' => {
                'display' => 'zip',
                'type' => 'application/x-zip',
@@ -248,6 +256,7 @@ our %known_snapshot_format_aliases = (
        'gzip'  => 'tgz',
        'bzip2' => 'tbz2',
        'xz'    => 'txz',
+       'zst'   => 'tzs',
 
        # backward compatibility: legacy gitweb config support
        'x-gzip' => undef, 'gz' => undef,
@@ -580,6 +589,28 @@ our %feature = (
                'default' => [0]},
 );
 
+sub human_readable_bytes {
+       my $bytes = shift;
+       if ($bytes eq "-") {
+               return $bytes;
+       }
+
+       my @units = ('', 'K', 'M', 'G', 'T', 'P');
+       my $i = 0;
+
+       while ($bytes >= 1024 && $i < $#units) {
+               $bytes /= 1024;
+               $i++;
+       }
+       if ($i == 0) {
+               return sprintf("%d", $bytes);
+       } elsif ($bytes < 10) {
+               return sprintf("%.1f%s", $bytes, $units[$i]);
+       } else {
+               return sprintf("%d%s", $bytes, $units[$i])
+       }
+}
+
 sub gitweb_get_feature {
        my ($name) = @_;
        return unless exists $feature{$name};
@@ -784,11 +815,7 @@ sub get_loadavg {
 }
 
 # version of the core git binary
-our $git_version;
-sub evaluate_git_version {
-       our $git_version = qx("$GIT" --version) =~ m/git version (.*)$/ ? $1 : "unknown";
-       $number_of_git_cmds++;
-}
+our $git_version="x.x.x";
 
 sub check_loadavg {
        if (defined $maxload && get_loadavg() > $maxload) {
@@ -938,7 +965,12 @@ sub evaluate_path_info {
        # find which part of PATH_INFO is project
        my $project = $path_info;
        $project =~ s,/+$,,;
-       while ($project && !check_head_link("$projectroot/$project")) {
+       while ($project) {
+               if (check_head_link("$projectroot/$project.git")) {
+                       last;
+               } elsif (check_head_link("$projectroot/$project")) {
+                       last;
+               }
                $project =~ s,/*[^/]*$,,;
        }
        return unless $project;
@@ -1093,6 +1125,9 @@ sub evaluate_and_validate_params {
        # parameters which are pathnames
        our $project = $input_params{'project'};
        if (defined $project) {
+               if ($project !~ /\.git$/) {
+                       $project .= ".git";
+               }
                if (!is_valid_project($project)) {
                        undef $project;
                        die_error(404, "No such project");
@@ -1274,7 +1309,6 @@ sub run_request {
        evaluate_uri();
        if ($first_request) {
                evaluate_gitweb_config();
-               evaluate_git_version();
        }
        if ($per_request_config) {
                if (ref($per_request_config) eq 'CODE') {
@@ -1427,6 +1461,7 @@ sub href {
 
                # Then add the project name, if present
                $href .= "/".esc_path_info($params{'project'});
+               $href =~ s/\.git$//g;
                delete $params{'project'};
 
                # since we destructively absorb parameters, we keep this
@@ -3702,7 +3737,7 @@ sub parse_ls_tree_line {
                $res{'mode'} = $1;
                $res{'type'} = $2;
                $res{'hash'} = $3;
-               $res{'size'} = $4;
+               $res{'size'} = human_readable_bytes($4);
                if ($opts{'-z'}) {
                        $res{'name'} = $5;
                } else {
@@ -4034,20 +4069,6 @@ sub get_page_title {
        return $title;
 }
 
-sub get_content_type_html {
-       # require explicit support from the UA if we are to send the page as
-       # '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) {
-               return 'application/xhtml+xml';
-       } else {
-               return 'text/html';
-       }
-}
-
 sub print_feed_meta {
        if (defined $project) {
                my %href_params = get_feed_info();
@@ -4198,20 +4219,16 @@ sub git_header_html {
        my %opts = @_;
 
        my $title = get_page_title();
-       print $cgi->header(-type=>get_content_type_html(), -charset => 'utf-8',
+       print $cgi->header(-type=> 'text/html', -charset => 'utf-8',
                           -status=> $status, -expires => $expires)
                unless ($opts{'-no_http_header'});
        my $mod_perl_version = $ENV{'MOD_PERL'} ? " $ENV{'MOD_PERL'}" : '';
        print <<EOF;
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html [
-       <!ENTITY nbsp "&#xA0;">
-       <!ENTITY sdot "&#x22C5;">
-]>
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
+<!DOCTYPE html>
 <!-- git web interface version $version, (C) 2005-2006, Kay Sievers <kay.sievers\@vrfy.org>, Christian Gierke -->
 <!-- git core binaries version $git_version -->
 <head>
+<meta charset="UTF-8">
 <meta name="generator" content="gitweb/$version git/$git_version$mod_perl_version"/>
 <meta name="robots" content="index, nofollow"/>
 <meta name="viewport" content="width=device-width, initial-scale=1"/>
@@ -5778,8 +5795,8 @@ sub git_project_list_rows {
                        print "</td>\n";
                }
                print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
-                                       -class => "list"},
-                                      esc_html_match_hl($pr->{'path'}, $search_regexp)) .
+                                       -class => "list"},
+                                      esc_html_match_hl($pr->{'path'} =~ s/\.git$//r, $search_regexp)) .
                      "</td>\n" .
                      "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"),
                                        -class => "list",
@@ -5802,6 +5819,16 @@ sub git_project_list_rows {
                      $cgi->a({-href => href(project=>$pr->{'path'}, action=>"log")}, "log") . " | " .
                      $cgi->a({-href => href(project=>$pr->{'path'}, action=>"tree")}, "tree") .
                      ($pr->{'forks'} ? " | " . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "forks") : '') .
+                     " | " . "snapshot (" . join(' ', map
+                       $cgi->a({
+                               -href => href(
+                                       project=>$pr->{'path'},
+                                       action=>"snapshot",
+                                       hash=>"HEAD",
+                                       snapshot_format=>$_
+                               )
+                       }, $known_snapshot_formats{$_}{'display'})
+               , @snapshot_fmts) . ")" .
                      "</td>\n" .
                      "</tr>\n";
        }
@@ -7191,8 +7218,9 @@ sub git_blob {
                               $highlight ? sanitize($line) : esc_html($line, -nbsp=>1);
                }
        }
-       close $fd
-               or print "Reading blob failed.\n";
+       if (!close($fd) && ($? >> 8 != 141)) {
+               print "Reading blob failed\n";
+       }
        print "</div>";
        git_footer_html();
 }