gitweb: Add generic git_object subroutine to display object of any type
authorJakub Narebski <jnareb@gmail.com>
Sun, 10 Dec 2006 12:25:47 +0000 (13:25 +0100)
committerJunio C Hamano <junkio@cox.net>
Tue, 12 Dec 2006 08:55:23 +0000 (00:55 -0800)
Add generic "object" view implemented in git_object subroutine, which is
used to display object of any type; to be more exact it redirects to the
view of correct type: "blob", "tree", "commit" or "tag".  To identify object
you have to provide either hash (identifier of an object), or (in the case of
tree and blob objects) hash of commit object (hash_base) and path (file_name).

Signed-off-by: Jakub Narebski <jnareb@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
gitweb/gitweb.perl

index b706f7435c6e9242f6778a7cdc38a20d5bc3de8e..d3816b88412262ce4723d3f50679a6d12e6b486a 100755 (executable)
@@ -434,6 +434,7 @@ my %actions = (
        "tags" => \&git_tags,
        "tree" => \&git_tree,
        "snapshot" => \&git_snapshot,
+       "object" => \&git_object,
        # those below don't need $project
        "opml" => \&git_opml,
        "project_list" => \&git_project_list,
@@ -3619,6 +3620,53 @@ sub git_commit {
        git_footer_html();
 }
 
+sub git_object {
+       # object is defined by:
+       # - hash or hash_base alone
+       # - hash_base and file_name
+       my $type;
+
+       # - hash or hash_base alone
+       if ($hash || ($hash_base && !defined $file_name)) {
+               my $object_id = $hash || $hash_base;
+
+               my $git_command = git_cmd_str();
+               open my $fd, "-|", "$git_command cat-file -t $object_id 2>/dev/null"
+                       or die_error('404 Not Found', "Object does not exist");
+               $type = <$fd>;
+               chomp $type;
+               close $fd
+                       or die_error('404 Not Found', "Object does not exist");
+
+       # - hash_base and file_name
+       } elsif ($hash_base && defined $file_name) {
+               $file_name =~ s,/+$,,;
+
+               system(git_cmd(), "cat-file", '-e', $hash_base) == 0
+                       or die_error('404 Not Found', "Base object does not exist");
+
+               # here errors should not hapen
+               open my $fd, "-|", git_cmd(), "ls-tree", $hash_base, "--", $file_name
+                       or die_error(undef, "Open git-ls-tree failed");
+               my $line = <$fd>;
+               close $fd;
+
+               #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa  panic.c'
+               unless ($line && $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t/) {
+                       die_error('404 Not Found', "File or directory for given base does not exist");
+               }
+               $type = $2;
+               $hash = $3;
+       } else {
+               die_error('404 Not Found', "Not enough information to find object");
+       }
+
+       print $cgi->redirect(-uri => href(action=>$type, -full=>1,
+                                         hash=>$hash, hash_base=>$hash_base,
+                                         file_name=>$file_name),
+                            -status => '302 Found');
+}
+
 sub git_blobdiff {
        my $format = shift || 'html';