Skip to content

Instantly share code, notes, and snippets.

@fbriere
Last active August 29, 2015 14:03
Show Gist options
  • Save fbriere/43be3a8d60eb0053adbf to your computer and use it in GitHub Desktop.
Save fbriere/43be3a8d60eb0053adbf to your computer and use it in GitHub Desktop.
gitweb configuration for git.fbriere.net
(This is a dummy file to force a title for this Gist.)
# .htaccess for git.fbriere.net
# Welcome to the 21st century!
AddDefaultCharset utf-8
# We'll need this. A lot. You will get intimately familiar with the manpage. :)
RewriteEngine on
# Remember that in htaccess context, the RewriteRule 'Pattern' is matched
# against the filesystem path, after *removing the prefix* that led the server
# to that rule. In our case, that is "/". So we need to omit the leading "/"
# in RewriteRule -- but leave it on in RewriteCond or RedirectMatch. Don't
# get confused. :)
#
# Also remember that Apache will automatically add a trailing slash *iff* a
# directory of that name exists. This may have an impact if we migrate a
# directory from one place to another -- better plan ahead and support both.
# gitweb config -- we also deny access to these files, just in case
SetEnv GIT_CONFIG /home/public/gitweb/gitconfig
SetEnv GITWEB_CONFIG /home/public/gitweb/gitweb.conf
RewriteRule ^gitweb/(gitweb\.conf|gitconfig)$ - [forbidden]
# This was moved a long time ago
RedirectMatch permanent ^/dexdrive\.git http://gitorious.org/linux-dexdrive
###
# Now the fun begins! Here are my goals:
#
# The canonical URL for gitweb is:
#
# http://git.fbriere.net/gitweb/
#
# Links output by gitweb will be in the "pathinfo" format, namely:
#
# http://git.fbriere.net/gitweb/repo-name.git[/action[/...]]
#
# The canonical URL for each repo is:
#
# http://git.fbriere.net/repo-name.git[/]
#
# The trailing slash is optional. The output will be the gitweb summary of
# that repo (i.e. the same as "http://git.fbriere.net/repo-name.git").
# (Aside from looking nicer, it allows replacing gitweb with another browser
# in the future, without changing the URL.)
#
# That canonical URL should *also* be git-clonable.
#
# Links that pre-date "pathinfo" should redirect to their new location.
#
# Historically, the gitweb URL used to be "/". I want these old links:
#
# http://git.fbriere.net/?p=repo-name.git[;a=...]
#
# ... to also redirect to their new location.
#
# Finally, some repos have been moved to GitHub (sometimes under a different
# name). I still want the old URLs to work for a while: the project summary
# page (both URLs) should redirect to its GitHub equivalent, and everything
# git-clone needs should also point to the right resources. (Unfortunately,
# git won't catch on and update its configured URL -- oh well.)
#
# Whew! Let's do this! :)
###
# First: repos which we moved to GitHub under a *different* name. We rename
# them internally, and let the general rules kick in later on.
# Rewrite the prefix -- leave everything else for later
RewriteRule ^(gitweb/)?debian\/eawpatches\.git(/.*)?$ /eawpatches-package.git$1
# Also redirect gitweb '?p=' links -- the 'p' argument will no longer be
# correct, but we'll ditch the whole query later on anyway
RewriteCond %{QUERY_STRING} ^p=debian\/eawpatches\.git
RewriteRule ^(?:gitweb/?)?$ /eawpatches-package.git
###
# Repositories moved to GitHub (with matching names)
# Redirect all "gitweb/?p=" to GitHub. We ditch the gitweb query string, as
# GitHub wouldn't know what to do with it.
# (For Apache 2.2 without qsdiscard: just append an empty query string instead.)
RewriteCond %{QUERY_STRING} ^p=(anki-kdrill|anki-kanjivocab|eawpatches-package)\.git
RewriteRule ^(?:gitweb/?)?$ https://github.com/fbriere/%1 [redirect=permanent,last,qsdiscard]
# Ditto for the new gitweb URLs -- ditching any $PATH_INFO
RewriteRule ^gitweb/(anki-kdrill|anki-kanjivocab|eawpatches-package)\.git(/.*)?$ https://github.com/fbriere/$1 [redirect=permanent,last,qsdiscard]
# Same thing for the canonical URL (with optional trailing slash)
RewriteRule ^(anki-kdrill|anki-kanjivocab|eawpatches-package)\.git/?$ https://github.com/fbriere/$1 [redirect=permanent,last,qsdiscard]
# Any file below is a Git resource -- send it to the GitHub clonable URL
RewriteRule ^(anki-kdrill|anki-kanjivocab|eawpatches-package)\.git/(.+) https://github.com/fbriere/$1.git/$2 [redirect=permanent,last]
###
# GitHub Gists are identified by their ID, not their name
RewriteCond %{QUERY_STRING} ^p=mailbinpurge\.git
RewriteRule ^(?:gitweb/?)?$ https://gist.github.com/e86584a807449e3128c0 [redirect=permanent,last,qsdiscard]
RewriteRule ^gitweb/mailbinpurge\.git/?$ https://gist.github.com/e86584a807449e3128c0 [redirect=permanent,last,qsdiscard]
RewriteRule ^mailbinpurge\.git/?$ https://gist.github.com/e86584a807449e3128c0 [redirect=permanent,last,qsdiscard]
RewriteRule ^mailbinpurge\.git(.+) https://gist.github.com/e86584a807449e3128c0.git/$1 [redirect=permanent,last,qsdiscard]
###
# Local repos
#
# Make sure we let calls to gitweb.cgi pass through unscathed.
# (Otherwise, "gitweb.cgi/repo.git" could be misconstrued as a repo name.)
RewriteRule ^gitweb/gitweb\.cgi(/.*)? - [END]
# Pass all "/gitweb/<repo-or-action>" URLs to gitweb.cgi -- but letting
# /gitweb/static/* requests go through.
RewriteCond %{REQUEST_URI} !^/gitweb/static/
RewriteRule ^gitweb/(.*) /gitweb/gitweb.cgi/$1 [last]
# Also call gitweb for a repo's canonical URL.
#
# For old URLs with a query string, gitweb.conf will take care of the redirect
RewriteRule ^(.*\.git)/?$ /gitweb/gitweb.cgi/$1 [last]
# Also let gitweb.conf handle old "/?p=..." URLs
RewriteCond %{QUERY_STRING} ^([ap]=.*)
RewriteRule ^$ /gitweb/?%1 [last]
# To rebuild gitweb from the Git source tree:
#
# make -C gitweb install prefix=/usr/local gitwebdir=$GITWEB_DIR
#
# (prefix defaults to $HOME, which you probably don't want.)
#
# NOTE: You *must* pass all options to "make install" -- it will rebuild
# if you don't.
use strict;
our ($cgi, %feature, %input_params);
# Directory containing our repos
our $projectroot = "/home/public";
# Filename of html text to include at top of each page
our $site_header = "header.html";
# Target of the first breadcrumb on top of all pages.
our $home_link = "/gitweb/";
# Enable the "pathinfo" option -- URLs generated by gitweb will have the
# project name and query string embedded.
$feature{'pathinfo'}{'default'} = [1];
# CGI.pm apparently strips $PATH_INFO from url() [although the gitweb code
# strangely states otherwise], thus yielding "/gitweb", which is not what we
# want. (Among other things, it would result in a base URL of "/".)
#
# Even if that were not the case, requests for "/repo.git" would have to be
# rewritten anyway, for the base URL to be correct, and for the search form to
# point to the right place.
#
our $my_uri = "/gitweb/";
our $my_url = $cgi->url(-base => 1) . $my_uri;
our $base_url = $my_url;
# Redirect any old "?p=repo.git;a=..." URL to its new canonical path.
#
# This is tricky, because the query string has not been parsed yet. So, we
# hijack a totally unrelated system, where certain gitweb features can be
# overridden on a per-project (even per-request) basis. This is done by
# providing a code reference, which is expected to return the desired
# configuration value for that feature.
#
# Now, we don't care about any of that stuff, but the code reference will be
# called *after* the query string has been parsed. So, we just pick any
# overridable feature at random (say, "snapshot") and do our thing in there.
$feature{'snapshot'}{'override'} = 1;
# Grab a copy of the current (default) code reference
my $old_sub = $feature{'snapshot'}{'sub'};
# Replace it with our own
$feature{'snapshot'}{'sub'} = sub {
# URLs for a "search" action will always have a query string in the end
# (No need to test "project_list", we'll only be called in a project)
if ($cgi->query_string && $input_params{action} ne 'search') {
print $cgi->redirect(
-status => '301 Moved Permanently',
-uri => href(%input_params, -full => 1),
);
exit;
}
# Pass the baton to the previous code reference
goto $old_sub;
};
# This proved quite useful when debugging
if ($ENV{REMOTE_ADDR} eq '127.0.0.1') {
my @info;
# Environment variables
push @info, "\$$_=$ENV{$_}" foreach qw[
PATH_INFO
QUERY_STRING
PATH_TRANSLATED
REDIRECT_URL
REQUEST_URI
REDIRECT_STATUS
SCRIPT_NAME
];
# CGI methods
push @info, "$_()=@{[ $cgi->$_ ]}" foreach qw[
url
request_uri
script_name
path_info
query_string
];
# gitweb (dynamically scoped) variables
no strict 'refs';
push @info, "\$$_=$$_" foreach qw[
my_url
my_uri
base_url
];
our $site_html_head_string = join "\n" => "<!--", @info, "-->";
}
# vim: syntax=perl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment