Merge branch 'master' of git://github.com/bobtfish/Gitalist
[catagits/Gitalist.git] / lib / Gitalist / Git / Object / Commit.pm
index 752b930..817c99f 100644 (file)
@@ -8,7 +8,6 @@ class Gitalist::Git::Object::Commit
         use MooseX::Types::Common::String qw/NonEmptySimpleStr/;
         use Moose::Autobox;
         use List::MoreUtils qw/any zip/;
-        use Gitalist::Util qw(to_utf8);
         our $SHA1RE = qr/[0-9a-fA-F]{40}/;
 
         has '+type' => ( default => 'commit' );
@@ -80,18 +79,6 @@ class Gitalist::Git::Object::Commit
             return \@difftree, [$self->_parse_diff(@out)];
         }
 
-method snapshot ( NonEmptySimpleStr $format ) {
-#    return unless (qw/tar zip/->any($format));
-    my $name = $self->project->name;
-    $name =~ s,([^/])/*\.git$,$1,;
-    my $filename = to_utf8($name);
-    $filename .= "-$self->sha1.$format";
-    $name =~ s/\047/\047\\\047\047/g;
-
-    my @cmd = ('archive', "--format=$format", "--prefix=$name", $self->sha1);
-    return $self->_run_cmd_fh(@cmd);
-}
-
         ## 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 --
@@ -153,4 +140,70 @@ method snapshot ( NonEmptySimpleStr $format ) {
             return @ret;
         }
 
+
+  # XXX A prime candidate for caching.
+  method blame ( NonEmptySimpleStr $filename ) {
+    my @blameout = $self->_run_cmd_list(
+      blame => '-p', $self->sha1, '--', $filename
+    );
+
+    my(%commitdata, @filedata);
+    while(defined(local $_ = shift @blameout)) {
+      my ($sha1, $orig_lineno, $lineno, $group_size) =
+        /^([0-9a-f]{40}) (\d+) (\d+)(?: (\d+))?$/;
+
+      $commitdata{$sha1} = {}
+        unless exists $commitdata{$sha1};
+
+      my $commit = $commitdata{$sha1};
+      my $line;
+      until(($line = shift @blameout) =~ s/^\t//) {
+        $commit->{$1} = $2
+         if $line =~ /^(\S+) (.*)/;
+      }
+
+      unless(exists $commit->{author_dt}) {
+        for my $t (qw/author committer/) {
+          my $dt = DateTime->from_epoch(epoch => $commit->{"$t-time"});
+          $dt->set_time_zone($commit->{"$t-tz"});
+          $commit->{"$t\_dt"} = $dt;
+        }
+      }
+
+      push @filedata, {
+        line => $line,
+        commit => { sha1 => $sha1, %$commit },
+        meta => {
+          orig_lineno => $orig_lineno,
+          lineno => $lineno,
+          ( $group_size ? (group_size => $group_size) : () ),
+        },
+      };
     }
+
+    return \@filedata;
+  }
+}
+
+
+1;
+
+__END__
+
+=head1 NAME
+
+Gitalist::Git::Object::Commit
+
+=head1 DESCRIPTION
+
+Gitalist::Git::Object::Commit.
+
+=head1 AUTHORS
+
+See L<Gitalist> for authors.
+
+=head1 LICENSE
+
+See L<Gitalist> for the license.
+
+=cut