Intermediate commit on the way to switching to Git::PurePerl.
broquaint [Sun, 20 Sep 2009 18:18:40 +0000 (19:18 +0100)]
lib/Gitalist/Controller/Root.pm
lib/Gitalist/Model/GPP.pm [new file with mode: 0644]
lib/Gitalist/Model/Git.pm
templates/default.tt2

index 10b8cb3..04ceabf 100644 (file)
@@ -74,17 +74,8 @@ sub index :Path :Args(0) {
 sub blob : Local {
   my ( $self, $c ) = @_;
 
-  my $git      = $c->model('Git');
-  my $req      = $c->req;
-  my $proj     = $req->param('p');
-  my $filename = $req->param('f')  || $req->param('filename');
-  my $hash     = $req->param('hb') || $git->get_head_hash($proj);
-  my $filehash = $req->param('h')  || $git->get_hash_by_path($proj, $hash, $filename, 'blob');
-  
-  my $blob = $git->run_cmd('cat-file' => blob => $filehash);
-
   $c->stash(
-      blob   => $blob,
+      blob   => $c->model('GPP')->get_object($c->req->param('h'))->content,
       action => 'blob',
   );
 }
@@ -93,8 +84,6 @@ sub reflog : Local {
   my ( $self, $c ) = @_;
 
   my @log = $c->model('Git')->reflog(
-      # XXX The project parameter should probably be passed into the Model.
-      $c->req->param('p'),
       '--since=yesterday'
   );
 
@@ -104,9 +93,19 @@ sub reflog : Local {
   );
 }
 
+sub commit {
+  my ( $self, $c ) = @_;
+}
+
 sub auto : Private {
     my($self, $c) = @_;
 
+    # XXX Probably not the best place for it but it will do for now.
+    if(my $proj = $c->req->param('p')) {
+        my $m = $c->model('Git');
+        $m->project($proj);
+    }
+
     # Yes, this is hideous.
     $self->header($c);
     $self->footer($c);
diff --git a/lib/Gitalist/Model/GPP.pm b/lib/Gitalist/Model/GPP.pm
new file mode 100644 (file)
index 0000000..e560b5c
--- /dev/null
@@ -0,0 +1,45 @@
+package Gitalist::Model::GPP;
+
+#use base 'Catalyst::Model::Adaptor';
+use Moose;
+use namespace::autoclean;
+
+extends 'Catalyst::Model';
+
+use Git::PurePerl;
+
+has git => (
+ #isa => 'Git::PurePerl'
+  is       => 'ro',
+  required => 1,
+  lazy     => 1,
+  default  => sub {
+    my($self) = @_;
+    return Git::PurePerl->new(
+      directory => $self->project_path
+    );
+  },
+);
+
+has project => (
+  is => 'rw',
+  isa => 'Str',
+);
+has project_path => (
+  is => 'rw',
+);
+
+
+sub ACCEPT_CONTEXT {
+    my ( $self, $c ) = @_;
+    $self->project( $c->req->param('p') );
+    $self->project_path( $c->model('Git')->project_dir( $self->project ) );
+    # XXX Or just return a new Git:PP object?
+    return $self;
+}
+
+sub get_object {
+  $_[0]->git->get_object($_[1]);
+}
+
+1;
index a4afd8e..570d2de 100644 (file)
@@ -5,6 +5,8 @@ use namespace::autoclean;
 
 BEGIN { extends 'Catalyst::Model' }
 
+use Git::PurePerl;
+
 use DateTime;
 use Path::Class;
 use Carp qw/croak/;
@@ -15,323 +17,331 @@ use List::MoreUtils qw/any/;
 use Scalar::Util qw/blessed/;
 
 {
-       my $git;
-       sub git {
-               return $git
-                       if $git;
-
-               if (my $config_git = Gitalist->config->{git}) {
-                       $git = $config_git if -x $config_git;
-               }
-               else {
-                       require File::Which;
-                       $git = File::Which::which('git');
-               }
-
-               if (!$git) {
-                       die <<EOR
+  my $git;
+  sub git_bin {
+    return $git
+      if $git;
+
+    if (my $config_git = Gitalist->config->{git}) {
+      $git = $config_git if -x $config_git;
+    }
+    else {
+      require File::Which;
+      $git = File::Which::which('git');
+    }
+
+    if (!$git) {
+      die <<EOR
 Could not find a git executable.
 Please specify the which git executable to use in gitweb.yml
 EOR
-               }
+    }
 
-               return $git;
-       }
+    return $git;
+  }
 }
 
+has project => (is => 'rw', isa => 'Str');
+
 sub is_git_repo {
-    my ($self, $dir) = @_;
+  my ($self, $dir) = @_;
 
-    return -f $dir->file('HEAD') || -f $dir->file('.git/HEAD');
+  return -f $dir->file('HEAD') || -f $dir->file('.git/HEAD');
 }
 
 sub project_info {
-    my ($self, $project) = @_;
+  my ($self, $project) = @_;
 
-    return {
-        name => $project,
-        $self->get_project_properties(
-                $self->git_dir_from_project_name($project),
-        ),
+  return {
+    name => $project,
+    $self->get_project_properties(
+      $self->git_dir_from_project_name($project),
+      ),
     };
 }
 
 sub get_project_properties {
-    my ($self, $dir) = @_;
-    my %props;
+  my ($self, $dir) = @_;
+  my %props;
 
-    eval {
-        $props{description} = $dir->file('description')->slurp;
-        chomp $props{description};
+  eval {
+    $props{description} = $dir->file('description')->slurp;
+    chomp $props{description};
     };
 
-    if ($props{description} && $props{description} =~ /^Unnamed repository;/) {
-        delete $props{description};
-    }
+  if ($props{description} && $props{description} =~ /^Unnamed repository;/) {
+    delete $props{description};
+  }
 
-    $props{owner} = (getpwuid $dir->stat->uid)[6];
+  ($props{owner} = (getpwuid $dir->stat->uid)[6]) =~ s/,+$//;
 
-    my $output = $self->run_cmd_in($dir, qw{
-            for-each-ref --format=%(committer)
-            --sort=-committerdate --count=1 refs/heads
-    });
+  my $output = $self->run_cmd_in($dir, qw{
+      for-each-ref --format=%(committer)
+      --sort=-committerdate --count=1 refs/heads
+      });
 
-    if (my ($epoch, $tz) = $output =~ /\s(\d+)\s+([+-]\d+)$/) {
-        my $dt = DateTime->from_epoch(epoch => $epoch);
-        $dt->set_time_zone($tz);
-        $props{last_change} = $dt;
-    }
+  if (my ($epoch, $tz) = $output =~ /\s(\d+)\s+([+-]\d+)$/) {
+    my $dt = DateTime->from_epoch(epoch => $epoch);
+    $dt->set_time_zone($tz);
+    $props{last_change} = $dt;
+  }
 
-    return %props;
+  return %props;
 }
 
 sub list_projects {
-    my ($self) = @_;
+  my ($self) = @_;
 
-    my $base = dir(Gitalist->config->{repo_dir});
+  my $base = dir(Gitalist->config->{repo_dir});
 
-    my @ret;
-    my $dh = $base->open;
-    while (my $file = $dh->read) {
-        next if $file =~ /^.{1,2}$/;
-
-        my $obj = $base->subdir($file);
-        next unless -d $obj;
-        next unless $self->is_git_repo($obj);
-               # XXX Leaky abstraction alert!
-               my $is_bare = !-d $obj->subdir('.git');
-
-               my $name = (File::Spec->splitdir($obj))[-1];
-        push @ret, {
-            name => ($name . ( $is_bare ? '.git' : '/.git' )),
-            $self->get_project_properties(
-                               $is_bare ? $obj : $obj->subdir('.git')
-                       ),
-        };
-    }
+  my @ret;
+  my $dh = $base->open;
+  while (my $file = $dh->read) {
+    next if $file =~ /^.{1,2}$/;
+
+    my $obj = $base->subdir($file);
+    next unless -d $obj;
+    next unless $self->is_git_repo($obj);
 
-    return [sort { $a->{name} cmp $b->{name} } @ret];
+    # XXX Leaky abstraction alert!
+    my $is_bare = !-d $obj->subdir('.git');
+
+    my $name = (File::Spec->splitdir($obj))[-1];
+    push @ret, {
+      name => ($name . ( $is_bare ? '.git' : '/.git' )),
+      $self->get_project_properties(
+        $is_bare ? $obj : $obj->subdir('.git')
+        ),
+      };
+  }
+
+  return [sort { $a->{name} cmp $b->{name} } @ret];
 }
 
 sub run_cmd {
-    my ($self, @args) = @_;
+  my ($self, @args) = @_;
 
-    open my $fh, '-|', __PACKAGE__->git, @args
-        or die "failed to run git command";
-    binmode $fh, ':encoding(UTF-8)';
+  open my $fh, '-|', __PACKAGE__->git_bin, @args
+    or die "failed to run git command";
+  binmode $fh, ':encoding(UTF-8)';
 
-    print STDERR "RAN - git @_[1..$#_]\n"; 
+  print STDERR "RAN - git @_[1..$#_]\n";
 
-    my $output = do { local $/ = undef; <$fh> };
-    close $fh;
+  my $output = do { local $/ = undef; <$fh> };
+  close $fh;
 
-    return $output;
+  return $output;
+}
+
+sub project_dir {
+  my($self, $project) = @_;
+
+  my $dir = blessed($project) && $project->isa('Path::Class::Dir')
+       ? $project->stringify
+       : $self->git_dir_from_project_name($project);
+
+  $dir =~ s/\.git$//;
+
+  return $dir;
 }
 
 sub run_cmd_in {
-    my ($self, $project, @args) = @_;
+  my ($self, $project, @args) = @_;
 
-    my $path;
-    if (blessed($project) && $project->isa('Path::Class::Dir')) {
-        $path = $project->stringify;
-    }
-    else {
-        $path = $self->git_dir_from_project_name($project);
-    }
-    return $self->run_cmd('--git-dir' => $path, @args);
+  return $self->run_cmd('--git-dir' => $self->project_dir($project), @args);
 }
 
 sub git_dir_from_project_name {
-    my ($self, $project) = @_;
+  my ($self, $project) = @_;
 
-    return dir(Gitalist->config->{repo_dir})->subdir($project);
+  return dir(Gitalist->config->{repo_dir})->subdir($project);
 }
 
 sub get_head_hash {
-    my ($self, $project) = @_;
+  my ($self, $project) = @_;
 
-    my $output = $self->run_cmd_in($project, qw/rev-parse --verify HEAD/ );
-    return unless defined $output;
+  my $output = $self->run_cmd_in($self->project, qw/rev-parse --verify HEAD/ );
+  return unless defined $output;
 
-    my ($head) = $output =~ /^([0-9a-fA-F]{40})$/;
-    return $head;
+  my ($head) = $output =~ /^([0-9a-fA-F]{40})$/;
+  return $head;
 }
 
 sub list_tree {
-    my ($self, $project, $rev) = @_;
+  my ($self, $project, $rev) = @_;
 
-    $rev ||= $self->get_head_hash($project);
+  $rev ||= $self->get_head_hash($project);
 
-    my $output = $self->run_cmd_in($project, qw/ls-tree -z/, $rev);
-    return unless defined $output;
+  my $output = $self->run_cmd_in($project, qw/ls-tree -z/, $rev);
+  return unless defined $output;
 
-    my @ret;
-    for my $line (split /\0/, $output) {
-        my ($mode, $type, $object, $file) = split /\s+/, $line, 4;
-
-        push @ret, {
-            mode   => oct $mode,
-            type   => $type,
-            object => $object,
-            file   => $file,
-        };
-    }
+  my @ret;
+  for my $line (split /\0/, $output) {
+    my ($mode, $type, $object, $file) = split /\s+/, $line, 4;
 
-    return @ret;
+    push @ret, {
+      mode   => oct $mode,
+      type   => $type,
+      object => $object,
+      file   => $file,
+      };
+  }
+
+  return @ret;
 }
 
 sub get_object_mode_string {
-    my ($self, $object) = @_;
+  my ($self, $object) = @_;
 
-    return unless $object && $object->{mode};
-    return mode_to_string($object->{mode});
+  return unless $object && $object->{mode};
+  return mode_to_string($object->{mode});
 }
 
 sub get_object_type {
-    my ($self, $project, $object) = @_;
+  my ($self, $project, $object) = @_;
 
-    my $output = $self->run_cmd_in($project, qw/cat-file -t/, $object);
-    return unless $output;
+  my $output = $self->run_cmd_in($project, qw/cat-file -t/, $object);
+  return unless $output;
 
-    chomp $output;
-    return $output;
+  chomp $output;
+  return $output;
 }
 
 sub get_hash_by_path {
-       my($self, $project, $base, $path, $type) = @_;
+  my($self, $base, $path, $type) = @_;
 
-       $path =~ s{/+$}();
+  $path =~ s{/+$}();
 
-       my $line = $self->run_cmd_in($project, 'ls-tree', $base, '--', $path)
+  my $line = $self->run_cmd_in($self->project, 'ls-tree', $base, '--', $path)
     or return;
 
-       #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa  panic.c'
-       $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t/;
-       return defined $type && $type ne $2
-       ? ()
-            : return $3;
+  #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa       panic.c'
+  $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t/;
+  return defined $type && $type ne $2
+    ? ()
+    : return $3;
 }
 
 sub cat_file {
-    my ($self, $project, $object) = @_;
+  my ($self, $object) = @_;
 
-    my $type = $self->get_object_type($project, $object);
-    die "object `$object' is not a file\n"
-        if (!defined $type || $type ne 'blob');
+  my $type = $self->get_object_type($self->project, $object);
+  die "object `$object' is not a file\n"
+    if (!defined $type || $type ne 'blob');
 
-    my $output = $self->run_cmd_in($project, qw/cat-file -p/, $object);
-    return unless $output;
+  my $output = $self->run_cmd_in($self->project, qw/cat-file -p/, $object);
+  return unless $output;
 
-    return $output;
+  return $output;
 }
 
 sub valid_rev {
-    my ($self, $rev) = @_;
+  my ($self, $rev) = @_;
 
-    return unless $rev;
-    return ($rev =~ /^([0-9a-fA-F]{40})$/);
+  return unless $rev;
+  return ($rev =~ /^([0-9a-fA-F]{40})$/);
 }
 
 sub diff {
-    my ($self, $project, @revs) = @_;
+  my ($self, $project, @revs) = @_;
 
-    croak("Gitalist::Model::Git::diff needs a project and either one or two revisions")
-        if scalar @revs < 1
-        || scalar @revs > 2
-        || any { !$self->valid_rev($_) } @revs;
+  croak("Gitalist::Model::Git::diff needs a project and either one or two revisions")
+    if scalar @revs < 1
+      || scalar @revs > 2
+      || any { !$self->valid_rev($_) } @revs;
 
-    my $output = $self->run_cmd_in($project, 'diff', @revs);
-    return unless $output;
+  my $output = $self->run_cmd_in($project, 'diff', @revs);
+  return unless $output;
 
-    return $output;
+  return $output;
 }
 
 {
-    my $formatter = DateTime::Format::Mail->new;
-
-    sub parse_rev_list {
-        my ($self, $output) = @_;
-        my @ret;
-
-        my @revs = split /\0/, $output;
-
-        for my $rev (split /\0/, $output) {
-            for my $line (split /\n/, $rev, 6) {
-                chomp $line;
-                next unless $line;
-
-                if ($self->valid_rev($line)) {
-                    push @ret, {rev => $line};
-                    next;
-                }
-
-                if (my ($key, $value) = $line =~ /^(tree|parent)\s+(.*)$/) {
-                    $ret[-1]->{$key} = $value;
-                    next;
-                }
-
-                if (my ($key, $value, $epoch, $tz) = $line =~ /^(author|committer)\s+(.*)\s+(\d+)\s+([+-]\d+)$/) {
-                    $ret[-1]->{$key} = $value;
-                    eval {
-                        $ret[-1]->{ $key . "_datetime" } = DateTime->from_epoch(epoch => $epoch);
-                        $ret[-1]->{ $key . "_datetime" }->set_time_zone($tz);
-                        $ret[-1]->{ $key . "_datetime" }->set_formatter($formatter);
-                    };
-
-                    if ($@) {
-                        $ret[-1]->{ $key . "_datetime" } = "$epoch $tz";
-                    }
-
-                    if (my ($name, $email) = $value =~ /^([^<]+)\s+<([^>]+)>$/) {
-                        $ret[-1]->{ $key . "_name"  } = $name;
-                        $ret[-1]->{ $key . "_email" } = $email;
-                    }
-                }
-
-                $line =~ s/^\n?\s{4}//;
-                $ret[-1]->{longmessage} = $line;
-                $ret[-1]->{message} = (split /\n/, $line, 2)[0];
-            }
+  my $formatter = DateTime::Format::Mail->new;
+
+  sub parse_rev_list {
+    my ($self, $output) = @_;
+    my @ret;
+
+    my @revs = split /\0/, $output;
+
+    for my $rev (split /\0/, $output) {
+      for my $line (split /\n/, $rev, 6) {
+        chomp $line;
+        next unless $line;
+
+        if ($self->valid_rev($line)) {
+          push @ret, {rev => $line};
+          next;
+        }
+
+        if (my ($key, $value) = $line =~ /^(tree|parent)\s+(.*)$/) {
+          $ret[-1]->{$key} = $value;
+          next;
         }
 
-        return @ret;
+        if (my ($key, $value, $epoch, $tz) = $line =~ /^(author|committer)\s+(.*)\s+(\d+)\s+([+-]\d+)$/) {
+          $ret[-1]->{$key} = $value;
+          eval {
+            $ret[-1]->{ $key . "_datetime" } = DateTime->from_epoch(epoch => $epoch);
+            $ret[-1]->{ $key . "_datetime" }->set_time_zone($tz);
+            $ret[-1]->{ $key . "_datetime" }->set_formatter($formatter);
+            };
+
+          if ($@) {
+            $ret[-1]->{ $key . "_datetime" } = "$epoch $tz";
+          }
+
+          if (my ($name, $email) = $value =~ /^([^<]+)\s+<([^>]+)>$/) {
+            $ret[-1]->{ $key . "_name"  } = $name;
+            $ret[-1]->{ $key . "_email" } = $email;
+          }
+        }
+
+        $line =~ s/^\n?\s{4}//;
+        $ret[-1]->{longmessage} = $line;
+        $ret[-1]->{message} = (split /\n/, $line, 2)[0];
+      }
     }
+
+    return @ret;
+  }
 }
 
 sub list_revs {
-    my ($self, $project, %args) = @_;
+  my ($self, $project, %args) = @_;
 
-    $args{rev} ||= $self->get_head_hash($project);
+  $args{rev} ||= $self->get_head_hash($project);
 
-    my $output = $self->run_cmd_in($project, 'rev-list',
-            '--header',
-            (defined $args{ count } ? "--max-count=$args{count}" : ()),
-            (defined $args{ skip  } ? "--skip=$args{skip}"     : ()),
-            $args{rev},
-            '--',
-            ($args{file} || ()),
+  my $output = $self->run_cmd_in($project, 'rev-list',
+    '--header',
+    (defined $args{ count } ? "--max-count=$args{count}" : ()),
+    (defined $args{ skip  } ? "--skip=$args{skip}"     : ()),
+    $args{rev},
+    '--',
+    ($args{file} || ()),
     );
-    return unless $output;
+  return unless $output;
 
-    my @revs = $self->parse_rev_list($output);
+  my @revs = $self->parse_rev_list($output);
 
-    return \@revs;
+  return \@revs;
 }
 
 sub rev_info {
-    my ($self, $project, $rev) = @_;
+  my ($self, $project, $rev) = @_;
 
-    return unless $self->valid_rev($rev);
+  return unless $self->valid_rev($rev);
 
-    return $self->list_revs($project, rev => $rev, count => 1);
+  return $self->list_revs($project, rev => $rev, count => 1);
 }
 
 sub reflog {
-    my ($self, $project, @logargs) = @_;
+  my ($self, @logargs) = @_;
 
-    my @entries
-      =  $self->run_cmd_in($project, qw(log -g), @logargs)
-      =~ /(^commit.+?(?:(?=^commit)|(?=\z)))/msg;
+  my @entries
+    =  $self->run_cmd_in($self->project, qw(log -g), @logargs)
+    =~ /(^commit.+?(?:(?=^commit)|(?=\z)))/msg;
 
 =begin
 
@@ -343,63 +353,67 @@ sub reflog {
 
       Merge branch 'rt125181
 =cut
-    return map {
-      # XXX Stuff like this makes me want to switch to Git::PurePerl
-      my($sha1, $type, $author, $date)
-        = m{
+
+  return map {
+
+    # XXX Stuff like this makes me want to switch to Git::PurePerl
+    my($sha1, $type, $author, $date)
+      = m{
           ^ commit \s+ ([0-9a-f]+)$
           .*?
           Reflog[ ]message: \s+ (.+?)$ \s+
           Author: \s+ ([^<]+) <.*?$ \s+
           Date: \s+ (.+?)$
-        }xms;
+}xms;
 
-      pos($_) = index($_, $date) + length $date;
-      # Yeah, I just did that.
+    pos($_) = index($_, $date) + length $date;
 
-      my($msg) = /\G\s+(\S.*)/sg;
+    # Yeah, I just did that.
 
-      {
-        hash    => $sha1,
-        type    => $type,
-        author  => $author,
-        # XXX Add DateTime goodness.
-        date    => $date,
-        message => $msg,
-      };
+    my($msg) = /\G\s+(\S.*)/sg;
+
+    {
+      hash    => $sha1,
+      type    => $type,
+      author  => $author,
+
+      # XXX Add DateTime goodness.
+      date    => $date,
+      message => $msg,
+    };
     } @entries;
 }
 
 sub get_heads {
-    my ($self, $project) = @_;
+  my ($self, $project) = @_;
 
-    my $output = $self->run_cmd_in($project, qw/for-each-ref --sort=-committerdate /, '--format=%(objectname)%00%(refname)%00%(committer)', 'refs/heads');
-    return unless $output;
+  my $output = $self->run_cmd_in($project, qw/for-each-ref --sort=-committerdate /, '--format=%(objectname)%00%(refname)%00%(committer)', 'refs/heads');
+  return unless $output;
 
-    my @ret;
-    for my $line (split /\n/, $output) {
-        my ($rev, $head, $commiter) = split /\0/, $line, 3;
-        $head =~ s!^refs/heads/!!;
+  my @ret;
+  for my $line (split /\n/, $output) {
+    my ($rev, $head, $commiter) = split /\0/, $line, 3;
+    $head =~ s!^refs/heads/!!;
 
-        push @ret, { rev => $rev, name => $head };
+    push @ret, { rev => $rev, name => $head };
 
-        #FIXME: That isn't the time I'm looking for..
-        if (my ($epoch, $tz) = $output =~ /\s(\d+)\s+([+-]\d+)$/) {
-            my $dt = DateTime->from_epoch(epoch => $epoch);
-            $dt->set_time_zone($tz);
-            $ret[-1]->{last_change} = $dt;
-        }
+    #FIXME: That isn't the time I'm looking for..
+    if (my ($epoch, $tz) = $output =~ /\s(\d+)\s+([+-]\d+)$/) {
+      my $dt = DateTime->from_epoch(epoch => $epoch);
+      $dt->set_time_zone($tz);
+      $ret[-1]->{last_change} = $dt;
     }
+  }
 
-    return \@ret;
+  return \@ret;
 }
 
 sub archive {
-    my ($self, $project, $rev) = @_;
+  my ($self, $project, $rev) = @_;
 
-    #FIXME: huge memory consuption
-    #TODO: compression
-    return $self->run_cmd_in($project, qw/archive --format=tar/, "--prefix=${project}/", $rev);
+  #FIXME: huge memory consuption
+  #TODO: compression
+  return $self->run_cmd_in($project, qw/archive --format=tar/, "--prefix=${project}/", $rev);
 }
 
 1;
index f8db2b2..6d51427 100644 (file)
@@ -9,7 +9,7 @@
   <meta http-equiv="content-type" content="[% content_type %]; charset=utf-8"/>
   <meta name="generator" content="gitweb/[% version %] git/[% git_version %][% mod_perl_version %]"/>
   <meta name="robots" content="index, nofollow"/>
-  <title>[% title %] (Gitalist)</title>
+  <title>[% title | html %] (Gitalist)</title>
   [% IF baseurl %]
   <base href="[% baseurl %]" />
   [% END %]
 [% site_header %]
 
 <div class="page_header">
-  <a title="[% logo_label %]" href="[% logo_url %]"><img src="[% logo_img %]" alt="git" class="logo"/></a>
-  <a href="[% home_link %]">[% home_link_str %]</a>
+  <a title="[% logo_label | url %]" href="[% logo_url | url %]"><img src="[% logo_img %]" alt="git" class="logo"/></a>
+  <a href="[% home_link | url %]">[% home_link_str %]</a>
   [%- IF project %]
-  / <a href="/git/gitweb.cgi?p=[% project %];a=summary">[% project %]</a>
+  / <a href="/?p=[% project %];a=summary">[% project %]</a>
   [% IF action;  " / " _ action; END;
   END %]
 </div>
@@ -78,7 +78,7 @@
 -%]
 <div class="page_footer">
 [% IF project AND project_description %]
-  <div class="page_footer_text">[% project_description %]</div>
+  <div class="page_footer_text">[% project_description | html %]</div>
 [% END %]
 [% FOR feed IN feeds %]
     <a class="[% feed.class %]" title="[% feed.title %]" href="[% feed.href %]">[% feed.name %]</a>