Showing 6 changed files with 142 additions and 189 deletions
+1 -1
lib/Gitprep.pm
... ...
@@ -62,7 +62,7 @@ sub startup {
62 62
   $r->get('/:user/:project')->to('#project');
63 63
   
64 64
   # Commit
65
-  $r->get('/:user/:project/commit/:id')->to('#commit');
65
+  $r->get('/:user/:project/commit/:diff')->to('#commitdiff');
66 66
   
67 67
   # Commits
68 68
   $r->get('/:user/:project/commits/:rev', {id => 'HEAD'})->to('#commits');
+23
lib/Gitprep/Git.pm
... ...
@@ -653,6 +653,29 @@ sub latest_commit_log {
653 653
   return $commit_log;
654 654
 }
655 655
 
656
+sub parse_blobdiff_lines {
657
+  my ($self, $lines_raw) = @_;
658
+  
659
+  # Parse
660
+  my @lines;
661
+  for my $line (@$lines_raw) {
662
+    $line = $self->dec($line);
663
+    chomp $line;
664
+    my $class;
665
+    
666
+    if ($line =~ /^diff \-\-git /) { $class = 'diff header' }
667
+    elsif ($line =~ /^index /) { $class = 'diff extended_header' }
668
+    elsif ($line =~ /^\+/) { $class = 'diff to_file' }
669
+    elsif ($line =~ /^\-/) { $class = 'diff from_file' }
670
+    elsif ($line =~ /^\@\@/) { $class = 'diff chunk_header' }
671
+    elsif ($line =~ /^Binary files/) { $class = 'diff binary_file' }
672
+    else { $class = 'diff' }
673
+    push @lines, {value => $line, class => $class};
674
+  }
675
+  
676
+  return \@lines;
677
+}
678
+
656 679
 sub parse_commit {
657 680
   my ($self, $project, $id) = @_;
658 681
   
-177
lib/Gitprep/Main.pm
... ...
@@ -70,126 +70,6 @@ sub blobdiff {
70 70
   }
71 71
 }
72 72
 
73
-sub commitdiff {
74
-  my $self = shift;
75
-  
76
-  # Paramters
77
-  my $project_ns = $self->param('project');
78
-  my $project = "/$project_ns";
79
-  my $home_ns = dirname $project_ns;
80
-  my $home = "/$home_ns";
81
-  my $diff = $self->param('diff');
82
-  my ($from_id, $id) = $diff =~ /(.+)\.\.(.+)/;
83
-  $id = $diff unless defined $id;
84
-  
85
-  # Git
86
-  my $git = $self->app->git;
87
-  
88
-  # Commit
89
-  my $commit = $git->parse_commit($project, $id)
90
-    or croak 'Unknown commit object';
91
-  my $author_date
92
-    = $git->parse_date($commit->{author_epoch}, $commit->{author_tz});
93
-  my $committer_date
94
-    = $git->parse_date($commit->{committer_epoch}, $commit->{committer_tz});
95
-  $commit->{author_date} = $git->timestamp($author_date);
96
-  $commit->{committer_date} = $git->timestamp($committer_date);
97
-  $from_id = $commit->{parent} unless defined $from_id;
98
-  
99
-  # Plain text
100
-  if ($self->param('plain')) {
101
-    # Get blob diffs (command "git diff-tree")
102
-    my @cmd = ($git->cmd($project), 'diff-tree', '-r', '-M',
103
-        '-p', $from_id, $id, '--');
104
-    open my $fh, '-|', @cmd
105
-      or croak 'Open git-diff-tree failed';
106
-
107
-    # Content
108
-    my $content = do { local $/; <$fh> };
109
-    my $content_disposition .= "inline; filename=$id";
110
-    
111
-    # Render
112
-    $self->res->headers->content_disposition($content_disposition);
113
-    $self->res->headers->content_type("text/plain;charset=" . $git->encoding);
114
-    $self->render_data($content);
115
-  }
116
-  
117
-  # HTML
118
-  else {
119
-    
120
-    # Diff tree
121
-    my $difftrees = $git->difftree($project,
122
-      $id, $commit->{parent}, $commit->{parents});
123
-    
124
-    # Get blob diffs (command "git diff-tree")
125
-    my @cmd = ($git->cmd($project), 'diff-tree', '-r', '-M',
126
-      '--no-commit-id', '--patch-with-raw', $from_id, $id, '--');
127
-    open my $fh, '-|', @cmd
128
-      or croak 'Open git-diff-tree failed';
129
-
130
-    # Parse output
131
-    my @blobdiffs;
132
-    while (my $line = $git->dec(scalar <$fh>)) {
133
-      
134
-      # Parse line
135
-      chomp $line;
136
-      my $diffinfo = $git->parse_difftree_raw_line($line);
137
-      my $from_file = $diffinfo->{from_file};
138
-      my $file = $diffinfo->{to_file};
139
-      
140
-      # Get blobdiff (command "git diff-tree")
141
-      my @cmd = ($git->cmd($project), 'diff-tree', '-r', '-M', '-p',
142
-        $from_id, $id, '--', (defined $from_file ? $from_file : ()), $file);
143
-      open my $fh_blobdiff, '-|', @cmd
144
-        or croak 'Open git-diff-tree failed';
145
-      my @lines = map { $git->dec($_) } <$fh>;
146
-      close $fh_blobdiff;
147
-      my $blobdiff = {
148
-        file => $file,
149
-        from_file => $from_file,
150
-        lines => $self->_parse_blobdiff_lines(\@lines)
151
-      };
152
-      
153
-      # Status
154
-      for my $difftree (@$difftrees) {
155
-        if ($difftree->{to_file} eq $file) {
156
-          $blobdiff->{status} = $difftree->{status};
157
-          last;
158
-        }
159
-      }
160
-      
161
-      push @blobdiffs, $blobdiff;
162
-    }
163
-
164
-    # References
165
-    my $refs = $git->references($project);
166
-    
167
-    # Render
168
-    $self->render(
169
-      'commitdiff',
170
-      home => $home,
171
-      home_ns => $home_ns,
172
-      project => $project,
173
-      project_ns => $project_ns,
174
-      from_id => $from_id,
175
-      id => $id,
176
-      commit => $commit,
177
-      difftrees => $difftrees,
178
-      blobdiffs => \@blobdiffs,
179
-      refs => $refs
180
-    );
181
-  }
182
-}
183
-
184
-sub _root_ns {
185
-  my $self = shift;
186
-  
187
-  my $root = $self->root;
188
-  $root =~ s/^\///;
189
-  
190
-  return $root;
191
-}
192
-
193 73
 sub snapshot {
194 74
   my $self = shift;
195 75
 
... ...
@@ -267,63 +147,6 @@ sub tag {
267 147
   );
268 148
 }
269 149
 
270
-sub _parse_blobdiff_lines {
271
-  my ($self, $lines_raw) = @_;
272
-  
273
-  # Git
274
-  my $git = $self->app->git;
275
-  
276
-  # Parse
277
-  my @lines;
278
-  for my $line (@$lines_raw) {
279
-    $line = $git->dec($line);
280
-    chomp $line;
281
-    my $class;
282
-    
283
-    if ($line =~ /^diff \-\-git /) { $class = 'diff header' }
284
-    elsif ($line =~ /^index /) { $class = 'diff extended_header' }
285
-    elsif ($line =~ /^\+/) { $class = 'diff to_file' }
286
-    elsif ($line =~ /^\-/) { $class = 'diff from_file' }
287
-    elsif ($line =~ /^\@\@/) { $class = 'diff chunk_header' }
288
-    elsif ($line =~ /^Binary files/) { $class = 'diff binary_file' }
289
-    else { $class = 'diff' }
290
-    push @lines, {value => $line, class => $class};
291
-  }
292
-  
293
-  return \@lines;
294
-}
295
-
296
-sub _parse_id_path {
297
-  my ($self, $project, $id_path) = @_;
298
-  
299
-  # Git
300
-  my $git = $self->app->git;
301
-  
302
-  # Parse id and path
303
-  my $refs = $git->references($project);
304
-  my $id;
305
-  my $path;
306
-  for my $rs (values %$refs) {
307
-    for my $ref (@$rs) {
308
-      $ref =~ s#^heads/##;
309
-      $ref =~ s#^tags/##;
310
-      if ($id_path =~ s#^\Q$ref(/|$)##) {
311
-        $id = $ref;
312
-        $path = $id_path;
313
-        last;
314
-      }      
315
-    }
316
-  }
317
-  unless (defined $id) {
318
-    if ($id_path =~ s#(^[^/]+)(/|$)##) {
319
-      $id = $1;
320
-      $path = $id_path;
321
-    }
322
-  }
323
-  
324
-  return ($id, $path);
325
-}
326
-
327 150
 sub _quote_command {
328 151
   my $self = shift;
329 152
   return join(' ',
+1 -1
templates/include/difftree.html.ep
... ...
@@ -1,5 +1,5 @@
1 1
 <table class="<%= @$parents > 1 ? 'combined' : 'diff_tree' %>"">
2
-
2
+  
3 3
   % my $has_header = @$difftrees && @$parents > 1 && stash('action') eq 'commitdiff';
4 4
   % if ($has_header) {
5 5
     <thead>
+1 -3
templates/main/blob.html.ep
... ...
@@ -2,12 +2,10 @@
2 2
   # API
3 3
   my $api = Gitprep::API->new($self);
4 4
   
5
-  # Parameter
5
+  # Parameters
6 6
   my $user = param('user');
7 7
   my $project = param('project');
8 8
   my $root_ns = $api->root_ns(config->{root});
9
-  
10
-  # Parameters
11 9
   my $rep_ns = "$root_ns/$user/$project.git";
12 10
   my $rep = "/$rep_ns";
13 11
   my $object = param('object');
+116 -7
templates/main/commitdiff.html.ep
... ...
@@ -1,19 +1,128 @@
1
+<%
2
+  use Gitprep::API;
3
+  
4
+  # API
5
+  my $api = Gitprep::API->new($self);
6
+  
7
+  # Paramters
8
+  my $project = param('project');
9
+  my $root_ns = $api->root_ns(config->{root});
10
+  my $rep_ns = "$root_ns/$user/$project.git";
11
+  my $rep = "/$rep_ns";
12
+  my $home_ns = $api->dirname($project);
13
+  my $home = "/$home_ns";
14
+  my $diff = param('diff');
15
+  my ($from_id, $id) = $diff =~ /(.+)\.\.(.+)/;
16
+  $id = $diff unless defined $id;
17
+  
18
+  # Git
19
+  my $git = app->git;
20
+  
21
+  # Commit
22
+  my $commit = $git->parse_commit($rep, $id)
23
+    or $api->croak('Unknown commit object');
24
+  my $author_date
25
+    = $git->parse_date($commit->{author_epoch}, $commit->{author_tz});
26
+  my $committer_date
27
+    = $git->parse_date($commit->{committer_epoch}, $commit->{committer_tz});
28
+  $commit->{author_date} = $git->timestamp($author_date);
29
+  $commit->{committer_date} = $git->timestamp($committer_date);
30
+  $from_id = $commit->{parent} unless defined $from_id;
31
+  
32
+  my $difftrees;
33
+  my $blobdiffs;
34
+
35
+  # Plain text
36
+  if ($self->param('plain')) {
37
+    # Get blob diffs (command "git diff-tree")
38
+    my @cmd = ($git->cmd($rep), 'diff-tree', '-r', '-M',
39
+        '-p', $from_id, $id, '--');
40
+    open my $fh, '-|', @cmd
41
+      or $api->croak('Open git-diff-tree failed');
42
+
43
+    # Content
44
+    my $content = do { local $/; <$fh> };
45
+    my $content_disposition .= "inline; filename=$id";
46
+    
47
+    # Render
48
+    $self->res->headers->content_disposition($content_disposition);
49
+    $self->res->headers->content_type("text/plain;charset=" . $git->encoding);
50
+    $self->render_data($content);
51
+  }
52
+  
53
+  # HTML
54
+  else {
55
+    
56
+    # Diff tree
57
+    $difftrees = $git->difftree($rep,
58
+      $id, $commit->{parent}, $commit->{parents});
59
+    
60
+    # Get blob diffs (command "git diff-tree")
61
+    my @cmd = ($git->cmd($rep), 'diff-tree', '-r', '-M',
62
+      '--no-commit-id', '--patch-with-raw', $from_id, $id, '--');
63
+    open my $fh, '-|', @cmd
64
+      or $api->croak('Open git-diff-tree failed');
65
+
66
+    # Parse output
67
+    while (my $line = $git->dec(scalar <$fh>)) {
68
+      
69
+      # Parse line
70
+      chomp $line;
71
+      my $diffinfo = $git->parse_difftree_raw_line($line);
72
+      my $from_file = $diffinfo->{from_file};
73
+      my $file = $diffinfo->{to_file};
74
+      
75
+      # Get blobdiff (command "git diff-tree")
76
+      my @cmd = ($git->cmd($rep), 'diff-tree', '-r', '-M', '-p',
77
+        $from_id, $id, '--', (defined $from_file ? $from_file : ()), $file);
78
+      open my $fh_blobdiff, '-|', @cmd
79
+        or $api->croak('Open git-diff-tree failed');
80
+      my @lines = map { $git->dec($_) } <$fh>;
81
+      close $fh_blobdiff;
82
+      my $blobdiff = {
83
+        file => $file,
84
+        from_file => $from_file,
85
+        lines => $git->parse_blobdiff_lines(\@lines)
86
+      };
87
+      
88
+      # Status
89
+      for my $difftree (@$difftrees) {
90
+        if ($difftree->{to_file} eq $file) {
91
+          $blobdiff->{status} = $difftree->{status};
92
+          last;
93
+        }
94
+      }
95
+      
96
+      push @$blobdiffs, $blobdiff;
97
+    }
98
+    
99
+    # Render
100
+    stash(
101
+      home => $home,
102
+      home_ns => $home_ns,
103
+      project => $project,
104
+      project => $project,
105
+      from_id => $from_id,
106
+      id => $id,
107
+      commit => $commit,
108
+    );
109
+  }
110
+%>
111
+
1 112
 % layout 'common';
113
+  %= include '/css/common';
2 114
   %= include '/include/header', title => 'Commit diff', project => $project;
3
-  %= include '/include/current_directory', home_ns => $home_ns, home => $home;
4
-  %= include '/include/page_navi', current => 'commitdiff', project_ns => $project_ns;
5 115
   <div class="page_nav">
6
-    <a href="<%= url_for('commitdiff_plain', project => $project_ns, diff => $commit->{id}) %>">
116
+    <a href="<%= url_for('commitdiff_plain', project => $project, diff => $commit->{id}) %>">
7 117
       Raw
8 118
     </a>
9 119
   </div>
10 120
   <div class="header">
11
-    <a class="title" href="<%= url_for('commit', project => $project_ns) %>">
121
+    <a class="title" href="<%= url_for('commit', project => $project) %>">
12 122
       <%= $commit->{title} %>
13 123
     </a>
14 124
   </div>
15 125
   <div class="title_text">
16
-    %= include 'include/refs', project_ns => $project_ns, commit => $commit, refs => $refs;
17 126
     <table class="object_header">
18 127
       <tr><td>Author</td><td><%= $commit->{author} %></td><td rowspan="2"></td></tr>
19 128
       <tr><td></td><td><%= $commit->{author_date} %></td></tr>
... ...
@@ -25,7 +134,7 @@
25 134
     <div class="list_head"></div>
26 135
 
27 136
     <%= include '/include/difftree', id => $commit->{id}, from_id => $commit->{parent},
28
-      difftrees => $difftrees, parents => $commit->{parents} %>
137
+      difftrees => $difftrees, parents => $commit->{parents}, project_ns => $project %>
29 138
 
30 139
     <div class="patchset">
31 140
       % for (my $i = 0; $i < @$blobdiffs; $i++) {
... ...
@@ -36,7 +145,7 @@
36 145
           % my $from_file = $blobdiff->{from_file};
37 146
           % $from_file = $file unless defined $from_file;
38 147
           % my $status = $blobdiff->{status};
39
-          %= include '/include/blobdiff_body', file => $file, from_file => $from_file, status => $status, lines => $blobdiff->{lines};
148
+          %= include '/include/blobdiff_body', file => $file, from_file => $from_file, status => $status, lines => $blobdiff->{lines}, project_ns => $project;
40 149
         </div>
41 150
       % }
42 151
     </div>