Merge branch 'aesthetics'
Dan Brook [Wed, 18 Nov 2009 13:06:30 +0000 (13:06 +0000)]
Conflicts:
lib/Gitalist/Controller/Root.pm

13 files changed:
lib/Gitalist/Controller/Root.pm
lib/Gitalist/Git/Object.pm
lib/Gitalist/Git/Object/Blob.pm [new file with mode: 0644]
lib/Gitalist/Git/Object/Commit.pm [new file with mode: 0644]
lib/Gitalist/Git/Object/HasTree.pm [new file with mode: 0644]
lib/Gitalist/Git/Object/Tag.pm [new file with mode: 0644]
lib/Gitalist/Git/Object/Tree.pm [new file with mode: 0644]
lib/Gitalist/Git/Project.pm
root/search_help.tt2 [new file with mode: 0644]
t/01app.t
t/02git_object.t
t/02git_project.t
t/03legacy_uri.t

index 83116c9..dfb43e3 100644 (file)
@@ -397,6 +397,11 @@ sub search : Local {
   );
 }
 
+sub search_help : Local {
+    my ($self, $c) = @_;
+    $c->stash(template => 'search_help.tt2');
+}
+
 sub atom : Local {
   my($self, $c) = @_;
 
@@ -430,19 +435,20 @@ sub atom : Local {
   $c->response->content_type('application/atom+xml')
 }
 
-sub search_help : Local {
-    # FIXME - implement search_help
-    Carp::croak "Not implemented.";
-}
-
 sub rss : Local {
     # FIXME - implement rss
     Carp::croak "Not implemented.";
 }
 
 sub patch : Local {
-    # FIXME - implement patches
-    Carp::croak "Not implemented.";
+    my ($self, $c) = @_;
+    my $commit = $self->_get_object($c);
+    my $parent = $c->req->param('hp') || undef;
+    my $patch = $commit->patch( $parent );
+    $c->response->body($patch);
+    $c->response->content_type('text/plain');
+    $c->response->status(200);
+
 }
 
 sub patches : Local {
index 8142c64..bec7c03 100644 (file)
@@ -5,9 +5,6 @@ class Gitalist::Git::Object {
     use MooseX::Types::Moose qw/Str Int Bool Maybe ArrayRef/;
     use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
     use File::Stat::ModeString qw/mode_to_string/;
-    use List::MoreUtils qw/any zip/;
-
-    our $SHA1RE = qr/[0-9a-fA-F]{40}/;
 
     # project and sha1 are required initargs
     has project => ( isa => 'Gitalist::Git::Project',
@@ -24,39 +21,24 @@ class Gitalist::Git::Object {
                   required => 1,
                   is => 'ro' );
 
+    has type => ( isa => NonEmptySimpleStr,
+                  is => 'ro',
+                  required => 1 );
+
     has $_ => ( isa => NonEmptySimpleStr,
                 required => 1,
                 is => 'ro',
                 lazy_build => 1 )
-        for qw/type modestr size/;
+        for qw/modestr size/;
 
     has _gpp_obj => ( isa => 'Git::PurePerl::Object',
                       required => 1,
                       is => 'ro',
                       lazy_build => 1,
-                      handles => [ 'parents',
-                                   'parent_sha1',
-                                   'author',
-                                   'authored_time',
-                                   'committer',
-                                   'committed_time',
+                      handles => [ 'content',
                                ],
                   );
 
-    # This feels wrong, but current templates assume
-    # these attributes are present on every object.
-    foreach my $key (qw/tree_sha1 comment content/) {
-        has $key => ( isa => Str,
-                      required => 1,
-                      is => 'ro',
-                      lazy_build => 1,
-                  );
-        method "_build_$key" {
-            confess("Object can't " . $key) unless $self->_gpp_obj->can($key);
-            return $self->_gpp_obj->$key;
-        }
-    }
-
     # objects can't determine their mode or filename
     has file => ( isa => NonEmptySimpleStr,
                   required => 0,
@@ -66,139 +48,19 @@ class Gitalist::Git::Object {
                   default => 0,
                   is => 'ro' );
 
-    has tree => ( isa => 'ArrayRef[Gitalist::Git::Object]',
-                  required => 0,
-                  is => 'ro',
-                  lazy_build => 1 );
-
-    method BUILD { $self->$_() for qw/_gpp_obj type size modestr/ }
-
-    method _build_tree {
-        confess("Can't list_tree on a blob object.")
-            if $self->type eq 'blob';
-        my $output = $self->_run_cmd(qw/ls-tree -z/, $self->sha1);
-        return unless defined $output;
-
-        my @ret;
-        for my $line (split /\0/, $output) {
-            my ($mode, $type, $object, $file) = split /\s+/, $line, 4;
-            push @ret, Gitalist::Git::Object->new( mode => oct $mode,
-                                    type => $type,
-                                    sha1 => $object,
-                                    file => $file,
-                                    project => $self->project,
-                                  );
-        }
-        return \@ret;
-    }
-
-    method diff ( Maybe[Bool] :$patch?,
-                  Maybe[NonEmptySimpleStr] :$parent?,
-                  Maybe[NonEmptySimpleStr] :$file?
-              ) {
-        # Use parent if specifed, else take the parent from the commit
-        # if there is only one, otherwise it was a merge commit.
-        $parent = $parent
-            ? $parent
-                : $self->parents <= 1
-                    ? $self->parent_sha1
-                        : '-c';
-        my @etc = (
-            ( $file  ? ('--', $file) : () ),
-        );
-
-        my @out = $self->_raw_diff(
-            ( $patch ? '--patch-with-raw' : () ),
-            ( $parent ? $parent : () ),
-            $self->sha1, @etc,
-        );
-
-        # XXX Yes, there is much wrongness having _parse_diff_tree be destructive.
-        my @difftree = $self->_parse_diff_tree(\@out);
-
-        return \@difftree
-            unless $patch;
-
-        # The blank line between the tree and the patch.
-        shift @out;
-
-        # XXX And no I'm not happy about having diff return tree + patch.
-        return \@difftree, [$self->_parse_diff(@out)];
-    }
+    method BUILD { $self->$_() for qw/_gpp_obj size modestr/ }
 
 ## Private methods
-    # gitweb uses the following sort of command for diffing merges:
-    # /home/dbrook/apps/bin/git --git-dir=/home/dbrook/dev/app/.git diff-tree -r -M --no-commit-id --patch-with-raw --full-index --cc 316cf158df3f6207afbae7270bcc5ba0 --
-    # and for regular diffs
-    # /home/dbrook/apps/bin/git --git-dir=/home/dbrook/dev/app/.git diff-tree -r -M --no-commit-id --patch-with-raw --full-index 2e3454ca0749641b42f063730b0090e1 316cf158df3f6207afbae7270bcc5ba0 --
-    method _raw_diff (@args) {
-        return $self->_run_cmd_list(
-            qw(diff-tree -r -M --no-commit-id --full-index),
-            @args
-        );
-    }
-
-    method _parse_diff_tree ($diff) {
-        my @keys = qw(modesrc modedst sha1src sha1dst status src dst);
-        my @ret;
-        while (@$diff and $diff->[0] =~ /^:\d+/) {
-            my $line = shift @$diff;
-            # see. man git-diff-tree for more info
-            # mode src, mode dst, sha1 src, sha1 dst, status, src[, dst]
-            my @vals = $line =~ /^:(\d+) (\d+) ($SHA1RE) ($SHA1RE) ([ACDMRTUX]\d*)\t([^\t]+)(?:\t([^\n]+))?$/;
-            my %line = zip @keys, @vals;
-            # Some convenience keys
-            $line{file}   = $line{src};
-            $line{sha1}   = $line{sha1dst};
-            $line{is_new} = $line{sha1src} =~ /^0+$/
-               if $line{sha1src};
-            @line{qw/status sim/} = $line{status} =~ /(R)(\d+)/
-                if $line{status} =~ /^R/;
-            push @ret, \%line;
-        }
-
-        return @ret;
-    }
-
-    method _parse_diff (@diff) {
-        my @ret;
-        for (@diff) {
-            # This regex is a little pathological.
-            if (m{^diff --git (a/(.*?)) (b/\2)}) {
-                push @ret, {
-                    head => $_,
-                    a    => $1,
-                    b    => $3,
-                    file => $2,
-                    diff => '',
-                };
-                next;
-            }
-
-            if (/^index (\w+)\.\.(\w+) (\d+)$/) {
-                @{$ret[-1]}{qw(index src dst mode)} = ($_, $1, $2, $3);
-                next
-            }
-
-            # XXX Somewhat hacky. Ahem.
-            $ret[@ret ? -1 : 0]{diff} .= "$_\n";
-        }
-
-        return @ret;
-    }
-
 
 ## Builders
-method _build__gpp_obj {
+    method _build__gpp_obj {
         return $self->_get_gpp_object($self->sha1)
     }
 
-    foreach my $key (qw/ type size /) {
-        method "_build_$key" {
-            my $v = $self->_cat_file_with_flag(substr($key, 0, 1));
-            chomp($v);
-            return $v;
-        }
+    method "_build_size" {
+        my $v = $self->_cat_file_with_flag('s');
+        chomp($v);
+        return $v;
     }
 
     method _build_modestr {
diff --git a/lib/Gitalist/Git/Object/Blob.pm b/lib/Gitalist/Git/Object/Blob.pm
new file mode 100644 (file)
index 0000000..4629c0b
--- /dev/null
@@ -0,0 +1,6 @@
+package Gitalist::Git::Object::Blob;
+use MooseX::Declare;
+
+class Gitalist::Git::Object::Blob extends Gitalist::Git::Object {
+        has '+type' => ( default => 'blob' );
+}
diff --git a/lib/Gitalist/Git/Object/Commit.pm b/lib/Gitalist/Git/Object/Commit.pm
new file mode 100644 (file)
index 0000000..c521b5a
--- /dev/null
@@ -0,0 +1,130 @@
+package Gitalist::Git::Object::Commit;
+use MooseX::Declare;
+
+class Gitalist::Git::Object::Commit
+    extends Gitalist::Git::Object
+    with Gitalist::Git::Object::HasTree {
+        use MooseX::Types::Moose qw/Str Int Bool Maybe ArrayRef/;
+        use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
+        use List::MoreUtils qw/any zip/;
+        our $SHA1RE = qr/[0-9a-fA-F]{40}/;
+
+        has '+type' => ( default => 'commit' );
+        has '+_gpp_obj' => ( handles => [ 'comment',
+                                          'tree_sha1',
+                                          'committer',
+                                          'committed_time',
+                                          'author',
+                                          'authored_time',
+                                          'parents',
+                                          'parent_sha1',
+                                          'parent_sha1s',
+                                      ],
+                         );
+
+        method patch ( Maybe[NonEmptySimpleStr] $parent? ) {
+            my @args = qw/format-patch --encoding=utf8 --stdout -1/;
+            my $refspec = $self->sha1;
+            if (defined $parent) {
+                push @args, '-n';
+                $refspec = $parent . '..' . $self->sha1;
+            }
+            push @args, '--root', $refspec;
+            my $out = $self->_run_cmd( @args );
+            return $out;
+        }
+
+        method diff ( Maybe[Bool] :$patch?,
+                       Maybe[NonEmptySimpleStr] :$parent?,
+                       Maybe[NonEmptySimpleStr] :$file?
+                   ) {
+            $parent = $parent
+                ? $parent
+                    : $self->parents <= 1
+                        ? $self->parent_sha1
+                            : '-c';
+            my @etc = (
+                ( $file  ? ('--', $file) : () ),
+            );
+
+            my @out = $self->_raw_diff(
+                ( $patch ? '--patch-with-raw' : () ),
+                ( $parent ? $parent : () ),
+                $self->sha1, @etc,
+            );
+
+            # XXX Yes, there is much wrongness having _parse_diff_tree be destructive.
+            my @difftree = $self->_parse_diff_tree(\@out);
+
+            return \@difftree
+                unless $patch;
+
+            # The blank line between the tree and the patch.
+            shift @out;
+
+            # XXX And no I'm not happy about having diff return tree + patch.
+            return \@difftree, [$self->_parse_diff(@out)];
+        }
+
+        ## Private methods
+        # gitweb uses the following sort of command for diffing merges:
+        # /home/dbrook/apps/bin/git --git-dir=/home/dbrook/dev/app/.git diff-tree -r -M --no-commit-id --patch-with-raw --full-index --cc 316cf158df3f6207afbae7270bcc5ba0 --
+        # and for regular diffs
+        # /home/dbrook/apps/bin/git --git-dir=/home/dbrook/dev/app/.git diff-tree -r -M --no-commit-id --patch-with-raw --full-index 2e3454ca0749641b42f063730b0090e1 316cf158df3f6207afbae7270bcc5ba0 --
+        method _raw_diff (@args) {
+            return $self->_run_cmd_list(
+                qw(diff-tree -r -M --no-commit-id --full-index),
+                @args
+            );
+        }
+
+        method _parse_diff_tree ($diff) {
+            my @keys = qw(modesrc modedst sha1src sha1dst status src dst);
+            my @ret;
+            while (@$diff and $diff->[0] =~ /^:\d+/) {
+                my $line = shift @$diff;
+                # see. man git-diff-tree for more info
+                # mode src, mode dst, sha1 src, sha1 dst, status, src[, dst]
+                my @vals = $line =~ /^:(\d+) (\d+) ($SHA1RE) ($SHA1RE) ([ACDMRTUX]\d*)\t([^\t]+)(?:\t([^\n]+))?$/;
+                my %line = zip @keys, @vals;
+                # Some convenience keys
+                $line{file}   = $line{src};
+                $line{sha1}   = $line{sha1dst};
+                $line{is_new} = $line{sha1src} =~ /^0+$/
+                    if $line{sha1src};
+                @line{qw/status sim/} = $line{status} =~ /(R)(\d+)/
+                    if $line{status} =~ /^R/;
+                push @ret, \%line;
+            }
+
+            return @ret;
+        }
+
+        method _parse_diff (@diff) {
+            my @ret;
+            for (@diff) {
+                # This regex is a little pathological.
+                if (m{^diff --git (a/(.*?)) (b/\2)}) {
+                    push @ret, {
+                        head => $_,
+                        a    => $1,
+                        b    => $3,
+                        file => $2,
+                        diff => '',
+                    };
+                    next;
+                }
+
+                if (/^index (\w+)\.\.(\w+) (\d+)$/) {
+                    @{$ret[-1]}{qw(index src dst mode)} = ($_, $1, $2, $3);
+                    next
+                }
+
+                # XXX Somewhat hacky. Ahem.
+                $ret[@ret ? -1 : 0]{diff} .= "$_\n";
+            }
+
+            return @ret;
+        }
+
+    }
diff --git a/lib/Gitalist/Git/Object/HasTree.pm b/lib/Gitalist/Git/Object/HasTree.pm
new file mode 100644 (file)
index 0000000..5974af7
--- /dev/null
@@ -0,0 +1,30 @@
+package Gitalist::Git::Object::HasTree;
+use MooseX::Declare;
+
+role Gitalist::Git::Object::HasTree {
+    has tree => ( isa => 'ArrayRef[Gitalist::Git::Object]',
+                  required => 0,
+                  is => 'ro',
+                  lazy_build => 1 );
+
+
+## Builders
+    method _build_tree {
+        my $output = $self->_run_cmd(qw/ls-tree -z/, $self->sha1);
+        return unless defined $output;
+
+        my @ret;
+        for my $line (split /\0/, $output) {
+            my ($mode, $type, $object, $file) = split /\s+/, $line, 4;
+            my $class = 'Gitalist::Git::Object::' . ucfirst($type);
+            push @ret, $class->new( mode => oct $mode,
+                                    type => $type,
+                                    sha1 => $object,
+                                    file => $file,
+                                    project => $self->project,
+                                  );
+        }
+        return \@ret;
+    }
+
+}
diff --git a/lib/Gitalist/Git/Object/Tag.pm b/lib/Gitalist/Git/Object/Tag.pm
new file mode 100644 (file)
index 0000000..397f3bb
--- /dev/null
@@ -0,0 +1,13 @@
+package Gitalist::Git::Object::Tag;
+use MooseX::Declare;
+
+class Gitalist::Git::Object::Tag extends Gitalist::Git::Object {
+    has '+type' => ( default => 'tag' );
+    has '+_gpp_obj' => ( handles => [ 'object',
+                                      'tag',
+                                      'tagger',
+                                      'tagged_time',
+                                  ],
+                         );
+
+}
diff --git a/lib/Gitalist/Git/Object/Tree.pm b/lib/Gitalist/Git/Object/Tree.pm
new file mode 100644 (file)
index 0000000..0d05689
--- /dev/null
@@ -0,0 +1,11 @@
+package Gitalist::Git::Object::Tree;
+use MooseX::Declare;
+
+class Gitalist::Git::Object::Tree
+    extends Gitalist::Git::Object
+    with Gitalist::Git::Object::HasTree {
+        has '+type' => ( default => 'tree' );
+        has '+_gpp_obj' => ( handles => [ 'directory_entries',
+                                      ],
+                         );
+    }
index c7b092d..5129f12 100644 (file)
@@ -26,7 +26,10 @@ class Gitalist::Git::Project with Gitalist::Git::HasUtils {
     use MooseX::Types::Moose qw/Str Maybe Bool HashRef ArrayRef/;
     use List::MoreUtils qw/any zip/;
     use DateTime;
-    use aliased 'Gitalist::Git::Object';
+    use Gitalist::Git::Object::Blob;
+    use Gitalist::Git::Object::Tree;
+    use Gitalist::Git::Object::Commit;
+    use Gitalist::Git::Object::Tag;
 
     our $SHA1RE = qr/[0-9a-fA-F]{40}/;
 
@@ -157,16 +160,20 @@ Each item is a L<Gitalist::Git::Object>.
 
 =head2 get_object ($sha1)
 
-Return a L<Gitalist::Git::Object> for the given sha1.
+Return an appropriate subclass of L<Gitalist::Git::Object> for the given sha1.
 
 =cut
     method get_object (NonEmptySimpleStr $sha1) {
         unless ( $self->_is_valid_rev($sha1) ) {
             $sha1 = $self->head_hash($sha1);
         }
-        return Object->new(
+        my $type = $self->run_cmd('cat-file', '-t', $sha1);
+        chomp($type);
+        my $class = 'Gitalist::Git::Object::' . ucfirst($type);
+        $class->new(
             project => $self,
             sha1 => $sha1,
+            type => $type,
         );
     }
 
diff --git a/root/search_help.tt2 b/root/search_help.tt2
new file mode 100644 (file)
index 0000000..c23a414
--- /dev/null
@@ -0,0 +1,28 @@
+[% PROCESS 'nav/actions.tt2' object = head %]
+
+<p><strong>Pattern</strong> is by default a normal string that is matched precisely (but without
+regard to case, except in the case of pickaxe). However, when you check the <em>re</em> checkbox,
+the pattern entered is recognized as the POSIX extended
+<a href="http://en.wikipedia.org/wiki/Regular_expression">regular expression</a> (also case
+insensitive).</p>
+<dl>
+<dt><b>commit</b></dt>
+<dd>The commit messages and authorship information will be scanned for the given pattern.</dd>
+
+<dt><b>grep</b></dt>
+<dd>All files in the currently selected tree (HEAD unless you are explicitly browsing
+    a different one) are searched for the given pattern. On large trees, this search can take
+a while and put some strain on the server, so please use it with some consideration. Note that
+due to git-grep peculiarity, currently if regexp mode is turned off, the matches are
+case-sensitive.</dd>
+<dt><b>author</b></dt>
+<dd>Name and e-mail of the change author and date of birth of the patch will be scanned for the given pattern.</dd>
+<dt><b>committer</b></dt>
+<dd>Name and e-mail of the committer and date of commit will be scanned for the given pattern.</dd>
+<dt><b>pickaxe</b></dt>
+<dd>All commits that caused the string to appear or disappear from any file (changes that
+added, removed or "modified" the string) will be listed. This search can take a while and
+takes a lot of strain on the server, so please use it wisely. Note that since you may be
+interested even in changes just changing the case as well, this search is case sensitive.</dd>
+</dl>
+
index 9ebc7a4..e4d270c 100644 (file)
--- a/t/01app.t
+++ b/t/01app.t
@@ -31,6 +31,9 @@ is request('/summary?p=DoesNotExist')->code, 404,
   test('/search', 'h=36c6c6708b8360d7023e8a1649c45bcf9b3bd818&f=&type=commit&text=added');
   test('/blobdiff', 'f=file1;h=5716ca5987cbf97d6bb54920bea6adde242d87e6;hp=257cc5642cb1a054f08cc83f2d943e56fd3ebe99;hb=refs/heads/master;hpb=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
   test('/blob', 'f=dir1/file2;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
+  test('/patch');
+  test('/patch', 'h=3f7567c7bdf7e7ebf410926493b92d398333116e');
+  test('/patch', 'h=3f7567c7bdf7e7ebf410926493b92d398333116e;hp=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
 }
 
 done_testing;
index bc1a544..d722bb0 100644 (file)
@@ -11,16 +11,21 @@ my $project = Gitalist::Git::Project->new(
     dir("$Bin/lib/repositories/repo1"),
 );
 
-BEGIN { use_ok 'Gitalist::Git::Object' }
+BEGIN {
+    use_ok 'Gitalist::Git::Object::Tree';
+    use_ok 'Gitalist::Git::Object::Blob';
+    use_ok 'Gitalist::Git::Object::Commit';
+    use_ok 'Gitalist::Git::Object::Tag';
+    }
 
-my $object = Gitalist::Git::Object->new(
+my $object = Gitalist::Git::Object::Tree->new(
     project => $project,
     sha1 => '729a7c3f6ba5453b42d16a43692205f67fb23bc1',
     type => 'tree',
     file => 'dir1',
     mode => 16384,
 );
-isa_ok($object, 'Gitalist::Git::Object');
+isa_ok($object, 'Gitalist::Git::Object::Tree', 'tree object');
 is($object->sha1,'729a7c3f6ba5453b42d16a43692205f67fb23bc1', 'sha1 is correct');
 is($object->type, 'tree', 'type is correct');
 is($object->file, 'dir1', 'file is correct');
@@ -29,11 +34,11 @@ is($object->modestr, 'd---------', "modestr is correct" );
 is($object->size, 33, "size is correct");
 
 # Create object from sha1.
-my $obj2 = Gitalist::Git::Object->new(
+my $obj2 = Gitalist::Git::Object::Blob->new(
     project => $project,
     sha1 => '5716ca5987cbf97d6bb54920bea6adde242d87e6',
 );
-isa_ok($obj2, 'Gitalist::Git::Object');
+isa_ok($obj2, 'Gitalist::Git::Object::Blob', 'blob object');
 is($obj2->sha1,'5716ca5987cbf97d6bb54920bea6adde242d87e6', 'sha1 is correct');
 is($obj2->type, 'blob', 'type is correct');
 is($obj2->mode, 0, 'mode is correct');
@@ -47,11 +52,11 @@ dies_ok {
     print $obj2->comment;
 } 'comment is an empty string';
 
-my $commit_obj = Gitalist::Git::Object->new(
+my $commit_obj = Gitalist::Git::Object::Commit->new(
     project => $project,
     sha1 => '3f7567c7bdf7e7ebf410926493b92d398333116e',
 );
-isa_ok($commit_obj, 'Gitalist::Git::Object', "commit object type correct");
+isa_ok($commit_obj, 'Gitalist::Git::Object::Commit', "commit object");
 my ($tree, $patch) = $commit_obj->diff(
     parent => undef,
     file => undef,
@@ -72,3 +77,24 @@ is($patch->{diff}, '--- a/file1
 +bar
 ', 'patch->{diff} is correct');
 is($patch->{dst}, '5716ca5987cbf97d6bb54920bea6adde242d87e6', 'patch->{dst} is correct');
+
+is($commit_obj->patch, 'From 3f7567c7bdf7e7ebf410926493b92d398333116e Mon Sep 17 00:00:00 2001
+From: Florian Ragwitz <rafl@debian.org>
+Date: Tue, 6 Mar 2007 20:39:45 +0100
+Subject: [PATCH] bar
+
+---
+ file1 |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/file1 b/file1
+index 257cc56..5716ca5 100644
+--- a/file1
++++ b/file1
+@@ -1 +1 @@
+-foo
++bar
+-- 
+1.6.4.2
+
+', 'commit_obj->patch is correct');
index 4c03933..c59b77e 100644 (file)
@@ -39,14 +39,18 @@ is(scalar $proj->list_tree, 2, 'expected number of entries in tree');
 isa_ok(($proj->list_tree)[1], 'Gitalist::Git::Object');
 
 # Return an ::Object from a sha1
-my $obj1 = $proj->get_object('5716ca5987cbf97d6bb54920bea6adde242d87e6');
-isa_ok($obj1, 'Gitalist::Git::Object');
+my $obj1 = $proj->get_object('729a7c3f6ba5453b42d16a43692205f67fb23bc1');
+isa_ok($obj1, 'Gitalist::Git::Object::Tree');
 
 my $hbp_sha1 = $proj->hash_by_path('36c6c6708b8360d7023e8a1649c45bcf9b3bd818', 'dir1/file2');
 my $obj2 = $proj->get_object($hbp_sha1);
+isa_ok($obj2, 'Gitalist::Git::Object::Blob');
 is($obj2->type, 'blob', 'hash_by_path obj is a file');
 is($obj2->content, "foo\n", 'hash_by_path obj is a file');
 
+my $obj3 = $proj->get_object($proj->head_hash);
+isa_ok($obj3, 'Gitalist::Git::Object::Commit');
+
 like($proj->head_hash('HEAD'), qr/^([0-9a-fA-F]{40})$/, 'head_hash');
 
 {
index 62c026d..a981d57 100644 (file)
@@ -124,24 +124,21 @@ test('/', 'a=log;h=HEAD');
 test('/', 'a=log;h=master');
 test('/', 'a=log;h=refs/heads/master');
 
-TODO: {
-    local $TODO = "Action: patch is not yet implemented.";
-    test('/', 'a=patch');
-    test('/', 'a=patch;h=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
-    test('/', 'a=patch;h=36c6c6708b8360d7023e8a1649c45bcf9b3bd818;hp=3f7567c7bdf7e7ebf410926493b92d398333116e');
-    test('/', 'a=patch;h=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
-    test('/', 'a=patch;h=3f7567c7bdf7e7ebf410926493b92d398333116e');
-    test('/', 'a=patch;h=3f7567c7bdf7e7ebf410926493b92d398333116e;hp=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
-    test('/', 'a=patch;h=HEAD');
-    test('/', 'a=patch;h=HEAD;hp=3f7567c7bdf7e7ebf410926493b92d398333116e');
-    test('/', 'a=patch;h=master');
-    test('/', 'a=patch;h=master;hp=3f7567c7bdf7e7ebf410926493b92d398333116e');
-    test('/', 'a=patch;h=refs/heads/master');
-    test('/', 'a=patch;h=refs/heads/master;hp=3f7567c7bdf7e7ebf410926493b92d398333116e');
-    test('/', 'a=patch;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
-    test('/', 'a=patch;hb=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
-    test('/', 'a=patch;hb=3f7567c7bdf7e7ebf410926493b92d398333116e');
-}
+test('/', 'a=patch');
+test('/', 'a=patch;h=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
+test('/', 'a=patch;h=36c6c6708b8360d7023e8a1649c45bcf9b3bd818;hp=3f7567c7bdf7e7ebf410926493b92d398333116e');
+test('/', 'a=patch;h=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
+test('/', 'a=patch;h=3f7567c7bdf7e7ebf410926493b92d398333116e');
+test('/', 'a=patch;h=3f7567c7bdf7e7ebf410926493b92d398333116e;hp=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
+test('/', 'a=patch;h=HEAD');
+test('/', 'a=patch;h=HEAD;hp=3f7567c7bdf7e7ebf410926493b92d398333116e');
+test('/', 'a=patch;h=master');
+test('/', 'a=patch;h=master;hp=3f7567c7bdf7e7ebf410926493b92d398333116e');
+test('/', 'a=patch;h=refs/heads/master');
+test('/', 'a=patch;h=refs/heads/master;hp=3f7567c7bdf7e7ebf410926493b92d398333116e');
+test('/', 'a=patch;hb=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');
+test('/', 'a=patch;hb=3bc0634310b9c62222bb0e724c11ffdfb297b4ac');
+test('/', 'a=patch;hb=3f7567c7bdf7e7ebf410926493b92d398333116e');
 
 TODO: {
     local $TODO = "Action: patches is not yet implemented.";
@@ -154,10 +151,7 @@ TODO: {
     test('/', 'a=patches;h=refs/heads/master');
 }
 
-TODO: {
-    local $TODO = "Action: search_help is not yet implemented.";
-    test('/', 'a=search_help');
-}
+test('/', 'a=search_help');
 
 test('/', 'a=shortlog');
 test('/', 'a=shortlog;h=36c6c6708b8360d7023e8a1649c45bcf9b3bd818');