gitweb: Harden parse_commit and parse_commits

Gitweb has problems and gives errors when repository it shows is on
unborn branch (HEAD doesn't point to a valid commit), but there exist
other branches.

One of errors that shows in gitweb logs is undefined $commit_id in
parse_commits() subroutine.  Therefore we harden both parse_commit()
and parse_commits() against undefined $commit_id, and against no
output from git-rev-list because HEAD doesn't point to a commit.

Reported-by: rajesh boyapati <boyapatisrajesh@gmail.com>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb: Silence stderr in parse_commit*() subroutines

git-rev-list command in parse_commit() and parse_commits() can fail
because $commit_id doesn't point to a valid commit; for example if we
are on unborn branch HEAD doesn't point to a valid commit.

In this case git-rev-list prints

  fatal: bad revision 'HEAD'

on its standard error.  This commit silences this warning, at the cost
of using shell to redirect it to /dev/null, and relying on
quote_command() to protect against code injection.

Note however that such error message from git (from extrenal command)
usually but not always does not appear in web server logs.

Reported-by: rajesh boyapati <boyapatisrajesh@gmail.com>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb: Jump do DONE_REQUEST not DONE_GITWEB on error

On error (die_error()), instead of ending gitweb process by non-local
jump to DONE_GITWEB label at the end of requests loop in run()
subroutine, just end current request by jumping to DONE_REQUESt at the
end of run_request() subroutine.

This would allow to create new deployment mechanisms (for example
PSGI) based on run_request() and not on run().

Note that DONE_REQUEST label is removed because it is no longer used,
and it wouldn't work correctly for PSGI anyway.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb: Prepare for splitting gitweb

Prepare gitweb for having been split into modules that are to be
installed alongside gitweb in 'lib/' subdirectory, by adding

  use lib __DIR__.'/lib';

to gitweb.perl (to main gitweb script), and preparing for putting
modules (relative path) in $(GITWEB_MODULES) in gitweb/Makefile.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb: Enable running gitweb as PSGI app, via CGI::Emulate::PSGI

This commit makes it possible to run gitweb as a PSGI application
(see http://plackperl.org), using any of PSGI web servers.  This
includes ability to run gitweb from command line via Plack::Runner
module; just run "./gitweb.cgi --psgi" and point web browser
to http://0:5000

Gitweb uses CGI mode by default; to trigger PSGI mode one must either
pass `--psgi` or `--plackup` option to gitweb script, or the script
must be run with *.psgi filename (either copy/rename script, or make
symlink ending with *.psgi e.g. gitweb.psgi).

Besides running gitweb itself, converting its run_request() from CGI
to PSGI via CGI::Emulate::PSGI, gitweb as PSGI app also serves static
files: scripts, stylesheets and images via Plack::Middleware::Static.
Currently it assumes that positions and URLs of those assets are left
at their default values, namely that URLs end with "/static/<file>",
and that files can be found in "static/" directory relative to the
gitweb script itself.  This assumption should be relaxed in future.

Currently "git instaweb --httpd=plackup" doesn't (yet!) use this newly
introduced feature: it is left for future commit.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb.psgi: Allow passing arguments to Plack::Runner

Command options after first '--' are passed literally to Plack::Runner
as arguments, in addition to default ones used.  This way you can
select PSGI server, host, port, etc.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
git-instaweb: Use new PSGI interface mode of gitweb

Now that gitweb supports PSGI interface itself, use it instead of
Plack::App::WrapCGI.

Note that gitweb as PSGI serves static files and ensures correct
handling of SIGCHLD, but the wrapper is still needed for logging,
mimetype handling (probably unnecessary), and selecting host and port.
It is now named gitweb-wrapper.psgi and not gitweb.psgi, though.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb.psgi: Use installed static files, if they are available

When gitweb is running as PSGI app, it must itself take care of
serving static files: stylesheets, script, images that are required
to render gitweb output.

This commit makes gitweb (in PSGI mode) use installed static files
from $(gitwebstaticdir) if such directory exists.  Before this commit
gitweb served static files from 'static/' directory relative to
position of gitweb script itself (to __DIR__).

Note that mechanism of serving is slightly different: the one with
__DIR__ uses Plack::Middleware::Static, while the installdir one uses
URLMap-ped set of Plack::App::File.

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb.conf(5): When to set $base_url

Add a paragraph to description of $base_url variable in gitweb.conf(5)
manpage explaining when and why one might need to set it, and how.

Based-on-report-by: José María Escartín Esteban <ripero84@gmail.com>
Signed-off-by: Jakub Narębski <jnareb@gmail.com>
gitweb: Improve repository verification

Bring repository verification in check_export_ok() to standards of
is_git_directory function from setup.c (core git), and validate_headref()
to standards of the same function in path.c,... and a bit more.

validate_headref() replaces check_head_link(); note that the former
requires path to HEAD file, while the late latter path to repository.

Issues of note:
* is_git_directory() in gitweb is a bit stricter: it checks that
  "/objects" and "/refs" are directories, and not only 'executable'
  permission,
* validate_headref() in gitweb is a bit stricter: it checks that
  reference symlink or symref points to starts with "refs/heads/",
  and not only with "refs/",
* calls to check_head_link(), all of which were meant to check if
  given directory can be a git repository, were replaced by newly
  introduced is_git_directory().

This change is preparation for removing "Last change" column from list
of projects, which is currently used also for validating repository.

Suggested-by: Kacper Kornet <draenog@pld-linux.org>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
gitweb: Add support for "gitdir: <path>" gitfile (WIP)

No use of resolve_gitdir, no tests !!!

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>