aboutsummaryrefslogtreecommitdiff
path: root/gitweb
diff options
context:
space:
mode:
Diffstat (limited to 'gitweb')
-rw-r--r--gitweb/Makefile129
-rw-r--r--gitweb/README74
-rw-r--r--gitweb/gitweb.js7
-rwxr-xr-xgitweb/gitweb.perl113
4 files changed, 293 insertions, 30 deletions
diff --git a/gitweb/Makefile b/gitweb/Makefile
new file mode 100644
index 000000000..c9eb1ee66
--- /dev/null
+++ b/gitweb/Makefile
@@ -0,0 +1,129 @@
+# The default target of this Makefile is...
+all::
+
+# Define V=1 to have a more verbose compile.
+#
+# Define JSMIN to point to JavaScript minifier that functions as
+# a filter to have gitweb.js minified.
+#
+
+prefix ?= $(HOME)
+bindir ?= $(prefix)/bin
+RM ?= rm -f
+
+# JavaScript minifier invocation that can function as filter
+JSMIN ?=
+
+# default configuration for gitweb
+GITWEB_CONFIG = gitweb_config.perl
+GITWEB_CONFIG_SYSTEM = /etc/gitweb.conf
+GITWEB_HOME_LINK_STR = projects
+GITWEB_SITENAME =
+GITWEB_PROJECTROOT = /pub/git
+GITWEB_PROJECT_MAXDEPTH = 2007
+GITWEB_EXPORT_OK =
+GITWEB_STRICT_EXPORT =
+GITWEB_BASE_URL =
+GITWEB_LIST =
+GITWEB_HOMETEXT = indextext.html
+GITWEB_CSS = gitweb.css
+GITWEB_LOGO = git-logo.png
+GITWEB_FAVICON = git-favicon.png
+ifdef JSMIN
+GITWEB_JS = gitweb.min.js
+else
+GITWEB_JS = gitweb.js
+endif
+GITWEB_SITE_HEADER =
+GITWEB_SITE_FOOTER =
+
+# include user config
+-include ../config.mak.autogen
+-include ../config.mak
+
+# determine version
+../GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
+ $(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) GIT-VERSION-FILE
+
+-include ../GIT-VERSION-FILE
+
+### Build rules
+
+SHELL_PATH ?= $(SHELL)
+PERL_PATH ?= /usr/bin/perl
+
+# Shell quote;
+bindir_SQ = $(subst ','\'',$(bindir)) #'
+SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) #'
+PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) #'
+
+# Quiet generation (unless V=1)
+QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
+QUIET_SUBDIR1 =
+
+ifneq ($(findstring $(MAKEFLAGS),w),w)
+PRINT_DIR = --no-print-directory
+else # "make -w"
+NO_SUBDIR = :
+endif
+
+ifneq ($(findstring $(MAKEFLAGS),s),s)
+ifndef V
+ QUIET = @
+ QUIET_GEN = $(QUIET)echo ' ' GEN $@;
+ QUIET_SUBDIR0 = +@subdir=
+ QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
+ $(MAKE) $(PRINT_DIR) -C $$subdir
+ export V
+ export QUIET
+ export QUIET_GEN
+ export QUIET_SUBDIR0
+ export QUIET_SUBDIR1
+endif
+endif
+
+all:: gitweb.cgi
+
+ifdef JSMIN
+FILES=gitweb.cgi gitweb.min.js
+gitweb.cgi: gitweb.perl gitweb.min.js
+else # !JSMIN
+FILES=gitweb.cgi
+gitweb.cgi: gitweb.perl
+endif # JSMIN
+
+gitweb.cgi:
+ $(QUIET_GEN)$(RM) $@ $@+ && \
+ sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
+ -e 's|++GIT_VERSION++|$(GIT_VERSION)|g' \
+ -e 's|++GIT_BINDIR++|$(bindir)|g' \
+ -e 's|++GITWEB_CONFIG++|$(GITWEB_CONFIG)|g' \
+ -e 's|++GITWEB_CONFIG_SYSTEM++|$(GITWEB_CONFIG_SYSTEM)|g' \
+ -e 's|++GITWEB_HOME_LINK_STR++|$(GITWEB_HOME_LINK_STR)|g' \
+ -e 's|++GITWEB_SITENAME++|$(GITWEB_SITENAME)|g' \
+ -e 's|++GITWEB_PROJECTROOT++|$(GITWEB_PROJECTROOT)|g' \
+ -e 's|"++GITWEB_PROJECT_MAXDEPTH++"|$(GITWEB_PROJECT_MAXDEPTH)|g' \
+ -e 's|++GITWEB_EXPORT_OK++|$(GITWEB_EXPORT_OK)|g' \
+ -e 's|++GITWEB_STRICT_EXPORT++|$(GITWEB_STRICT_EXPORT)|g' \
+ -e 's|++GITWEB_BASE_URL++|$(GITWEB_BASE_URL)|g' \
+ -e 's|++GITWEB_LIST++|$(GITWEB_LIST)|g' \
+ -e 's|++GITWEB_HOMETEXT++|$(GITWEB_HOMETEXT)|g' \
+ -e 's|++GITWEB_CSS++|$(GITWEB_CSS)|g' \
+ -e 's|++GITWEB_LOGO++|$(GITWEB_LOGO)|g' \
+ -e 's|++GITWEB_FAVICON++|$(GITWEB_FAVICON)|g' \
+ -e 's|++GITWEB_JS++|$(GITWEB_JS)|g' \
+ -e 's|++GITWEB_SITE_HEADER++|$(GITWEB_SITE_HEADER)|g' \
+ -e 's|++GITWEB_SITE_FOOTER++|$(GITWEB_SITE_FOOTER)|g' \
+ $< >$@+ && \
+ chmod +x $@+ && \
+ mv $@+ $@
+
+ifdef JSMIN
+gitweb.min.js: gitweb.js
+ $(QUIET_GEN)$(JSMIN) <$< >$@
+endif # JSMIN
+
+clean:
+ $(RM) $(FILES)
+
+.PHONY: all clean .FORCE-GIT-VERSION-FILE
diff --git a/gitweb/README b/gitweb/README
index e34ee793e..ad6a04c46 100644
--- a/gitweb/README
+++ b/gitweb/README
@@ -174,7 +174,7 @@ not include variables usually directly set during build):
Base URL for relative URLs in pages generated by gitweb,
(e.g. $logo, $favicon, @stylesheets if they are relative URLs),
needed and used only for URLs with nonempty PATH_INFO via
- <base href="$base_url>. Usually gitweb sets its value correctly,
+ <base href="$base_url">. Usually gitweb sets its value correctly,
and there is no need to set this variable, e.g. to $my_uri or "/".
* $home_link
Target of the home link on top of all pages (the first part of view
@@ -228,6 +228,11 @@ not include variables usually directly set during build):
repositories from launching cross-site scripting (XSS) attacks. Set this
to true if you don't trust the content of your repositories. The default
is false.
+ * $maxload
+ Used to set the maximum load that we will still respond to gitweb queries.
+ If server load exceed this value then return "503 Service Unavaliable" error.
+ Server load is taken to be 0 if gitweb cannot determine its value. Set it to
+ undefined value to turn it off. The default is 300.
Projects list file format
@@ -307,12 +312,16 @@ If you want to have one URL for both gitweb and your http://
repositories, you can configure apache like this:
<VirtualHost *:80>
- ServerName git.example.org
- DocumentRoot /pub/git
- SetEnv GITWEB_CONFIG /etc/gitweb.conf
+ ServerName git.example.org
+ DocumentRoot /pub/git
+ SetEnv GITWEB_CONFIG /etc/gitweb.conf
+
+ # turning on mod rewrite
RewriteEngine on
+
# make the front page an internal rewrite to the gitweb script
RewriteRule ^/$ /cgi-bin/gitweb.cgi
+
# make access for "dumb clients" work
RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ /cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]
</VirtualHost>
@@ -338,6 +347,63 @@ something like the following in your gitweb.conf (or gitweb_config.perl) file:
$home_link = "/";
+Webserver configuration with multiple projects' root
+----------------------------------------------------
+
+If you want to use gitweb with several project roots you can edit your apache
+virtual host and gitweb.conf configuration files like this :
+
+virtual host configuration :
+
+<VirtualHost *:80>
+ ServerName git.example.org
+ DocumentRoot /pub/git
+ SetEnv GITWEB_CONFIG /etc/gitweb.conf
+
+ # turning on mod rewrite
+ RewriteEngine on
+
+ # make the front page an internal rewrite to the gitweb script
+ RewriteRule ^/$ /cgi-bin/gitweb.cgi [QSA,L,PT]
+
+ # look for a public_git folder in unix users' home
+ # http://git.example.org/~<user>/
+ RewriteRule ^/\~([^\/]+)(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
+
+ # http://git.example.org/+<user>/
+ #RewriteRule ^/\+([^\/]+)(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
+
+ # http://git.example.org/user/<user>/
+ #RewriteRule ^/user/([^\/]+)/(gitweb.cgi)?$ /cgi-bin/gitweb.cgi [QSA,E=GITWEB_PROJECTROOT:/home/$1/public_git/,L,PT]
+
+ # defined list of project roots
+ RewriteRule ^/scm(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi [QSA,E=GITWEB_PROJECTROOT:/pub/scm/,L,PT]
+ RewriteRule ^/var(/|/gitweb.cgi)?$ /cgi-bin/gitweb.cgi [QSA,E=GITWEB_PROJECTROOT:/var/git/,L,PT]
+
+ # make access for "dumb clients" work
+ RewriteRule ^/(.*\.git/(?!/?(HEAD|info|objects|refs)).*)?$ /cgi-bin/gitweb.cgi%{REQUEST_URI} [L,PT]
+</VirtualHost>
+
+gitweb.conf configuration :
+
+$projectroot = $ENV{'GITWEB_PROJECTROOT'} || "/pub/git";
+
+These configurations enable two things. First, each unix user (<user>) of the
+server will be able to browse through gitweb git repositories found in
+~/public_git/ with the following url : http://git.example.org/~<user>/
+
+If you do not want this feature on your server just remove the second rewrite rule.
+
+If you already use mod_userdir in your virtual host or you don't want to use
+the '~' as first character just comment or remove the second rewrite rule and
+uncomment one of the following according to what you want.
+
+Second, repositories found in /pub/scm/ and /var/git/ will be accesible
+through http://git.example.org/scm/ and http://git.example.org/var/.
+You can add as many project roots as you want by adding rewrite rules like the
+third and the fourth.
+
+
PATH_INFO usage
-----------------------
If you enable PATH_INFO usage in gitweb by putting
diff --git a/gitweb/gitweb.js b/gitweb/gitweb.js
index 2a25b7cc4..9c66928c4 100644
--- a/gitweb/gitweb.js
+++ b/gitweb/gitweb.js
@@ -779,7 +779,12 @@ function handleResponse() {
}
// the server returned error
- if (xhr.readyState === 3 && xhr.status !== 200) {
+ // try ... catch block is to work around bug in IE8
+ try {
+ if (xhr.readyState === 3 && xhr.status !== 200) {
+ return;
+ }
+ } catch (e) {
return;
}
if (xhr.readyState === 4 && xhr.status !== 200) {
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 0fe853932..f1d857961 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -221,6 +221,12 @@ our %avatar_size = (
'double' => 32
);
+# Used to set the maximum load that we will still respond to gitweb queries.
+# If server load exceed this value then return "503 server busy" error.
+# If gitweb cannot determined server load, it is taken to be 0.
+# Leave it undefined (or set to 'undef') to turn off load checking.
+our $maxload = 300;
+
# You define site-wide feature defaults here; override them with
# $GITWEB_CONFIG as necessary.
our %feature = (
@@ -448,7 +454,11 @@ sub gitweb_get_feature {
$feature{$name}{'sub'},
$feature{$name}{'override'},
@{$feature{$name}{'default'}});
- if (!$override) { return @defaults; }
+ # project specific override is possible only if we have project
+ our $git_dir; # global variable, declared later
+ if (!$override || !defined $git_dir) {
+ return @defaults;
+ }
if (!defined $sub) {
warn "feature $name is not overridable";
return @defaults;
@@ -544,11 +554,36 @@ sub filter_snapshot_fmts {
}
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
+our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++";
+# die if there are errors parsing config file
if (-e $GITWEB_CONFIG) {
do $GITWEB_CONFIG;
-} else {
- our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++";
- do $GITWEB_CONFIG_SYSTEM if -e $GITWEB_CONFIG_SYSTEM;
+ die $@ if $@;
+} elsif (-e $GITWEB_CONFIG_SYSTEM) {
+ do $GITWEB_CONFIG_SYSTEM;
+ die $@ if $@;
+}
+
+# Get loadavg of system, to compare against $maxload.
+# Currently it requires '/proc/loadavg' present to get loadavg;
+# if it is not present it returns 0, which means no load checking.
+sub get_loadavg {
+ if( -e '/proc/loadavg' ){
+ open my $fd, '<', '/proc/loadavg'
+ or return 0;
+ my @load = split(/\s+/, scalar <$fd>);
+ close $fd;
+
+ # The first three columns measure CPU and IO utilization of the last one,
+ # five, and 10 minute periods. The fourth column shows the number of
+ # currently running processes and the total number of processes in the m/n
+ # format. The last column displays the last process ID used.
+ return $load[0] || 0;
+ }
+ # additional checks for load average should go here for things that don't export
+ # /proc/loadavg
+
+ return 0;
}
# version of the core git binary
@@ -557,6 +592,10 @@ $number_of_git_cmds++;
$projects_list ||= $projectroot;
+if (defined $maxload && get_loadavg() > $maxload) {
+ die_error(503, "The load average on the server is too high");
+}
+
# ======================================================================
# input validation and dispatch
@@ -1305,7 +1344,6 @@ sub chop_str {
$str =~ m/^(.*?)($begre)$/;
my ($lead, $body) = ($1, $2);
if (length($lead) > 4) {
- $body =~ s/^[^;]*;// if ($lead =~ m/&[^;]*$/);
$lead = " ...";
}
return "$lead$body";
@@ -1316,8 +1354,6 @@ sub chop_str {
$str =~ m/^(.*?)($begre)$/;
my ($mid, $right) = ($1, $2);
if (length($mid) > 5) {
- $left =~ s/&[^;]*$//;
- $right =~ s/^[^;]*;// if ($mid =~ m/&[^;]*$/);
$mid = " ... ";
}
return "$left$mid$right";
@@ -1327,7 +1363,6 @@ sub chop_str {
my $body = $1;
my $tail = $2;
if (length($tail) > 4) {
- $body =~ s/&[^;]*$//;
$tail = "... ";
}
return "$body$tail";
@@ -2181,6 +2216,8 @@ sub config_to_multi {
sub git_get_project_config {
my ($key, $type) = @_;
+ return unless defined $git_dir;
+
# key sanity check
return unless ($key);
$key =~ s/^gitweb\.//;
@@ -3229,7 +3266,7 @@ EOF
print "</head>\n" .
"<body>\n";
- if (-f $site_header) {
+ if (defined $site_header && -f $site_header) {
insert_file($site_header);
}
@@ -3330,12 +3367,13 @@ sub git_footer_html {
print "</div>\n"; # class="page_footer"
}
- if (-f $site_footer) {
+ if (defined $site_footer && -f $site_footer) {
insert_file($site_footer);
}
print qq!<script type="text/javascript" src="!.esc_url($javascript).qq!"></script>\n!;
- if ($action eq 'blame_incremental') {
+ if (defined $action &&
+ $action eq 'blame_incremental') {
print qq!<script type="text/javascript">\n!.
qq!startBlame("!. href(action=>"blame_data", -replay=>1) .qq!",\n!.
qq! "!. href() .qq!");\n!.
@@ -3361,22 +3399,33 @@ sub git_footer_html {
# 500: The server isn't configured properly, or
# an internal error occurred (e.g. failed assertions caused by bugs), or
# an unknown error occurred (e.g. the git binary died unexpectedly).
+# 503: The server is currently unavailable (because it is overloaded,
+# or down for maintenance). Generally, this is a temporary state.
sub die_error {
my $status = shift || 500;
my $error = shift || "Internal server error";
-
- my %http_responses = (400 => '400 Bad Request',
- 403 => '403 Forbidden',
- 404 => '404 Not Found',
- 500 => '500 Internal Server Error');
+ my $extra = shift;
+
+ my %http_responses = (
+ 400 => '400 Bad Request',
+ 403 => '403 Forbidden',
+ 404 => '404 Not Found',
+ 500 => '500 Internal Server Error',
+ 503 => '503 Service Unavailable',
+ );
git_header_html($http_responses{$status});
print <<EOF;
<div class="page_body">
<br /><br />
$status - $error
<br />
-</div>
EOF
+ if (defined $extra) {
+ print "<hr />\n" .
+ "$extra\n";
+ }
+ print "</div>\n";
+
git_footer_html();
exit;
}
@@ -3478,14 +3527,21 @@ sub git_print_header_div {
}
sub print_local_time {
+ print format_local_time(@_);
+}
+
+sub format_local_time {
+ my $localtime = '';
my %date = @_;
if ($date{'hour_local'} < 6) {
- printf(" (<span class=\"atnight\">%02d:%02d</span> %s)",
+ $localtime .= sprintf(" (<span class=\"atnight\">%02d:%02d</span> %s)",
$date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'});
} else {
- printf(" (%02d:%02d %s)",
+ $localtime .= sprintf(" (%02d:%02d %s)",
$date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'});
}
+
+ return $localtime;
}
# Outputs the author name and date in long form
@@ -4309,17 +4365,24 @@ sub fill_project_list_info {
# print 'sort by' <th> element, generating 'sort by $name' replay link
# if that order is not selected
sub print_sort_th {
+ print format_sort_th(@_);
+}
+
+sub format_sort_th {
my ($name, $order, $header) = @_;
+ my $sort_th = "";
$header ||= ucfirst($name);
if ($order eq $name) {
- print "<th>$header</th>\n";
+ $sort_th .= "<th>$header</th>\n";
} else {
- print "<th>" .
- $cgi->a({-href => href(-replay=>1, order=>$name),
- -class => "header"}, $header) .
- "</th>\n";
+ $sort_th .= "<th>" .
+ $cgi->a({-href => href(-replay=>1, order=>$name),
+ -class => "header"}, $header) .
+ "</th>\n";
}
+
+ return $sort_th;
}
sub git_project_list_body {
@@ -4750,7 +4813,7 @@ sub git_project_list {
}
git_header_html();
- if (-f $home_text) {
+ if (defined $home_text && -f $home_text) {
print "<div class=\"index_include\">\n";
insert_file($home_text);
print "</div>\n";