Newer Older
1819 lines | 42.732kb
renamed gitpub to gitprep
Yuki Kimoto authored on 2012-11-26
1
package Gitprep::Git;
copy gitweblite soruce code
root authored on 2012-11-23
2
use Mojo::Base -base;
3

            
4
use Carp 'croak';
cleanup
Yuki Kimoto authored on 2013-05-14
5
use Encode qw/encode decode/;
Supported specific character...
Tetsuya Hayashi authored on 2014-03-15
6
use Encode::Guess;
copy gitweblite soruce code
root authored on 2012-11-23
7
use Fcntl ':mode';
cleanup
Yuki Kimoto authored on 2013-05-14
8
use File::Basename qw/basename dirname/;
improved create repository f...
Yuki Kimoto authored on 2013-03-20
9
use File::Copy 'move';
cleanup
Yuki Kimoto authored on 2013-05-14
10
use File::Find 'find';
11
use File::Path qw/mkpath rmtree/;
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
12
use POSIX 'floor';
fix bug that in CGI reposito...
Yuki Kimoto authored on 2015-11-05
13
use Gitprep::Util;
added create repository feat...
Yuki Kimoto authored on 2013-03-18
14

            
15
# Attributes
16
has 'bin';
Renamed encoding to default_...
Tetsuya Hayashi authored on 2014-03-15
17
has default_encoding => 'UTF-8';
cleanup blob page
Yuki Kimoto authored on 2013-03-19
18
has text_exts => sub { ['txt'] };
add time zone system
Yuki Kimoto authored on 2014-03-08
19
has 'time_zone_second';
cleanup encoding
Yuki Kimoto authored on 2016-04-05
20
has 'app';
copy gitweblite soruce code
root authored on 2012-11-23
21

            
cleanup branch_status
Yuki Kimoto authored on 2016-04-16
22
sub rep_work_current_branch {
23
  my ($self, $user, $project) = @_;
cleanup
Yuki Kimoto authored on 2013-05-14
24
  
cleanup branch_status
Yuki Kimoto authored on 2016-04-16
25
  my @cmd = $self->cmd_work_rep($user, $project, 'rev-parse',  '--abbrev-ref', 'HEAD');
26
  
27
  open my $fh, '-|', @cmd
28
    or croak "Can't get current branch: @cmd";
29
  my $current_branch = <$fh>;
30
  chomp $current_branch;
31
  
32
  return $current_branch;
cleanup
Yuki Kimoto authored on 2013-05-14
33
}
34

            
cleanup branch_status
Yuki Kimoto authored on 2016-04-16
35
sub branch {
cleanup
Yuki Kimoto authored on 2016-04-16
36
  my ($self, $rep_info, $branch_name) = @_;
cleanup branch
Yuki Kimoto authored on 2016-04-16
37
  
38
  # Branch
39
  $branch_name =~ s/^\*//;
40
  $branch_name =~ s/^\s*//;
41
  $branch_name =~ s/\s*$//;
42
  my $branch = {};
43
  $branch->{name} = $branch_name;
cleanup
Yuki Kimoto authored on 2016-04-16
44
  my $commit = $self->get_commit_new($rep_info, $branch_name);
cleanup branch
Yuki Kimoto authored on 2016-04-16
45
  $branch->{commit} = $commit;
46

            
47
  return $branch;
48
}
49

            
cleanup
Yuki Kimoto authored on 2013-05-14
50
sub branch_status {
cleanup
Yuki Kimoto authored on 2016-04-16
51
  my ($self, $rep_info, $branch1, $branch2) = @_;
cleanup
Yuki Kimoto authored on 2013-05-14
52
  
53
  # Branch status
54
  my $status = {ahead => 0, behind => 0};
cleanup cmd
Yuki Kimoto authored on 2016-04-16
55
  my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
56
    $rep_info,
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
57
    'rev-list',
58
    '--left-right',
59
    "$branch1...$branch2"
cleanup
Yuki Kimoto authored on 2013-05-14
60
  );
61
  open my $fh, '-|', @cmd
62
    or croak "Can't get branch status: @cmd";
63
  while (my $line = <$fh>) {
64
    if ($line =~ /^</) { $status->{behind}++ }
65
    elsif ($line =~ /^>/) { $status->{ahead}++ }
66
  }
67
  
68
  return $status;
69
}
70

            
add rename project and suppr...
Yuki Kimoto authored on 2013-05-24
71
sub no_merged_branch_h {
cleanup
Yuki Kimoto authored on 2016-04-16
72
  my ($self, $rep_info) = @_;
cleanup
Yuki Kimoto authored on 2013-05-14
73
  
74
  # No merged branches
75
  my $no_merged_branches_h = {};
76
  {
cleanup
Yuki Kimoto authored on 2016-04-16
77
    my @cmd = $self->cmd($rep_info, 'branch', '--no-merged');
add rename project and suppr...
Yuki Kimoto authored on 2013-05-24
78
    open my $fh, '-|', @cmd or return;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
79
    my @lines = <$fh>;
80
    for my $branch_name (@lines) {
81
      $branch_name = $self->_dec($branch_name);
cleanup
Yuki Kimoto authored on 2013-05-14
82
      $branch_name =~ s/^\*//;
83
      $branch_name =~ s/^\s*//;
84
      $branch_name =~ s/\s*$//;
85
      $no_merged_branches_h->{$branch_name} = 1;
86
    }
87
  }
88
  
add rename project and suppr...
Yuki Kimoto authored on 2013-05-24
89
  return $no_merged_branches_h;
90
}
91

            
92
sub branches {
cleanup
Yuki Kimoto authored on 2016-04-16
93
  my ($self, $rep_info) = @_;
add rename project and suppr...
Yuki Kimoto authored on 2013-05-24
94
  
cleanup
Yuki Kimoto authored on 2013-05-14
95
  # Branches
cleanup
Yuki Kimoto authored on 2016-04-16
96
  my @cmd = $self->cmd($rep_info, 'branch');
cleanup
Yuki Kimoto authored on 2013-05-14
97
  open my $fh, '-|', @cmd or return;
98
  my $branches = [];
add rename project and suppr...
Yuki Kimoto authored on 2013-05-24
99
  my $start;
100
  my $no_merged_branches_h;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
101
  my @lines = <$fh>;
102
  for my $branch_name (@lines) {
103
    $branch_name = $self->_dec($branch_name);
fix no merged branch not sho...
Yuki Kimoto authored on 2013-05-27
104
    $branch_name =~ s/^\*//;
105
    $branch_name =~ s/^\s*//;
106
    $branch_name =~ s/\s*$//;
cleanup
Yuki Kimoto authored on 2013-05-14
107
    
add rename project and suppr...
Yuki Kimoto authored on 2013-05-24
108
    # No merged branch
cleanup
Yuki Kimoto authored on 2016-04-16
109
    $no_merged_branches_h = $self->no_merged_branch_h($rep_info)
add rename project and suppr...
Yuki Kimoto authored on 2013-05-24
110
      unless $start++;
111
    
cleanup
Yuki Kimoto authored on 2013-05-14
112
    # Branch
cleanup
Yuki Kimoto authored on 2016-04-16
113
    my $branch = $self->branch($rep_info, $branch_name);
cleanup
Yuki Kimoto authored on 2013-05-14
114
    $branch->{no_merged} = 1 if $no_merged_branches_h->{$branch_name};
115
    push @$branches, $branch;
116
  }
117
  @$branches = sort { $a->{commit}{age} <=> $b->{commit}{age} } @$branches;
118
  
119
  return $branches;
120
}
121

            
122
sub branches_count {
cleanup
Yuki Kimoto authored on 2016-04-16
123
  my ($self, $rep_info) = @_;
cleanup
Yuki Kimoto authored on 2013-05-14
124
  
125
  # Branches count
cleanup
Yuki Kimoto authored on 2016-04-16
126
  my @cmd = $self->cmd($rep_info, 'branch');
cleanup
Yuki Kimoto authored on 2013-05-14
127
  open my $fh, '-|', @cmd or return;
128
  my @branches = <$fh>;
129
  my $branches_count = @branches;
130
  
131
  return $branches_count;
132
}
133

            
cleanup cmd
Yuki Kimoto authored on 2016-04-16
134
sub cmd {
cleanup
Yuki Kimoto authored on 2016-04-16
135
  my ($self, $rep_info, @command) = @_;
cleanup cmd
Yuki Kimoto authored on 2016-04-16
136
  
cleanup
Yuki Kimoto authored on 2016-04-16
137
  my $git_dir = $rep_info->{git_dir};
138
  my $work_tree = $rep_info->{work_tree};
cleanup cmd
Yuki Kimoto authored on 2016-04-16
139
  
140
  my @command_all = ($self->bin);
141
  if (defined $git_dir) {
142
    push @command_all, "--git-dir=$git_dir";
143
  }
144
  if (defined $work_tree) {
145
    push @command_all, "--work-tree=$work_tree";
146
  }
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
147
  push @command_all, @command;
cleanup cmd
Yuki Kimoto authored on 2016-04-16
148
  
149
  return @command_all;
150
}
151

            
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
152
sub cmd_rep {
cleanup
Yuki Kimoto authored on 2013-05-14
153
  my ($self, $user, $project, @cmd) = @_;
copy gitweblite soruce code
root authored on 2012-11-23
154
  
cleanup
Yuki Kimoto authored on 2013-05-14
155
  # Git command
cleanup
Yuki Kimoto authored on 2016-04-16
156
  my $rep_info = $self->app->rep_path($user, $project);
copy gitweblite soruce code
root authored on 2012-11-23
157
  
cleanup
Yuki Kimoto authored on 2016-04-16
158
  return $self->cmd_dir($rep_info, @cmd);
copy gitweblite soruce code
root authored on 2012-11-23
159
}
160

            
add working directory api
Yuki Kimoto authored on 2016-04-13
161
sub cmd_dir {
162
  my ($self, $dir, @cmd) = @_;
added branch long name featu...
Yuki Kimoto authored on 2013-05-12
163
  
add working directory api
Yuki Kimoto authored on 2016-04-13
164
  return ($self->bin, "--git-dir=$dir", @cmd);
165
}
166

            
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
167
sub cmd_rep_work {
add working directory api
Yuki Kimoto authored on 2016-04-13
168
  my ($self, $user, $project, @cmd) = @_;
169
  
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
170
  # Working directory
cleanup
Yuki Kimoto authored on 2016-04-16
171
  my $work_rep_info = $self->app->rep_work_path($user, $project);
add working directory api
Yuki Kimoto authored on 2016-04-13
172
  
cleanup
Yuki Kimoto authored on 2016-04-16
173
  return $self->cmd_work_dir($work_rep_info, @cmd);
add working directory api
Yuki Kimoto authored on 2016-04-13
174
}
175

            
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
176
sub cmd_work_dir {
add working directory api
Yuki Kimoto authored on 2016-04-13
177
  my ($self, $dir, @cmd) = @_;
178
  
improve create working repos...
Yuki Kimoto authored on 2016-04-15
179
  return ($self->bin, "--git-dir=$dir/.git", "--work-tree=$dir",  @cmd);
added branch long name featu...
Yuki Kimoto authored on 2013-05-12
180
}
181

            
added contributer count
Yuki Kimoto authored on 2013-01-28
182
sub authors {
cleanup
Yuki Kimoto authored on 2016-04-16
183
  my ($self, $rep_info, $rev, $file) = @_;
added contributer count
Yuki Kimoto authored on 2013-01-28
184
  
cleanup
Yuki Kimoto authored on 2013-05-14
185
  # Authors
cleanup authors
Yuki Kimoto authored on 2016-04-16
186
  my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
187
    $rep_info,
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
188
    'log',
189
    '--format=%an',
190
    $rev,
191
    '--',
192
    $file
cleanup blob page
Yuki Kimoto authored on 2013-03-19
193
  );
added contributer count
Yuki Kimoto authored on 2013-01-28
194
  open my $fh, "-|", @cmd
195
    or croak 500, "Open git-cat-file failed";
196
  my $authors = {};
cleanup encoding
Yuki Kimoto authored on 2016-04-05
197
  my @lines = <$fh>;
198
  for my $line (@lines) {
199
    $line = $self->_dec($line);
added contributer count
Yuki Kimoto authored on 2013-01-28
200
    $line =~ s/[\r\n]//g;
201
    $authors->{$line} = 1;
202
  }
203
  
204
  return [sort keys %$authors];
205
}
206

            
add blame method
Yuki Kimoto authored on 2013-08-10
207
sub blame {
cleanup
Yuki Kimoto authored on 2016-04-16
208
  my ($self, $rep_info, $rev, $file) = @_;
add blame method
Yuki Kimoto authored on 2013-08-10
209
  
210
  # Git blame
cleanup blame
Yuki Kimoto authored on 2016-04-16
211
  my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
212
    $rep_info,
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
213
    'blame',
214
    '--line-porcelain',
215
    $rev,
216
    '--',
217
    $file
add blame method
Yuki Kimoto authored on 2013-08-10
218
  );
219
  open my $fh, '-|', @cmd
220
    or croak "Can't git blame --line-porcelain";
221
  
222
  # Format lines
223
  my $blame_lines = [];
224
  my $blame_line;
add hot color to blame page
Yuki Kimoto authored on 2013-08-10
225
  my $max_author_time;
226
  my $min_author_time;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
227
  my @lines = <$fh>;
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
228
  
cleanup methods
Yuki Kimoto authored on 2016-04-16
229
  my $enc = $self->decide_encoding($rep_info, \@lines);
cleanup encoding
Yuki Kimoto authored on 2016-04-05
230
  for my $line (@lines) {
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
231
    $line = decode($enc, $line);
add blame method
Yuki Kimoto authored on 2013-08-10
232
    chomp $line;
233
    
234
    if ($blame_line) {
235
      if ($line =~ /^author +(.+)/) {
236
        $blame_line->{author} = $1;
237
      }
238
      elsif ($line =~ /^author-mail +(.+)/) {
239
        $blame_line->{author_mail} = $1;
240
      }
improve blame design
Yuki Kimoto authored on 2013-08-10
241
      elsif ($line =~ /^author-time +(.+)/) {
242
        my $author_time = $1;
add hot color to blame page
Yuki Kimoto authored on 2013-08-10
243
        $blame_line->{author_time} = $author_time;
244
        $max_author_time = $author_time if !$max_author_time || $author_time > $max_author_time;
245
        $min_author_time = $author_time if !$min_author_time || $author_time < $min_author_time;
improve blame design
Yuki Kimoto authored on 2013-08-10
246
        my $author_age_string_date = $self->_age_string_date($author_time);
247
        $blame_line->{author_age_string_date} = $author_age_string_date;
improve blame page design
Yuki Kimoto authored on 2016-01-13
248
        my $author_age_string_date_local = $self->_age_string_date_local($author_time);
249
        $blame_line->{author_age_string_date_local} = $author_age_string_date_local;
improve blame design
Yuki Kimoto authored on 2013-08-10
250
      }
add blame method
Yuki Kimoto authored on 2013-08-10
251
      elsif ($line =~ /^summary +(.+)/) {
252
        $blame_line->{summary} = $1;
253
      }
254
      elsif ($line =~ /^\t(.+)?/) {
255
        my $content = $1;
256
        $content = '' unless defined $content;
257
        $blame_line->{content} = $content;
258
        push @$blame_lines, $blame_line;
259
        $blame_line = undef;
260
      }
261
    }
262
    elsif ($line =~ /^([a-fA-F0-9]{40}) +\d+ +(\d+)/) {
263
      $blame_line = {};
264
      $blame_line->{commit} = $1;
improve blame design
Yuki Kimoto authored on 2013-08-10
265
      $blame_line->{number} = $2;
add blame method
Yuki Kimoto authored on 2013-08-10
266
      if ($blame_lines->[-1]
267
        && $blame_lines->[-1]{commit} eq $blame_line->{commit})
268
      {
269
        $blame_line->{before_same_commit} = 1;
270
      }
271
    }
272
  }
273
  
add hot color to blame page
Yuki Kimoto authored on 2013-08-10
274
  my $blame = {
275
    lines => $blame_lines,
276
    max_author_time => $max_author_time,
277
    min_author_time => $min_author_time
278
  };
279
  
280
  return $blame;
add blame method
Yuki Kimoto authored on 2013-08-10
281
}
282

            
283
sub blob {
cleanup
Yuki Kimoto authored on 2016-04-16
284
  my ($self, $rep_info, $rev, $file) = @_;
add blame method
Yuki Kimoto authored on 2013-08-10
285
  
286
  # Blob
cleanup method
Yuki Kimoto authored on 2016-04-16
287
  my $hash = $self->path_to_hash($rep_info, $rev, $file, 'blob')
add blame method
Yuki Kimoto authored on 2013-08-10
288
    or croak 'Cannot find file';
cleanup blob
Yuki Kimoto authored on 2016-04-16
289
  my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
290
    $rep_info,
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
291
    'cat-file',
292
    'blob',
293
    $hash
add blame method
Yuki Kimoto authored on 2013-08-10
294
  );
295
  open my $fh, '-|', @cmd
296
    or croak "Can't cat $file, $hash";
297
  
298
  # Format lines
cleanup encoding
Yuki Kimoto authored on 2016-04-05
299
  my @lines = <$fh>;
300
  my @new_lines;
cleanup methods
Yuki Kimoto authored on 2016-04-16
301
  my $enc = $self->decide_encoding($rep_info, \@lines);
cleanup encoding
Yuki Kimoto authored on 2016-04-05
302
  for my $line (@lines) {
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
303
    $line = decode($enc, $line);
add blame method
Yuki Kimoto authored on 2013-08-10
304
    chomp $line;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
305
    push @new_lines, $line;
add blame method
Yuki Kimoto authored on 2013-08-10
306
  }
307
  
cleanup encoding
Yuki Kimoto authored on 2016-04-05
308
  return \@new_lines;
add blame method
Yuki Kimoto authored on 2013-08-10
309
}
310

            
cleanup
Yuki Kimoto authored on 2013-05-14
311
sub blob_diffs {
cleanup
Yuki Kimoto authored on 2016-04-16
312
  my ($self, $rep_info, $rev1, $rev2, $diff_trees, $opt) = @_;
cleanup blob_diffs
Yuki Kimoto authored on 2016-04-16
313
  
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
314
  $opt //= {};
315
  my $ignore_space_change = $opt->{ignore_space_change};
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
316
  
cleanup
Yuki Kimoto authored on 2013-05-14
317
  return unless defined $rev1 && defined $rev2;
added commit page test
Yuki Kimoto authored on 2013-04-27
318
  
cleanup
Yuki Kimoto authored on 2013-05-14
319
  # Diff tree
cleanup blob_diffs
Yuki Kimoto authored on 2016-04-16
320
  my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
321
    $rep_info,
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
322
    'diff-tree',
323
    '-r',
324
    '-M',
325
    '--no-commit-id',
326
    '--patch-with-raw',
327
    ($ignore_space_change ? '--ignore-space-change' : ()),
328
    $rev1,
329
    $rev2,
330
    '--'
cleanup
Yuki Kimoto authored on 2013-03-19
331
  );
add --ignore-space-change fe...
Yuki Kimoto authored on 2014-12-09
332
  
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
333
  open my $fh, '-|', @cmd
334
    or croak('Open self-diff-tree failed');
cleanup
Yuki Kimoto authored on 2013-05-14
335
  my @diff_tree;
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
336
  my @diff_tree_lines = <$fh>;
cleanup methods
Yuki Kimoto authored on 2016-04-16
337
  my $diff_tree_enc = $self->decide_encoding($rep_info, \@diff_tree_lines);
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
338
  for my $line (@diff_tree_lines) {
339
    $line = decode($diff_tree_enc, $line);
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
340
    chomp $line;
cleanup
Yuki Kimoto authored on 2013-05-14
341
    push @diff_tree, $line if $line =~ /^:/;
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
342
    last if $line =~ /^\n/;
343
  }
344
  close $fh;
cleanup
Yuki Kimoto authored on 2013-05-14
345
  
346
  # Blob diffs
cleanup
Yuki Kimoto authored on 2013-05-14
347
  my $blob_diffs = [];
cleanup
Yuki Kimoto authored on 2013-05-14
348
  for my $line (@diff_tree) {
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
349
  
cleanup
Yuki Kimoto authored on 2013-05-14
350
    # File information
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
351
    chomp $line;
cleanup
Yuki Kimoto authored on 2013-05-14
352
    my $diffinfo = $self->parse_diff_tree_line($line);
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
353
    my $from_file = $diffinfo->{from_file};
354
    my $file = $diffinfo->{to_file};
355
    
cleanup
Yuki Kimoto authored on 2013-05-14
356
    # Blob diff
cleanup blob_diffs
Yuki Kimoto authored on 2016-04-16
357
    my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
358
      $rep_info,
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
359
      'diff-tree',
360
      '-r',
361
      '-M',
362
      '-p',
363
      ($ignore_space_change ? '--ignore-space-change' : ()),
364
      $rev1,
365
      $rev2,
366
      '--',
367
      (defined $from_file ? $from_file : ()),
368
      $file
cleanup
Yuki Kimoto authored on 2013-03-19
369
    );
cleanup
Yuki Kimoto authored on 2013-05-14
370
    open my $fh, '-|', @cmd
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
371
      or croak('Open self-diff-tree failed');
cleanup encoding
Yuki Kimoto authored on 2016-04-05
372
    my @lines = <$fh>;
cleanup methods
Yuki Kimoto authored on 2016-04-16
373
    my $enc = $self->decide_encoding($rep_info, \@lines);
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
374
    @lines = map { decode($enc, $_) } @lines;
cleanup
Yuki Kimoto authored on 2013-05-14
375
    close $fh;
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
376
    my ($lines, $diff_info) = $self->parse_blob_diff_lines(\@lines);
cleanup
Yuki Kimoto authored on 2013-05-14
377
    my $blob_diff = {
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
378
      file => $file,
379
      from_file => $from_file,
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
380
      lines => $lines,
381
      add_line_count => $diff_info->{add_line_count},
fixed blob diff line number ...
Yuki Kimoto authored on 2013-06-01
382
      delete_line_count => $diff_info->{delete_line_count},
383
      binary => $diff_info->{binary}
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
384
    };
385
    
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
386
    # Diff tree info
cleanup
Yuki Kimoto authored on 2013-05-14
387
    for my $diff_tree (@$diff_trees) {
388
      if ($diff_tree->{to_file} eq $file) {
389
        $blob_diff->{status} = $diff_tree->{status};
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
390
        $diff_tree->{add_line_count} = $diff_info->{add_line_count};
391
        $diff_tree->{delete_line_count} = $diff_info->{delete_line_count};
392
        $diff_tree->{add_block_count} = $diff_info->{add_block_count};
393
        $diff_tree->{delete_block_count} = $diff_info->{delete_block_count};
fixed blob diff line number ...
Yuki Kimoto authored on 2013-06-01
394
        $diff_tree->{binary} = $diff_info->{binary};
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
395
        last;
396
      }
397
    }
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
398
    
cleanup
Yuki Kimoto authored on 2013-05-14
399
    push @$blob_diffs, $blob_diff;
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
400
  }
401
  
cleanup
Yuki Kimoto authored on 2013-05-14
402
  return $blob_diffs;
added compare page file chan...
Yuki Kimoto authored on 2013-02-07
403
}
404

            
binary data not shown
Yuki Kimoto authored on 2013-06-02
405
sub blob_is_image {
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
406
  my $self = shift;
binary data not shown
Yuki Kimoto authored on 2013-06-02
407
  
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
408
  my $mime_type = $self->blob_mime_type(@_);
binary data not shown
Yuki Kimoto authored on 2013-06-02
409
  
410
  return ($mime_type || '') =~ m#^image/#;
411
}
412

            
cleanup
Yuki Kimoto authored on 2013-05-14
413
sub blob_mime_type {
cleanup
Yuki Kimoto authored on 2016-04-16
414
  my ($self, $rep_info, $rev, $file) = @_;
cleanup blob and raw page
Yuki Kimoto authored on 2013-05-02
415
  
cleanup
Yuki Kimoto authored on 2013-05-14
416
  # Blob
cleanup method
Yuki Kimoto authored on 2016-04-16
417
  my $hash = $self->path_to_hash($rep_info, $rev, $file, 'blob')
cleanup blob and raw page
Yuki Kimoto authored on 2013-05-02
418
    or croak 'Cannot find file';
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
419
  my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
420
    $rep_info,
cleanup blob and raw page
Yuki Kimoto authored on 2013-05-02
421
    'cat-file',
422
    'blob',
cleanup
Yuki Kimoto authored on 2013-05-14
423
    $hash
cleanup blob and raw page
Yuki Kimoto authored on 2013-05-02
424
  );
425
  open my $fh, '-|', @cmd
cleanup
Yuki Kimoto authored on 2013-05-14
426
    or croak "Can't cat $file, $hash";
copy gitweblite soruce code
root authored on 2012-11-23
427

            
428
  return 'text/plain' unless $fh;
429
  
430
  # MIME type
431
  my $text_exts = $self->text_exts;
432
  for my $text_ext (@$text_exts) {
433
    my $ext = quotemeta($text_ext);
434
    return 'text/plain' if $file =~ /\.$ext$/i;
435
  }
436
  if (-T $fh) { return 'text/plain' }
437
  elsif (! $file) { return 'application/octet-stream' }
438
  elsif ($file =~ m/\.png$/i) { return 'image/png' }
439
  elsif ($file =~ m/\.gif$/i) { return 'image/gif' }
440
  elsif ($file =~ m/\.jpe?g$/i) { return 'image/jpeg'}
441
  else { return 'application/octet-stream'}
442
  
443
  return;
444
}
445

            
cleanup
Yuki Kimoto authored on 2013-05-14
446
sub blob_content_type {
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
447
  my $self = shift;
copy gitweblite soruce code
root authored on 2012-11-23
448
  
449
  # Content type
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
450
  my $type = $self->blob_mime_type(@_);
copy gitweblite soruce code
root authored on 2012-11-23
451
  if ($type eq 'text/plain') {
Renamed encoding to default_...
Tetsuya Hayashi authored on 2014-03-15
452
    $type .= "; charset=" . $self->default_encoding;
copy gitweblite soruce code
root authored on 2012-11-23
453
  }
454

            
455
  return $type;
456
}
457

            
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
458
sub blob_mode {
cleanup
Yuki Kimoto authored on 2016-04-16
459
  my ($self, $rep_info, $rev, $file) = @_;
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
460
  
cleanup
Yuki Kimoto authored on 2013-05-14
461
  # Blob mode
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
462
  $file =~ s#/+$##;
cleanup blob_mode
Yuki Kimoto authored on 2016-04-16
463
  my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
464
    $rep_info,
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
465
    'ls-tree',
466
    $rev,
467
    '--',
468
    $file
469
  );
470
  open my $fh, '-|', @cmd
471
    or croak 'Open git-ls-tree failed';
cleanup encoding
Yuki Kimoto authored on 2016-04-05
472
  my $line = <$fh>;
473
  $line = $self->_dec($line);
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
474
  close $fh or return;
475
  my ($mode) = ($line || '') =~ m/^([0-9]+) /;
476
  
477
  return $mode;
478
}
479

            
480
sub blob_raw {
cleanup
Yuki Kimoto authored on 2016-04-16
481
  my ($self, $rep_info, $rev, $path) = @_;
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
482
  
cleanup
Yuki Kimoto authored on 2013-05-14
483
  # Blob raw
cleanup
Yuki Kimoto authored on 2016-04-16
484
  my @cmd = $self->cmd($rep_info, 'cat-file', 'blob', "$rev:$path");
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
485
  open my $fh, "-|", @cmd
486
    or croak 500, "Open git-cat-file failed";
487
  local $/;
cleanup blob_raw
Yuki Kimoto authored on 2016-04-16
488
  my $blob_raw = <$fh>;
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
489

            
490
  close $fh or croak 'Reading git-shortlog failed';
491
  
492
  return $blob_raw;
493
}
494

            
cleanup
Yuki Kimoto authored on 2013-05-14
495
sub blob_size {
cleanup
Yuki Kimoto authored on 2016-04-16
496
  my ($self, $rep_info, $rev, $file) = @_;
added file size to blob page
Yuki Kimoto authored on 2013-01-29
497
  
cleanup
Yuki Kimoto authored on 2013-05-14
498
  # Blob size(KB)
cleanup blob_size
Yuki Kimoto authored on 2016-04-16
499
  my @cmd = $self->cmd(
cleanup
Yuki Kimoto authored on 2016-04-16
500
    $rep_info,
cleanup blob page
Yuki Kimoto authored on 2013-03-19
501
    'cat-file',
502
    '-s',
503
    "$rev:$file"
504
  );
added file size to blob page
Yuki Kimoto authored on 2013-01-29
505
  open my $fh, "-|", @cmd
506
    or croak 500, "Open cat-file failed";
cleanup encoding
Yuki Kimoto authored on 2016-04-05
507
  my $size = <$fh>;
508
  $size = $self->_dec($size);
added file size to blob page
Yuki Kimoto authored on 2013-01-29
509
  chomp $size;
510
  close $fh or croak 'Reading cat-file failed';
511
  
cleanup
Yuki Kimoto authored on 2013-05-14
512
  # Format
513
  my $size_f = sprintf('%.3f', $size / 1000);
514
  $size_f =~ s/0+$//;
improved blob page desing
Yuki Kimoto authored on 2013-05-02
515
  
cleanup
Yuki Kimoto authored on 2013-05-14
516
  return $size_f;
added file size to blob page
Yuki Kimoto authored on 2013-01-29
517
}
518

            
improved create repository f...
Yuki Kimoto authored on 2013-03-21
519
sub check_head_link {
520
  my ($self, $dir) = @_;
added separeted commit getti...
Yuki Kimoto authored on 2013-02-04
521
  
improved create repository f...
Yuki Kimoto authored on 2013-03-21
522
  # Chack head
523
  my $head_file = "$dir/HEAD";
524
  return ((-e $head_file) ||
525
    (-l $head_file && readlink($head_file) =~ /^refs\/heads\//));
526
}
added separeted commit getti...
Yuki Kimoto authored on 2013-02-04
527

            
added commits number
Yuki Kimoto authored on 2012-11-28
528
sub commits_number {
cleanup
Yuki Kimoto authored on 2016-04-16
529
  my ($self, $rep_info, $ref) = @_;
added commits number
Yuki Kimoto authored on 2012-11-28
530
  
531
  # Command "git diff-tree"
cleanup
Yuki Kimoto authored on 2016-04-16
532
  my @cmd = $self->cmd($rep_info, 'shortlog', '-s', $ref);
added commits number
Yuki Kimoto authored on 2012-11-28
533
  open my $fh, "-|", @cmd
534
    or croak 500, "Open git-shortlog failed";
cleanup encoding
Yuki Kimoto authored on 2016-04-05
535
  my @commits_infos = <$fh>;
536
  @commits_infos = map { chomp; $self->_dec($_) } @commits_infos;
added commits number
Yuki Kimoto authored on 2012-11-28
537
  close $fh or croak 'Reading git-shortlog failed';
538
  
539
  my $commits_num = 0;
540
  for my $commits_info (@commits_infos) {
541
    if ($commits_info =~ /^ *([0-9]+)/) {
542
      $commits_num += $1;
543
    }
544
  }
545
  
546
  return $commits_num;
547
}
548

            
cleanup
Yuki Kimoto authored on 2013-05-14
549
sub exists_branch {
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
550
  my ($self, $rep) = @_;
cleanup
Yuki Kimoto authored on 2013-05-14
551
  
552
  # Exists branch
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
553
  my @cmd = $self->cmd($rep, 'branch');
cleanup
Yuki Kimoto authored on 2013-05-14
554
  open my $fh, "-|", @cmd
555
    or croak 'git branch failed';
556
  local $/;
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
557
  my $branch = <$fh>;
cleanup
Yuki Kimoto authored on 2013-05-14
558
  
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
559
  return $branch ne '' ? 1 : 0;
cleanup
Yuki Kimoto authored on 2013-05-14
560
}
561

            
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
562
sub delete_branch {
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
563
  my ($self, $rep, $branch) = @_;
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
564
  
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
565
  my $branches = $self->branches($rep);
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
566
  my $exists;
567
  for my $b (@$branches) {
568
    if ($branch eq $b->{name}) {
569
      $exists = 1;
570
      next;
571
    }
572
  }
573
  
574
  if ($exists) {
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
575
    my @cmd = $self->cmd($rep, 'branch', '-D', $branch);
fix bug that in CGI reposito...
Yuki Kimoto authored on 2015-11-05
576
    Gitprep::Util::run_command(@cmd)
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
577
      or croak "Branch deleting failed. Can't delete branch $branch";
578
  }
579
  else {
580
    croak "Branch deleteting failed.. branchg $branch is not exists";
581
  }
582
}
583

            
added project rename feature
Yuki Kimoto authored on 2013-03-25
584
sub description {
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
585
  my ($self, $rep, $description) = @_;
added project rename feature
Yuki Kimoto authored on 2013-03-25
586
  
cleanup descriptioN
Yuki Kimoto authored on 2016-04-16
587
  my $git_dir = $rep->{git_dir};
588
  my $file = "$git_dir/description";
added project rename feature
Yuki Kimoto authored on 2013-03-25
589
  
590
  if (defined $description) {
591
    # Write description
592
    open my $fh, '>',$file
593
      or croak "Can't open file $rep: $!";
594
    print $fh encode('UTF-8', $description)
595
      or croak "Can't write description: $!";
596
    close $fh;
597
  }
598
  else {
599
    # Read description
added not exists repository ...
Yuki Kimoto authored on 2013-05-15
600
    return unless -f $file;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
601
    my $description = $self->_slurp($file) || '';
602
    $description = $self->_dec($description);
added project rename feature
Yuki Kimoto authored on 2013-03-25
603
    return $description;
604
  }
605
}
606

            
cleanup
Yuki Kimoto authored on 2013-05-14
607
sub diff_tree {
cleanup method
Yuki Kimoto authored on 2016-04-16
608
  my ($self, $rep_info, $rev, $parent, $opt) = @_;
add --ignore-space-change fe...
Yuki Kimoto authored on 2014-12-09
609
  
610
  $opt ||= {};
611
  my $ignore_space_change = $opt->{ignore_space_change};
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
612
  
copy gitweblite soruce code
root authored on 2012-11-23
613
  # Root
614
  $parent = '--root' unless defined $parent;
615

            
cleanup
Yuki Kimoto authored on 2013-03-19
616
  # Get diff tree
cleanup method
Yuki Kimoto authored on 2016-04-16
617
  my @cmd = $self->cmd(
618
    $rep_info,
cleanup
Yuki Kimoto authored on 2013-03-19
619
    "diff-tree",
620
    '-r',
621
    '--no-commit-id',
622
    '-M',
add --ignore-space-change fe...
Yuki Kimoto authored on 2014-12-09
623
    ($ignore_space_change ? '--ignore-space-change' : ()),
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
624
    $parent,
625
    $rev,
cleanup
Yuki Kimoto authored on 2013-03-19
626
    '--'
627
  );
add --ignore-space-change fe...
Yuki Kimoto authored on 2014-12-09
628
  
copy gitweblite soruce code
root authored on 2012-11-23
629
  open my $fh, "-|", @cmd
630
    or croak 500, "Open git-diff-tree failed";
cleanup encoding
Yuki Kimoto authored on 2016-04-05
631
  my @diff_tree = <$fh>;
632
  @diff_tree = map { chomp; $self->_dec($_) } @diff_tree;
copy gitweblite soruce code
root authored on 2012-11-23
633
  close $fh or croak 'Reading git-diff-tree failed';
634
  
635
  # Parse "git diff-tree" output
636
  my $diffs = [];
cleanup
Yuki Kimoto authored on 2013-05-14
637
  for my $line (@diff_tree) {
638
    my $diff = $self->parsed_diff_tree_line($line);
copy gitweblite soruce code
root authored on 2012-11-23
639
    
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
640
    my ($to_mode_oct, $to_mode_str, $to_file_type);
641
    my ($from_mode_oct, $from_mode_str, $from_file_type);
642
    if ($diff->{to_mode} ne ('0' x 6)) {
643
      $to_mode_oct = oct $diff->{to_mode};
644
      if (S_ISREG($to_mode_oct)) { # only for regular file
645
        $to_mode_str = sprintf('%04o', $to_mode_oct & 0777); # permission bits
copy gitweblite soruce code
root authored on 2012-11-23
646
      }
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
647
      $to_file_type = $self->file_type($diff->{to_mode});
648
    }
649
    if ($diff->{from_mode} ne ('0' x 6)) {
650
      $from_mode_oct = oct $diff->{from_mode};
651
      if (S_ISREG($from_mode_oct)) { # only for regular file
652
        $from_mode_str = sprintf('%04o', $from_mode_oct & 0777); # permission bits
copy gitweblite soruce code
root authored on 2012-11-23
653
      }
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
654
      $from_file_type = $self->file_type($diff->{from_mode});
copy gitweblite soruce code
root authored on 2012-11-23
655
    }
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
656
    
657
    $diff->{to_mode_str} = $to_mode_str;
658
    $diff->{to_mode_oct} = $to_mode_oct;
659
    $diff->{to_file_type} = $to_file_type;
660
    $diff->{from_mode_str} = $from_mode_str;
661
    $diff->{from_mode_oct} = $from_mode_oct;
662
    $diff->{from_file_type} = $from_file_type;
663

            
664
    push @$diffs, $diff;
copy gitweblite soruce code
root authored on 2012-11-23
665
  }
666
  
667
  return $diffs;
668
}
669

            
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
670
sub file_type {
671
  my ($self, $mode) = @_;
672
  
673
  # File type
674
  if ($mode !~ m/^[0-7]+$/) { return $mode }
675
  else { $mode = oct $mode }
676
  if ($self->_s_isgitlink($mode)) { return 'submodule' }
677
  elsif (S_ISDIR($mode & S_IFMT)) { return 'directory' }
678
  elsif (S_ISLNK($mode)) { return 'symlink' }
679
  elsif (S_ISREG($mode)) { return 'file' }
680
  else { return 'unknown' }
681
  
682
  return
683
}
684

            
685
sub file_type_long {
686
  my ($self, $mode) = @_;
687
  
cleanup
Yuki Kimoto authored on 2013-05-14
688
  # File type long
added branch deleting featur...
Yuki Kimoto authored on 2013-05-05
689
  if ($mode !~ m/^[0-7]+$/) { return $mode }
690
  else { $mode = oct $mode }
691
  if ($self->_s_isgitlink($mode)) { return 'submodule' }
692
  elsif (S_ISDIR($mode & S_IFMT)) { return 'directory' }
693
  elsif (S_ISLNK($mode)) { return 'symlink' }
694
  elsif (S_ISREG($mode)) {
695
    if ($mode & S_IXUSR) { return 'executable file' }
696
    else { return 'file' }
697
  }
698
  else { return 'unknown' }
699
  
700
  return;
701
}
702

            
cleanup
Yuki Kimoto authored on 2013-05-14
703
sub forward_commits {
cleanup method
Yuki Kimoto authored on 2016-04-16
704
  my ($self, $rep_info, $rev1, $rev2) = @_;
setting page
Yuki Kimoto authored on 2013-03-24
705
  
cleanup
Yuki Kimoto authored on 2013-05-14
706
  # Forwarding commits
cleanup method
Yuki Kimoto authored on 2016-04-16
707
  my @cmd = $self->cmd(
708
    $rep_info,
cleanup
Yuki Kimoto authored on 2013-05-14
709
    'rev-list',
710
    '--left-right',
711
    "$rev1...$rev2"
712
  );
713
  open my $fh, '-|', @cmd
714
    or croak "Can't get info: @cmd";
715
  my $commits = [];
716
  while (my $line = <$fh>) {
717
    if ($line =~ /^>(.+)\s/) {
718
      my $rev = $1;
cleanup method
Yuki Kimoto authored on 2016-04-16
719
      my $commit = $self->get_commit_new($rep_info, $rev);
cleanup
Yuki Kimoto authored on 2013-05-14
720
      push @$commits, $commit;
added merged branches to bra...
Yuki Kimoto authored on 2013-05-03
721
    }
722
  }
723
  
cleanup
Yuki Kimoto authored on 2013-05-14
724
  return $commits;
added merged branches to bra...
Yuki Kimoto authored on 2013-05-03
725
}
726

            
cleanup
Yuki Kimoto authored on 2013-05-14
727
sub path_to_hash {
cleanup method
Yuki Kimoto authored on 2016-04-16
728
  my ($self, $rep_info, $rev, $path, $type) = @_;
copy gitweblite soruce code
root authored on 2012-11-23
729
  
730
  # Get blob id or tree id (command "git ls-tree")
731
  $path =~ s#/+$##;
cleanup method
Yuki Kimoto authored on 2016-04-16
732
  my @cmd = $self->cmd(
733
    $rep_info,
cleanup
Yuki Kimoto authored on 2013-03-19
734
    'ls-tree',
cleanup
Yuki Kimoto authored on 2013-04-29
735
    $rev,
cleanup
Yuki Kimoto authored on 2013-03-19
736
    '--',
737
    $path
738
  );
copy gitweblite soruce code
root authored on 2012-11-23
739
  open my $fh, '-|', @cmd
740
    or croak 'Open git-ls-tree failed';
cleanup encoding
Yuki Kimoto authored on 2016-04-05
741
  my $line = <$fh>;
742
  $line = $self->_dec($line);
copy gitweblite soruce code
root authored on 2012-11-23
743
  close $fh or return;
744
  my ($t, $id) = ($line || '') =~ m/^[0-9]+ (.+) ([0-9a-fA-F]{40})\t/;
change markdown engine to Te...
Yuki Kimoto authored on 2013-10-07
745
  $t ||= '';
copy gitweblite soruce code
root authored on 2012-11-23
746
  return if defined $type && $type ne $t;
747

            
748
  return $id;
749
}
750

            
cleanup
Yuki Kimoto authored on 2013-05-14
751

            
752
sub last_activity {
cleanup method
Yuki Kimoto authored on 2016-04-16
753
  my ($self, $rep) = @_;
added branch and tag refs to...
Yuki Kimoto authored on 2013-04-26
754
  
cleanup
Yuki Kimoto authored on 2013-05-14
755
  # Command "git for-each-ref"
cleanup method
Yuki Kimoto authored on 2016-04-16
756
  my @cmd = $self->cmd(
757
    $rep,
cleanup
Yuki Kimoto authored on 2013-05-14
758
    'for-each-ref',
759
    '--format=%(committer)',
760
    '--sort=-committerdate',
761
    '--count=1', 'refs/heads'
added branch and tag refs to...
Yuki Kimoto authored on 2013-04-26
762
  );
cleanup
Yuki Kimoto authored on 2013-05-14
763
  open my $fh, '-|', @cmd or return;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
764
  my $most_recent = <$fh>;
765
  $most_recent = $self->_dec($most_recent);
cleanup
Yuki Kimoto authored on 2013-05-14
766
  close $fh or return;
added branch and tag refs to...
Yuki Kimoto authored on 2013-04-26
767
  
cleanup
Yuki Kimoto authored on 2013-05-14
768
  # Parse most recent
769
  if (defined $most_recent &&
770
      $most_recent =~ / (\d+) [-+][01]\d\d\d$/) {
771
    my $timestamp = $1;
772
    my $age = time - $timestamp;
773
    return ($age, $self->_age_string($age));
added branch and tag refs to...
Yuki Kimoto authored on 2013-04-26
774
  }
775
  
cleanup
Yuki Kimoto authored on 2013-05-14
776
  return;
777
}
778

            
779
sub parse_rev_path {
cleanup tags
Yuki Kimoto authored on 2016-04-16
780
  my ($self, $rep_info, $rev_path) = @_;
copy gitweblite soruce code
root authored on 2012-11-23
781
  
cleanup
Yuki Kimoto authored on 2013-05-14
782
  # References
cleanup parse_rev_path
Yuki Kimoto authored on 2016-04-16
783
  my @cmd = $self->cmd(
cleanup tags
Yuki Kimoto authored on 2016-04-16
784
    $rep_info,
cleanup
Yuki Kimoto authored on 2013-05-14
785
    'show-ref',
786
    '--dereference'
cleanup
Yuki Kimoto authored on 2013-03-19
787
  );
cleanup
Yuki Kimoto authored on 2013-05-14
788
  open my $fh, '-|', @cmd
789
    or return;
790
  my $refs = [];
cleanup encoding
Yuki Kimoto authored on 2016-04-05
791
  my @lines = <$fh>;
792
  for my $line (@lines) {
793
    $line = $self->_dec($line);
cleanup
Yuki Kimoto authored on 2013-05-14
794
    chomp $line;
795
    if ($line =~ m!^[0-9a-fA-F]{40}\s(refs/((?:heads|tags)/(.*)))$!) {
796
      push @$refs, $1, $2, $3;
797
    }
798
  }
copy gitweblite soruce code
root authored on 2012-11-23
799
  close $fh or return;
800
  
cleanup
Yuki Kimoto authored on 2013-05-14
801
  @$refs = sort {
802
    my @a_match = $a =~ /(\/)/g;
803
    my @b_match = $b =~ /(\/)/g;
804
    scalar @b_match <=> scalar @a_match;
805
  } @$refs;
806
  
807
  for my $ref (@$refs) {
808
    $rev_path =~ m#/$#;
809
    if ($rev_path =~ m#^(\Q$ref\E)/(.+)#) {
810
      my $rev = $1;
811
      my $path = $2;
812
      return ($rev, $path);
813
    }
814
    elsif ($rev_path eq $ref) {
815
      return ($rev_path, '');
816
    }
copy gitweblite soruce code
root authored on 2012-11-23
817
  }
818
  
cleanup
Yuki Kimoto authored on 2013-05-14
819
  if ($rev_path) {
820
    my ($rev, $path) = split /\//, $rev_path, 2;
821
    $path = '' unless defined $path;
822
    return ($rev, $path);
823
  }
824

            
copy gitweblite soruce code
root authored on 2012-11-23
825
  return;
826
}
827

            
828
sub object_type {
cleanup tags
Yuki Kimoto authored on 2016-04-16
829
  my ($self, $rep_info, $rev) = @_;
copy gitweblite soruce code
root authored on 2012-11-23
830
  
cleanup
Yuki Kimoto authored on 2013-03-19
831
  # Get object type
cleanup tags
Yuki Kimoto authored on 2016-04-16
832
  my @cmd = $self->cmd(
833
    $rep_info,
cleanup
Yuki Kimoto authored on 2013-03-19
834
    'cat-file',
835
    '-t',
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
836
    $rev
cleanup
Yuki Kimoto authored on 2013-03-19
837
  );
copy gitweblite soruce code
root authored on 2012-11-23
838
  open my $fh, '-|', @cmd  or return;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
839
  my $type = <$fh>;
840
  $type = $self->_dec($type);
copy gitweblite soruce code
root authored on 2012-11-23
841
  close $fh or return;
842
  chomp $type;
843
  
844
  return $type;
845
}
846

            
show deleted repository in u...
Yuki Kimoto authored on 2013-05-15
847
sub repository {
cleanup tags
Yuki Kimoto authored on 2016-04-16
848
  my ($self, $rep_info) = @_;
show deleted repository in u...
Yuki Kimoto authored on 2013-05-15
849

            
cleanup tags
Yuki Kimoto authored on 2016-04-16
850
  return unless -d $self->app->rep_path($rep_info->{user}, $rep_info->{project});
Fixed repositories page
Yuki Kimoto authored on 2012-11-23
851
  
show deleted repository in u...
Yuki Kimoto authored on 2013-05-15
852
  my $rep = {};
cleanup tags
Yuki Kimoto authored on 2016-04-16
853
  my @activity = $self->last_activity($rep_info);
show deleted repository in u...
Yuki Kimoto authored on 2013-05-15
854
  if (@activity) {
855
    $rep->{age} = $activity[0];
856
    $rep->{age_string} = $activity[1];
Fixed repositories page
Yuki Kimoto authored on 2012-11-23
857
  }
show deleted repository in u...
Yuki Kimoto authored on 2013-05-15
858
  else { $rep->{age} = 0 }
859
  
cleanup tags
Yuki Kimoto authored on 2016-04-16
860
  my $description = $self->description($rep_info) || '';
show deleted repository in u...
Yuki Kimoto authored on 2013-05-15
861
  $rep->{description} = $self->_chop_str($description, 25, 5);
cleanup
Yuki Kimoto authored on 2013-03-19
862
  
show deleted repository in u...
Yuki Kimoto authored on 2013-05-15
863
  return $rep;
Fixed repositories page
Yuki Kimoto authored on 2012-11-23
864
}
865

            
cleanup
Yuki Kimoto authored on 2013-05-14
866
sub references {
cleanup tags
Yuki Kimoto authored on 2016-04-16
867
  my ($self, $rep_info, $type) = @_;
cleanup
Yuki Kimoto authored on 2013-05-14
868
  
869
  $type ||= '';
870
  
871
  # Branches or tags
cleanup tags
Yuki Kimoto authored on 2016-04-16
872
  my @cmd = $self->cmd(
873
    $rep_info,
cleanup
Yuki Kimoto authored on 2013-05-14
874
    'show-ref',
875
    '--dereference',
876
    (
877
      $type eq 'heads' ? ('--heads') :
878
      $type eq 'tags' ? ('--tags') :
879
      ()
880
    )
881
  );
882
  
883
  open my $fh, '-|', @cmd
884
    or return;
885
  
886
  # Parse references
887
  my %refs;
888
  my $type_re = $type ? $type : '(?:heads|tags)';
cleanup encoding
Yuki Kimoto authored on 2016-04-05
889
  my @lines = <$fh>;
890
  for my $line (@lines) {
891
    $line = $self->_dec($line);
cleanup
Yuki Kimoto authored on 2013-05-14
892
    chomp $line;
893
    if ($line =~ m!^([0-9a-fA-F]{40})\srefs/$type_re/(.*)$!) {
improved tag and branch refe...
Yuki Kimoto authored on 2013-06-03
894
      my $rev = $1;
895
      my $ref = $2;
896
      $ref =~ s/\^\{\}//;
897
      if (defined $refs{$rev}) { push @{$refs{$rev}}, $ref }
898
      else { $refs{$rev} = [$ref] }
cleanup
Yuki Kimoto authored on 2013-05-14
899
    }
900
  }
901
  close $fh or return;
902
  
903
  return \%refs;
904
}
905

            
copy gitweblite soruce code
root authored on 2012-11-23
906
sub short_id {
907
  my ($self, $project) = (shift, shift);
908
  
909
  # Short id
910
  return $self->id($project, @_, '--short=7');
911
}
912

            
improved tag page design
Yuki Kimoto authored on 2013-05-01
913
sub tags_count {
cleanup methods
Yuki Kimoto authored on 2016-04-16
914
  my ($self, $rep_info) = @_;
improved tag page design
Yuki Kimoto authored on 2013-05-01
915
  
916
  my $limit = 1000;
917
  
918
  # Get tags
cleanup methods
Yuki Kimoto authored on 2016-04-16
919
  my @cmd = $self->cmd(
920
    $rep_info,
improved tag page design
Yuki Kimoto authored on 2013-05-01
921
    'for-each-ref',
922
    ($limit ? '--count='.($limit+1) : ()),
923
    'refs/tags'
924
  );
925
  open my $fh, '-|', @cmd or return;
926
  
927
  # Tags count
928
  my @lines = <$fh>;
929
  
930
  return scalar @lines;
931
}
932

            
copy gitweblite soruce code
root authored on 2012-11-23
933
sub tags {
cleanup tags
Yuki Kimoto authored on 2016-04-16
934
  my ($self, $rep_info, $limit, $count, $offset) = @_;
improved tag page design
Yuki Kimoto authored on 2013-05-01
935
  
936
  $limit ||= 1000;
937
  $count ||= 50;
938
  $offset ||= 0;
cleanup
Yuki Kimoto authored on 2013-03-19
939
  
940
  # Get tags
cleanup tags
Yuki Kimoto authored on 2016-04-16
941
  my @cmd = $self->cmd(
942
    $rep_info,
cleanup
Yuki Kimoto authored on 2013-03-19
943
    'for-each-ref',
944
    ($limit ? '--count='.($limit+1) : ()),
945
    '--sort=-creatordate',
946
    '--format=%(objectname) %(objecttype) %(refname) '
947
      . '%(*objectname) %(*objecttype) %(subject)%00%(creator)',
948
    'refs/tags'
949
  );
copy gitweblite soruce code
root authored on 2012-11-23
950
  open my $fh, '-|', @cmd or return;
951
  
improved tag page design
Yuki Kimoto authored on 2013-05-01
952
  
copy gitweblite soruce code
root authored on 2012-11-23
953
  # Parse Tags
954
  my @tags;
improved tag page design
Yuki Kimoto authored on 2013-05-01
955
  my $line_num = 1;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
956
  my @lines = <$fh>;
957
  for my $line (@lines) {
958
    $line = $self->_dec($line);
copy gitweblite soruce code
root authored on 2012-11-23
959
    
improved tag page design
Yuki Kimoto authored on 2013-05-01
960
    if ($line_num > $offset && $line_num < $offset + $count + 1) {
961
    
962
      my %tag;
963

            
964
      chomp $line;
965
      my ($refinfo, $creatorinfo) = split(/\0/, $line);
966
      my ($id, $type, $name, $refid, $reftype, $title) = split(' ', $refinfo, 6);
967
      my ($creator, $epoch, $tz) =
968
        ($creatorinfo =~ /^(.*) ([0-9]+) (.*)$/);
969
      $tag{fullname} = $name;
970
      $name =~ s!^refs/tags/!!;
971

            
972
      $tag{type} = $type;
973
      $tag{id} = $id;
974
      $tag{name} = $name;
975
      if ($type eq 'tag') {
976
        $tag{subject} = $title;
977
        $tag{reftype} = $reftype;
978
        $tag{refid}   = $refid;
copy gitweblite soruce code
root authored on 2012-11-23
979
      } else {
improved tag page design
Yuki Kimoto authored on 2013-05-01
980
        $tag{reftype} = $type;
981
        $tag{refid}   = $id;
copy gitweblite soruce code
root authored on 2012-11-23
982
      }
983

            
improved tag page design
Yuki Kimoto authored on 2013-05-01
984
      if ($type eq 'tag' || $type eq 'commit') {
985
        $tag{epoch} = $epoch;
986
        if ($epoch) {
987
          $tag{age} = $self->_age_string(time - $tag{epoch});
988
        } else {
989
          $tag{age} = 'unknown';
990
        }
991
      }
992
      
993
      $tag{comment_short} = $self->_chop_str($tag{subject}, 30, 5)
994
        if $tag{subject};
995

            
cleanup tags
Yuki Kimoto authored on 2016-04-16
996
      $tag{commit} = $self->get_commit_new($rep_info, $name);
improved tag page design
Yuki Kimoto authored on 2013-05-01
997

            
998
      push @tags, \%tag;
999
    }
1000
    $line_num++;
copy gitweblite soruce code
root authored on 2012-11-23
1001
  }
improved tag page design
Yuki Kimoto authored on 2013-05-01
1002
  
copy gitweblite soruce code
root authored on 2012-11-23
1003
  close $fh;
1004

            
1005
  return \@tags;
1006
}
1007

            
improved project page design
Yuki Kimoto authored on 2013-04-29
1008
sub last_change_commit {
cleanup methods
Yuki Kimoto authored on 2016-04-16
1009
  my ($self, $rep_info, $rev, $file) = @_;
improved project page design
Yuki Kimoto authored on 2013-04-29
1010
  
1011
  my $commit_log = {};
1012
  $file = '' unless defined $file;
1013
  
cleanup methods
Yuki Kimoto authored on 2016-04-16
1014
  my @cmd = $self->cmd(
1015
    $rep_info,
improved project page design
Yuki Kimoto authored on 2013-04-29
1016
    '--no-pager',
1017
    'log',
1018
    '-n',
1019
    '1',
1020
    '--pretty=format:%H', 
1021
    $rev,
1022
    '--',
1023
    $file
1024
  );
1025
  open my $fh, '-|', @cmd
1026
    or croak 'Open git-log failed';
1027
  
1028
  local $/;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
1029
  my $commit_log_text = <$fh>;
1030
  $commit_log_text = $self->_dec($commit_log_text);
improved project page design
Yuki Kimoto authored on 2013-04-29
1031
  
1032
  my $commit;
1033
  if ($commit_log_text =~ /^([0-9a-zA-Z]+)/) {
1034
    my $rev = $1;
cleanup methods
Yuki Kimoto authored on 2016-04-16
1035
    $commit = $self->get_commit_new($rep_info, $rev);
improved project page design
Yuki Kimoto authored on 2013-04-29
1036
  }
1037
  
1038
  return $commit;
1039
}
1040

            
cleanup
Yuki Kimoto authored on 2013-05-14
1041
sub parse_blob_diff_lines {
cleanup commit page
Yuki Kimoto authored on 2013-04-12
1042
  my ($self, $lines) = @_;
fixed blob diff line number ...
Yuki Kimoto authored on 2013-06-01
1043

            
1044
  my $diff_info = {};
1045

            
added commit page
Yuki Kimoto authored on 2013-01-29
1046
  # Parse
1047
  my @lines;
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1048
  my $next_before_line_num;
1049
  my $next_after_line_num;
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
1050
  my $add_line_count = 0;
1051
  my $delete_line_count = 0;
cleanup commit page
Yuki Kimoto authored on 2013-04-12
1052
  for my $line (@$lines) {
fixed blob diff line number ...
Yuki Kimoto authored on 2013-06-01
1053
    
added commit page
Yuki Kimoto authored on 2013-01-29
1054
    chomp $line;
1055
    
improved commit page design
Yuki Kimoto authored on 2013-04-12
1056
    my $class;
cleanup commit page
Yuki Kimoto authored on 2013-04-12
1057
    my $before_line_num;
1058
    my $after_line_num;
improved commit page design
Yuki Kimoto authored on 2013-04-12
1059
    
fixed blob diff line number ...
Yuki Kimoto authored on 2013-06-01
1060
    if ($line =~ /^@@\s-(\d+)(?:,\d+)?\s\+(\d+)/) {
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1061
      $next_before_line_num = $1;
1062
      $next_after_line_num = $2;
1063
      
1064
      $before_line_num = '...';
1065
      $after_line_num = '...';
1066
      
1067
      $class = 'chunk_header';
1068
    }
added line number to commit ...
Yuki Kimoto authored on 2013-04-12
1069
    elsif ($line =~ /^\+\+\+/ || $line =~ /^---/) { next }
1070
    elsif ($line =~ /^\-/) {
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1071
      $class = 'from_file';
added line number to commit ...
Yuki Kimoto authored on 2013-04-12
1072
      $before_line_num = $next_before_line_num++;
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1073
      $after_line_num = '';
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
1074
      $delete_line_count++;
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1075
    }
added line number to commit ...
Yuki Kimoto authored on 2013-04-12
1076
    elsif ($line =~ /^\+/) {
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1077
      $class = 'to_file';
1078
      $before_line_num = '';
added line number to commit ...
Yuki Kimoto authored on 2013-04-12
1079
      $after_line_num = $next_after_line_num++;
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
1080
      $add_line_count++;
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1081
    }
fixed blob diff line number ...
Yuki Kimoto authored on 2013-06-01
1082
    elsif ($line =~ /^Binary files/) {
1083
      $class = 'binary_file';
1084
      $diff_info->{binary} = 1;
1085
    }
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1086
    elsif ($line =~ /^ /) {
1087
      $class = 'diff';
added line number to commit ...
Yuki Kimoto authored on 2013-04-12
1088
      $before_line_num = $next_before_line_num++;
1089
      $after_line_num = $next_after_line_num++;
added line number logic to c...
Yuki Kimoto authored on 2013-04-12
1090
    }
1091
    else { next }
cleanup commit page
Yuki Kimoto authored on 2013-04-12
1092
    
1093
    my $line_data = {
1094
      value => $line,
1095
      class => $class,
1096
      before_line_num => $before_line_num,
1097
      after_line_num => $after_line_num
1098
    };
1099
    push @lines, $line_data;
improved commit page design
Yuki Kimoto authored on 2013-04-12
1100
  }
1101
  
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
1102
  # Diff info
1103
  my $diff_line_count = $add_line_count + $delete_line_count;
1104
  my $add_block_count
1105
    = $diff_line_count == 0
1106
    ? 0
1107
    : floor(($add_line_count * 5) / $diff_line_count);
1108
  my $delete_block_count
1109
    = $diff_line_count == 0
1110
    ? 0
1111
    : floor(($delete_line_count * 5) / $diff_line_count);
1112
  
fixed blob diff line number ...
Yuki Kimoto authored on 2013-06-01
1113
  $diff_info->{add_line_count} = $add_line_count;
1114
  $diff_info->{delete_line_count} = $delete_line_count;
1115
  $diff_info->{add_block_count} = $add_block_count;
1116
  $diff_info->{delete_block_count} = $delete_block_count;
1117
  
add diff status bar to commi...
Yuki Kimoto authored on 2013-05-30
1118
  return (\@lines, $diff_info);
improved commit page design
Yuki Kimoto authored on 2013-04-12
1119
}
1120

            
rename parse_commit to get_c...
Yuki Kimoto authored on 2013-05-01
1121
sub get_commit {
cleanup
Yuki Kimoto authored on 2013-03-19
1122
  my ($self, $user, $project, $id) = @_;
copy gitweblite soruce code
root authored on 2012-11-23
1123
  
1124
  # Git rev-list
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
1125
  my @cmd = $self->cmd_rep(
cleanup
Yuki Kimoto authored on 2013-03-19
1126
    $user,
1127
    $project,
1128
    'rev-list',
1129
    '--parents',
1130
    '--header',
1131
    '--max-count=1',
1132
    $id,
1133
    '--'
1134
  );
copy gitweblite soruce code
root authored on 2012-11-23
1135
  open my $fh, '-|', @cmd
1136
    or croak 'Open git-rev-list failed';
1137
  
1138
  # Parse commit
1139
  local $/ = "\0";
cleanup encoding
Yuki Kimoto authored on 2016-04-05
1140
  my $content = <$fh>;
1141
  $content = $self->_dec($content);
cleanup
Yuki Kimoto authored on 2013-05-13
1142
  return unless defined $content;
copy gitweblite soruce code
root authored on 2012-11-23
1143
  my $commit = $self->parse_commit_text($content, 1);
cleanup branch
Yuki Kimoto authored on 2016-04-16
1144
  close $fh;
1145

            
1146
  return $commit;
1147
}
1148

            
1149
sub get_commit_new {
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
1150
  my ($self, $rep, $id) = @_;
cleanup branch
Yuki Kimoto authored on 2016-04-16
1151
  
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
1152
  my $git_dir = $rep->{git_dir};
1153
  my $work_tree = $rep->{work_tree};
cleanup branch
Yuki Kimoto authored on 2016-04-16
1154
  
1155
  # Git rev-list
cleanup cmd
Yuki Kimoto authored on 2016-04-16
1156
  my @cmd = $self->cmd(
cleanup rep_info
Yuki Kimoto authored on 2016-04-16
1157
    $rep,
1158
    'rev-list',
1159
    '--parents',
1160
    '--header',
1161
    '--max-count=1',
1162
    $id,
1163
    '--'
cleanup branch
Yuki Kimoto authored on 2016-04-16
1164
  );
1165
  open my $fh, '-|', @cmd
1166
    or croak 'Open git-rev-list failed';
1167
  
1168
  # Parse commit
1169
  local $/ = "\0";
1170
  my $content = <$fh>;
1171
  $content = $self->_dec($content);
1172
  return unless defined $content;
1173
  my $commit = $self->parse_commit_text($content, 1);
copy gitweblite soruce code
root authored on 2012-11-23
1174
  close $fh;
1175

            
1176
  return $commit;
1177
}
1178

            
1179
sub parse_commit_text {
1180
  my ($self, $commit_text, $withparents) = @_;
1181
  
1182
  my @commit_lines = split '\n', $commit_text;
1183
  my %commit;
1184

            
1185
  pop @commit_lines; # Remove '\0'
1186
  return unless @commit_lines;
1187

            
1188
  my $header = shift @commit_lines;
1189
  return if $header !~ m/^[0-9a-fA-F]{40}/;
1190
  
1191
  ($commit{id}, my @parents) = split ' ', $header;
1192
  while (my $line = shift @commit_lines) {
1193
    last if $line eq "\n";
1194
    if ($line =~ m/^tree ([0-9a-fA-F]{40})$/) {
1195
      $commit{tree} = $1;
1196
    } elsif ((!defined $withparents) && ($line =~ m/^parent ([0-9a-fA-F]{40})$/)) {
1197
      push @parents, $1;
1198
    } elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) {
1199
      $commit{author} = $1;
1200
      $commit{author_epoch} = $2;
1201
      $commit{author_tz} = $3;
1202
      if ($commit{author} =~ m/^([^<]+) <([^>]*)>/) {
1203
        $commit{author_name}  = $1;
1204
        $commit{author_email} = $2;
1205
      } else {
1206
        $commit{author_name} = $commit{author};
1207
      }
1208
    } elsif ($line =~ m/^committer (.*) ([0-9]+) (.*)$/) {
1209
      $commit{committer} = $1;
1210
      $commit{committer_epoch} = $2;
1211
      $commit{committer_tz} = $3;
1212
      if ($commit{committer} =~ m/^([^<]+) <([^>]*)>/) {
1213
        $commit{committer_name}  = $1;
1214
        $commit{committer_email} = $2;
1215
      } else {
1216
        $commit{committer_name} = $commit{committer};
1217
      }
1218
    }
1219
  }
1220
  return unless defined $commit{tree};
1221
  $commit{parents} = \@parents;
1222
  $commit{parent} = $parents[0];
1223

            
1224
  for my $title (@commit_lines) {
1225
    $title =~ s/^    //;
1226
    if ($title ne '') {
1227
      $commit{title} = $self->_chop_str($title, 80, 5);
1228
      # remove leading stuff of merges to make the interesting part visible
1229
      if (length($title) > 50) {
1230
        $title =~ s/^Automatic //;
1231
        $title =~ s/^merge (of|with) /Merge ... /i;
1232
        if (length($title) > 50) {
1233
          $title =~ s/(http|rsync):\/\///;
1234
        }
1235
        if (length($title) > 50) {
1236
          $title =~ s/(master|www|rsync)\.//;
1237
        }
1238
        if (length($title) > 50) {
1239
          $title =~ s/kernel.org:?//;
1240
        }
1241
        if (length($title) > 50) {
1242
          $title =~ s/\/pub\/scm//;
1243
        }
1244
      }
1245
      $commit{title_short} = $self->_chop_str($title, 50, 5);
1246
      last;
1247
    }
1248
  }
1249
  if (! defined $commit{title} || $commit{title} eq '') {
1250
    $commit{title} = $commit{title_short} = '(no commit message)';
1251
  }
1252
  # remove added spaces
1253
  for my $line (@commit_lines) {
1254
    $line =~ s/^    //;
1255
  }
1256
  $commit{comment} = \@commit_lines;
1257

            
1258
  my $age = time - $commit{committer_epoch};
1259
  $commit{age} = $age;
1260
  $commit{age_string} = $self->_age_string($age);
add time zone system
Yuki Kimoto authored on 2014-03-08
1261
  
1262
  # GMT
1263
  {
support atom feed of commits...
Yuki Kimoto authored on 2014-10-03
1264
    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($commit{committer_epoch});
add time zone system
Yuki Kimoto authored on 2014-03-08
1265
    $commit{age_string_date} = sprintf '%4d-%02d-%02d', 1900 + $year, $mon + 1, $mday;
1266
    $commit{age_string_datetime} = sprintf '%4d-%02d-%02d %02d:%02d:%02d',
1267
      1900 + $year, $mon + 1, $mday, $hour, $min, $sec;
1268
  }
1269
  
1270
  # Local Time
1271
  {
1272
    my $time_zone_second = $self->time_zone_second || 0;
1273
    
support atom feed of commits...
Yuki Kimoto authored on 2014-10-03
1274
    my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($commit{committer_epoch} + $time_zone_second);
add time zone system
Yuki Kimoto authored on 2014-03-08
1275
    $commit{age_string_date_local}
1276
      = sprintf '%4d-%02d-%02d', 1900 + $year, $mon + 1, $mday;
support atom feed of commits...
Yuki Kimoto authored on 2014-10-03
1277
    $commit{age_string_datetime_local} = sprintf '%4d-%02d-%02d %02d:%02d:%02d',
add time zone system
Yuki Kimoto authored on 2014-03-08
1278
      1900 + $year, $mon + 1, $mday, $hour, $min, $sec;
1279
  }
support atom feed of commits...
Yuki Kimoto authored on 2014-10-03
1280

            
copy gitweblite soruce code
root authored on 2012-11-23
1281
  return \%commit;
1282
}
1283

            
cleanup
Yuki Kimoto authored on 2013-04-30
1284
sub get_commits {
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
1285
  my ($self, $user, $project, $rev, $maxcount, $skip, $file, @args) = @_;
copy gitweblite soruce code
root authored on 2012-11-23
1286

            
cleanup
Yuki Kimoto authored on 2013-03-19
1287
  # Get Commits
copy gitweblite soruce code
root authored on 2012-11-23
1288
  $maxcount ||= 1;
1289
  $skip ||= 0;
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
1290
  my @cmd = $self->cmd_rep(
cleanup
Yuki Kimoto authored on 2013-03-19
1291
    $user,
1292
    $project,
1293
    'rev-list',
1294
    '--header',
1295
    @args,
1296
    ('--max-count=' . $maxcount),
1297
    ('--skip=' . $skip),
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
1298
    $rev,
cleanup
Yuki Kimoto authored on 2013-03-19
1299
    '--',
added branch long name featu...
Yuki Kimoto authored on 2013-05-12
1300
    (defined $file && length $file ? ($file) : ())
cleanup
Yuki Kimoto authored on 2013-03-19
1301
  );
copy gitweblite soruce code
root authored on 2012-11-23
1302
  open my $fh, '-|', @cmd
1303
    or croak 'Open git-rev-list failed';
cleanup
Yuki Kimoto authored on 2013-03-19
1304
  
1305
  # Prase Commits text
copy gitweblite soruce code
root authored on 2012-11-23
1306
  local $/ = "\0";
1307
  my @commits;
cleanup encoding
Yuki Kimoto authored on 2016-04-05
1308
  my @lines = <$fh>;
1309
  for my $line (@lines) {
1310
    $line = $self->_dec($line);
copy gitweblite soruce code
root authored on 2012-11-23
1311
    my $commit = $self->parse_commit_text($line);
1312
    push @commits, $commit;
1313
  }
1314
  close $fh;
cleanup
Yuki Kimoto authored on 2013-03-19
1315
  
copy gitweblite soruce code
root authored on 2012-11-23
1316
  return \@commits;
1317
}
1318

            
1319
sub parse_date {
1320
  my $self = shift;
1321
  my $epoch = shift;
1322
  my $tz = shift || '-0000';
1323
  
1324
  # Parse data
1325
  my %date;
1326
  my @months = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/;
1327
  my @days = qw/Sun Mon Tue Wed Thu Fri Sat/;
1328
  my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime $epoch;
1329
  $date{hour} = $hour;
1330
  $date{minute} = $min;
1331
  $date{mday} = $mday;
1332
  $date{day} = $days[$wday];
1333
  $date{month} = $months[$mon];
1334
  $date{rfc2822} = sprintf '%s, %d %s %4d %02d:%02d:%02d +0000',
1335
    $days[$wday], $mday, $months[$mon], 1900 + $year, $hour ,$min, $sec;
1336
  $date{'mday-time'} = sprintf '%d %s %02d:%02d',
1337
    $mday, $months[$mon], $hour ,$min;
1338
  $date{'iso-8601'}  = sprintf '%04d-%02d-%02dT%02d:%02d:%02dZ',
1339
    1900 + $year, 1+$mon, $mday, $hour ,$min, $sec;
1340
  my ($tz_sign, $tz_hour, $tz_min) = ($tz =~ m/^([-+])(\d\d)(\d\d)$/);
1341
  $tz_sign = ($tz_sign eq '-' ? -1 : +1);
1342
  my $local = $epoch + $tz_sign * ((($tz_hour*60) + $tz_min) * 60);
1343
  ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime $local;
1344
  $date{hour_local} = $hour;
1345
  $date{minute_local} = $min;
1346
  $date{tz_local} = $tz;
1347
  $date{'iso-tz'} = sprintf('%04d-%02d-%02d %02d:%02d:%02d %s',
1348
    1900 + $year, $mon+1, $mday, $hour, $min, $sec, $tz);
1349
  
1350
  return \%date;
1351
}
1352

            
cleanup
Yuki Kimoto authored on 2013-05-14
1353
sub parsed_diff_tree_line {
copy gitweblite soruce code
root authored on 2012-11-23
1354
  my ($self, $line) = @_;
1355
  
1356
  return $line if ref $line eq 'HASH';
1357

            
cleanup
Yuki Kimoto authored on 2013-05-14
1358
  return $self->parse_diff_tree_line($line);
copy gitweblite soruce code
root authored on 2012-11-23
1359
}
1360

            
cleanup
Yuki Kimoto authored on 2013-05-14
1361
sub parse_diff_tree_line {
copy gitweblite soruce code
root authored on 2012-11-23
1362
  my ($self, $line) = @_;
1363

            
1364
  my %res;
1365
  if ($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/) {
1366
    $res{from_mode} = $1;
1367
    $res{to_mode} = $2;
1368
    $res{from_id} = $3;
1369
    $res{to_id} = $4;
1370
    $res{status} = $5;
1371
    $res{similarity} = $6;
1372
    if ($res{status} eq 'R' || $res{status} eq 'C') {
1373
      ($res{from_file}, $res{to_file}) = map { $self->_unquote($_) } split("\t", $7);
1374
    } else {
1375
      $res{from_file} = $res{to_file} = $res{file} = $self->_unquote($7);
1376
    }
1377
  }
1378
  elsif ($line =~ s/^(::+)((?:[0-7]{6} )+)((?:[0-9a-fA-F]{40} )+)([a-zA-Z]+)\t(.*)$//) {
1379
    $res{nparents}  = length($1);
1380
    $res{from_mode} = [ split(' ', $2) ];
1381
    $res{to_mode} = pop @{$res{from_mode}};
1382
    $res{from_id} = [ split(' ', $3) ];
1383
    $res{to_id} = pop @{$res{from_id}};
1384
    $res{status} = [ split('', $4) ];
1385
    $res{to_file} = $self->_unquote($5);
1386
  }
1387
  elsif ($line =~ m/^([0-9a-fA-F]{40})$/) { $res{commit} = $1 }
1388

            
1389
  return \%res;
1390
}
1391

            
1392
sub parse_ls_tree_line {
1393
  my ($self, $line) = @_;
1394
  my %opts = @_;
1395
  my %res;
1396

            
1397
  if ($opts{'-l'}) {
1398
    $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40}) +(-|[0-9]+)\t(.+)$/s;
1399

            
1400
    $res{mode} = $1;
1401
    $res{type} = $2;
1402
    $res{hash} = $3;
1403
    $res{size} = $4;
1404
    if ($opts{'-z'}) { $res{name} = $5 }
1405
    else { $res{name} = $self->_unquote($5) }
1406
  }
1407
  else {
1408
    $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/s;
1409

            
1410
    $res{mode} = $1;
1411
    $res{type} = $2;
1412
    $res{hash} = $3;
1413
    if ($opts{'-z'}) { $res{name} = $4 }
1414
    else { $res{name} = $self->_unquote($4) }
1415
  }
1416

            
1417
  return \%res;
1418
}
1419

            
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1420
sub import_branch {
complete branch import featu...
Yuki Kimoto authored on 2013-08-15
1421
  my ($self, $user, $project, $branch, $remote_user, $remote_project, $remote_branch, $opt) = @_;
1422
  
1423
  my $force = $opt->{force};
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1424
  
1425
  # Git pull
cleanup
Yuki Kimoto authored on 2016-04-14
1426
  my $remote_rep = $self->app->rep_path($remote_user, $remote_project);
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
1427
  my @cmd = $self->cmd_rep(
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1428
    $user,
1429
    $project,
1430
    'fetch',
1431
    $remote_rep,
complete branch import featu...
Yuki Kimoto authored on 2013-08-15
1432
    ($force ? '+' : '') . "refs/heads/$remote_branch:refs/heads/$branch"
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1433
  );
1434
  
fix bug that in CGI reposito...
Yuki Kimoto authored on 2015-11-05
1435
  Gitprep::Util::run_command(@cmd)
complete branch import featu...
Yuki Kimoto authored on 2013-08-15
1436
    or croak 'Open git fetch for import_branch failed';
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1437
}
1438

            
copy gitweblite soruce code
root authored on 2012-11-23
1439
sub search_bin {
1440
  my $self = shift;
1441
  
1442
  # Search git bin
1443
  my $env_path = $ENV{PATH};
1444
  my @paths = split /:/, $env_path;
1445
  for my $path (@paths) {
1446
    $path =~ s#/$##;
1447
    my $bin = "$path/git";
1448
    if (-f $bin) {
1449
      return $bin;
1450
      last;
1451
    }
1452
  }
improved git path searching
Yuki Kimoto authored on 2012-11-23
1453
  
1454
  my $local_bin = '/usr/local/bin/git';
1455
  return $local_bin if -f $local_bin;
1456
  
1457
  my $bin = '/usr/bin/git';
1458
  return $bin if -f $bin;
1459
  
copy gitweblite soruce code
root authored on 2012-11-23
1460
  return;
1461
}
1462

            
improved create repository f...
Yuki Kimoto authored on 2013-03-21
1463
sub separated_commit {
1464
  my ($self, $user, $project, $rev1, $rev2) = @_;
1465
  
1466
  # Command "git diff-tree"
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
1467
  my @cmd = $self->cmd_rep(
improved create repository f...
Yuki Kimoto authored on 2013-03-21
1468
    $user,
1469
    $project,
1470
    'show-branch',
1471
    $rev1,
1472
    $rev2
1473
  );
1474
  open my $fh, "-|", @cmd
1475
    or croak 500, "Open git-show-branch failed";
1476

            
1477
  my $commits = [];
1478
  my $start;
1479
  my @lines = <$fh>;
1480
  my $last_line = pop @lines;
1481
  my $commit;
1482
  if (defined $last_line) {
1483
      my ($id) = $last_line =~ /^.*?\[(.+)?\]/;
rename parse_commit to get_c...
Yuki Kimoto authored on 2013-05-01
1484
      $commit = $self->get_commit($user, $project, $id);
improved create repository f...
Yuki Kimoto authored on 2013-03-21
1485
  }
1486

            
1487
  return $commit;
1488
}
1489

            
copy gitweblite soruce code
root authored on 2012-11-23
1490
sub snapshot_name {
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
1491
  my ($self, $project, $rev) = @_;
copy gitweblite soruce code
root authored on 2012-11-23
1492

            
1493
  my $name = $project;
1494
  $name =~ s,([^/])/*\.git$,$1,;
1495
  $name = basename($name);
1496
  # sanitize name
1497
  $name =~ s/[[:cntrl:]]/?/g;
1498

            
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
1499
  my $ver = $rev;
1500
  if ($rev =~ /^[0-9a-fA-F]+$/) {
1501
    my $full_hash = $self->id($project, $rev);
1502
    if ($full_hash =~ /^$rev/ && length($rev) > 7) {
1503
      $ver = $self->short_id($project, $rev);
copy gitweblite soruce code
root authored on 2012-11-23
1504
    }
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
1505
  } elsif ($rev =~ m!^refs/tags/(.*)$!) {
copy gitweblite soruce code
root authored on 2012-11-23
1506
    $ver = $1;
1507
  } else {
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
1508
    if ($rev =~ m!^refs/(?:heads|remotes)/(.*)$!) {
copy gitweblite soruce code
root authored on 2012-11-23
1509
      $ver = $1;
1510
    }
impved merge commit logic
Yuki Kimoto authored on 2013-06-01
1511
    $ver .= '-' . $self->short_id($project, $rev);
copy gitweblite soruce code
root authored on 2012-11-23
1512
  }
1513
  $ver =~ s!/!.!g;
1514

            
1515
  $name = "$name-$ver";
1516

            
1517
  return wantarray ? ($name, $name) : $name;
1518
}
1519

            
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1520
sub timestamp {
1521
  my ($self, $date) = @_;
1522
  
1523
  # Time stamp
1524
  my $strtime = $date->{rfc2822};
1525
  my $localtime_format = '(%02d:%02d %s)';
1526
  if ($date->{hour_local} < 6) { $localtime_format = '(%02d:%02d %s)' }
1527
  $strtime .= ' ' . sprintf(
1528
    $localtime_format,
1529
    $date->{hour_local},
1530
    $date->{minute_local},
1531
    $date->{tz_local}
1532
  );
1533

            
1534
  return $strtime;
1535
}
1536

            
1537
sub trees {
1538
  my ($self, $user, $project, $rev, $dir) = @_;
1539
  $dir = '' unless defined $dir;
1540
  
1541
  # Get tree
1542
  my $tid;
1543
  if (defined $dir && $dir ne '') {
cleanup method
Yuki Kimoto authored on 2016-04-16
1544
    $tid = $self->path_to_hash($self->app->rep_info($user, $project), $rev, $dir, 'tree');
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1545
  }
1546
  else {
1547
    my $commit = $self->get_commit($user, $project, $rev);
1548
    $tid = $commit->{tree};
1549
  }
1550
  my @entries = ();
1551
  my $show_sizes = 0;
cleanup cmd_rep, cmd_rep_wor...
Yuki Kimoto authored on 2016-04-14
1552
  my @cmd = $self->cmd_rep(
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1553
    $user,
1554
    $project,
1555
    'ls-tree',
1556
    '-z',
1557
    ($show_sizes ? '-l' : ()),
1558
    $tid
1559
  );
1560
  open my $fh, '-|', @cmd
1561
    or $self->croak('Open git-ls-tree failed');
1562
  {
1563
    local $/ = "\0";
cleanup encoding
Yuki Kimoto authored on 2016-04-05
1564
    @entries = <$fh>;
1565
    @entries = map { chomp; $self->_dec($_) } @entries;
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1566
  }
1567
  close $fh
1568
    or $self->croak(404, "Reading tree failed");
1569

            
1570
  # Parse tree
1571
  my $trees;
1572
  for my $line (@entries) {
1573
    my $tree = $self->parse_ls_tree_line($line, -z => 1, -l => $show_sizes);
1574
    $tree->{mode_str} = $self->_mode_str($tree->{mode});
1575
    
1576
    # Commit log
1577
    my $path = defined $dir && $dir ne '' ? "$dir/$tree->{name}" : $tree->{name};
cleanup methods
Yuki Kimoto authored on 2016-04-16
1578
    my $commit = $self->last_change_commit($self->app->rep_info($user, $project), $rev, $path);
change pull feature to impor...
Yuki Kimoto authored on 2013-08-14
1579
    $tree->{commit} = $commit;
1580
    
1581
    push @$trees, $tree;
1582
  }
1583
  $trees = [sort {$b->{type} cmp $a->{type} || $a->{name} cmp $b->{name}} @$trees];
1584
  
1585
  return $trees;
1586
}
1587

            
refactored
Xavier Caron authored on 2013-08-30
1588
sub _age_ago {
1589
  my($self,$unit,$age) = @_;
1590

            
does not use plural when uni...
Xavier Caron authored on 2013-08-30
1591
  return $age . " $unit" . ( $unit =~ /^(sec|min)$/ ? "" : ( $age > 1 ? "s" : "" ) ) . " ago";
refactored
Xavier Caron authored on 2013-08-30
1592
}
1593

            
copy gitweblite soruce code
root authored on 2012-11-23
1594
sub _age_string {
1595
  my ($self, $age) = @_;
1596
  my $age_str;
1597

            
added commit datetime to pro...
Yuki Kimoto authored on 2013-05-03
1598
  if ($age >= 60 * 60 * 24 * 365) {
refactored
Xavier Caron authored on 2013-08-30
1599
    $age_str = $self->_age_ago(year => (int $age/60/60/24/365));
added commit datetime to pro...
Yuki Kimoto authored on 2013-05-03
1600
  } elsif ($age >= 60 * 60 * 24 * (365/12)) {
refactored
Xavier Caron authored on 2013-08-30
1601
    $age_str = $self->_age_ago(month => int $age/60/60/24/(365/12));
added commit datetime to pro...
Yuki Kimoto authored on 2013-05-03
1602
  } elsif ($age >= 60 * 60 * 24 * 7) {
refactored
Xavier Caron authored on 2013-08-30
1603
    $age_str = $self->_age_ago(week => int $age/60/60/24/7);
added commit datetime to pro...
Yuki Kimoto authored on 2013-05-03
1604
  } elsif ($age >= 60 * 60 * 24) {
refactored
Xavier Caron authored on 2013-08-30
1605
    $age_str = $self->_age_ago(day => int $age/60/60/24);
added commit datetime to pro...
Yuki Kimoto authored on 2013-05-03
1606
  } elsif ($age >= 60 * 60) {
refactored
Xavier Caron authored on 2013-08-30
1607
    $age_str = $self->_age_ago(hour => int $age/60/60);
added commit datetime to pro...
Yuki Kimoto authored on 2013-05-03
1608
  } elsif ($age >= 60) {
refactored
Xavier Caron authored on 2013-08-30
1609
    $age_str = $self->_age_ago(min => int $age/60);
added commit datetime to pro...
Yuki Kimoto authored on 2013-05-03
1610
  } elsif ($age >= 1) {
refactored
Xavier Caron authored on 2013-08-30
1611
    $age_str = $self->_age_ago(sec => int $age);
copy gitweblite soruce code
root authored on 2012-11-23
1612
  } else {
fixed a typo
Xavier Caron authored on 2013-08-30
1613
    $age_str .= 'right now';
copy gitweblite soruce code
root authored on 2012-11-23
1614
  }
cleanup blob and raw page
Yuki Kimoto authored on 2013-05-02
1615
  
1616
  $age_str =~ s/^1 /a /;
more phonetically correct
Xavier Caron authored on 2013-08-30
1617
  $age_str =~ s/^a hour/an hour/;
cleanup blob and raw page
Yuki Kimoto authored on 2013-05-02
1618
  
copy gitweblite soruce code
root authored on 2012-11-23
1619
  return $age_str;
1620
}
1621

            
1622
sub _chop_str {
1623
  my $self = shift;
1624
  my $str = shift;
1625
  my $len = shift;
1626
  my $add_len = shift || 10;
1627
  my $where = shift || 'right';
1628

            
1629
  if ($where eq 'center') {
1630
    # Filler is length 5
1631
    return $str if ($len + 5 >= length($str));
1632
    $len = int($len/2);
1633
  } else {
1634
    # Filler is length 4
1635
    return $str if ($len + 4 >= length($str)); 
1636
  }
1637

            
1638
  # Regexps: ending and beginning with word part up to $add_len
1639
  my $endre = qr/.{$len}\w{0,$add_len}/;
1640
  my $begre = qr/\w{0,$add_len}.{$len}/;
1641

            
1642
  if ($where eq 'left') {
1643
    $str =~ m/^(.*?)($begre)$/;
1644
    my ($lead, $body) = ($1, $2);
1645
    if (length($lead) > 4) {
1646
      $lead = ' ...';
1647
    }
1648
    return "$lead$body";
1649

            
1650
  } elsif ($where eq 'center') {
1651
    $str =~ m/^($endre)(.*)$/;
1652
    my ($left, $str)  = ($1, $2);
1653
    $str =~ m/^(.*?)($begre)$/;
1654
    my ($mid, $right) = ($1, $2);
1655
    if (length($mid) > 5) {
1656
      $mid = ' ... ';
1657
    }
1658
    return "$left$mid$right";
1659

            
1660
  } else {
1661
    $str =~ m/^($endre)(.*)$/;
1662
    my $body = $1;
1663
    my $tail = $2;
1664
    if (length($tail) > 4) {
1665
      $tail = '... ';
1666
    }
1667
    return "$body$tail";
1668
  }
1669
}
1670

            
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1671
sub decide_encoding {
cleanup methods
Yuki Kimoto authored on 2016-04-16
1672
  my ($self, $rep_info, $lines) = @_;
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1673
  
1674
  my $guess_encoding_str = $self->app->dbi->model('project')->select(
1675
    'guess_encoding',
cleanup methods
Yuki Kimoto authored on 2016-04-16
1676
    where => {user_id => $rep_info->{user}, name => $rep_info->{project}}
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1677
  )->value;
cleanup encoding_suspects
Yuki Kimoto authored on 2016-04-05
1678
  
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1679
  my @guess_encodings;
cleanup blame
Yuki Kimoto authored on 2016-04-16
1680
  if (defined $guess_encoding_str && length $guess_encoding_str) {
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1681
    @guess_encodings = split(/\s*,\s*/, $guess_encoding_str);
1682
  }
cleanup encoding_suspects
Yuki Kimoto authored on 2016-04-05
1683
  
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1684
  my $encoding;
1685
  if (@guess_encodings) {
1686
    my @new_lines;
1687
    for (my $i = 0; $i < 100; $i++) {
1688
      last unless defined $lines->[$i];
1689
      push @new_lines, $lines->[$i];
1690
    }
1691
    
1692
    my $str = join('', @new_lines);
1693

            
1694
    my $ret = Encode::Guess->guess($str, @guess_encodings);
1695
    
improve dec_guess logic
Yuki Kimoto authored on 2016-04-05
1696
    if (ref $ret) {
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1697
      $encoding = $ret->name;
improve dec_guess logic
Yuki Kimoto authored on 2016-04-05
1698
    }
1699
    else {
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1700
      $encoding = $self->default_encoding
cleanup encoding_suspects
Yuki Kimoto authored on 2016-04-05
1701
    }
1702
  }
1703
  else {
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1704
    $encoding = $self->default_encoding;
cleanup encoding_suspects
Yuki Kimoto authored on 2016-04-05
1705
  }
1706
  
remove [basic]encoding_suspe...
Yuki Kimoto authored on 2016-04-06
1707
  return $encoding;
Supported specific character...
Tetsuya Hayashi authored on 2014-03-15
1708
}
1709

            
cleanuP
Yuki Kimoto authored on 2016-04-16
1710
sub _age_string_date {
1711
  my ($self, $age) = @_;
1712

            
1713
  my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($age);
1714
  my $age_string_date = sprintf '%4d-%02d-%02d', 1900 + $year, $mon + 1, $mday;
1715
  
1716
  return $age_string_date;
1717
}
1718

            
1719
sub _age_string_date_local {
1720
  my ($self, $age) = @_;
1721
  
1722
  my $time_zone_second = $self->time_zone_second || 0;
1723
  
1724
  my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime($age + $time_zone_second);
1725
  my $age_string_date_local = sprintf '%4d-%02d-%02d', 1900 + $year, $mon + 1, $mday;
1726
  
1727
  return $age_string_date_local;
1728
}
1729

            
cleanup
Yuki Kimoto authored on 2013-05-14
1730
sub _dec {
revert encoding support
Yuki Kimoto authored on 2013-11-22
1731
  my ($self, $str) = @_;
improved create repository f...
Yuki Kimoto authored on 2013-03-21
1732
  
Renamed encoding to default_...
Tetsuya Hayashi authored on 2014-03-15
1733
  my $enc = $self->default_encoding;
improved create repository f...
Yuki Kimoto authored on 2013-03-21
1734
  
cleanup encoding logic
Yuki Kimoto authored on 2016-04-05
1735
  $str = decode($enc, $str);
improved create repository f...
Yuki Kimoto authored on 2013-03-21
1736
  
cleanup encoding logic
Yuki Kimoto authored on 2016-04-05
1737
  return $str;
added README commited rep fe...
Yuki Kimoto authored on 2013-03-28
1738
}
1739

            
revert encoding support
Yuki Kimoto authored on 2013-11-22
1740
sub _enc {
1741
  my ($self, $str) = @_;
1742
  
Renamed encoding to default_...
Tetsuya Hayashi authored on 2014-03-15
1743
  my $enc = $self->default_encoding;
revert encoding support
Yuki Kimoto authored on 2013-11-22
1744
  
1745
  return encode($enc, $str);
1746
}
1747

            
improved create repository f...
Yuki Kimoto authored on 2013-03-21
1748
sub _mode_str {
1749
  my $self = shift;
1750
  my $mode = oct shift;
1751

            
1752
  # Mode to string
1753
  if ($self->_s_isgitlink($mode)) { return 'm---------' }
1754
  elsif (S_ISDIR($mode & S_IFMT)) { return 'drwxr-xr-x' }
1755
  elsif (S_ISLNK($mode)) { return 'lrwxrwxrwx' }
1756
  elsif (S_ISREG($mode)) {
1757
    if ($mode & S_IXUSR) {
1758
      return '-rwxr-xr-x';
1759
    } else {
1760
      return '-rw-r--r--'
1761
    }
1762
  } else { return '----------' }
1763
  
1764
  return;
1765
}
1766

            
1767
sub _s_isgitlink {
1768
  my ($self, $mode) = @_;
1769
  
1770
  # Check if git link
1771
  my $s_ifgitlink = 0160000;
1772
  return (($mode & S_IFMT) == $s_ifgitlink)
copy gitweblite soruce code
root authored on 2012-11-23
1773
}
1774

            
1775
sub _slurp {
1776
  my ($self, $file) = @_;
1777
  
1778
  # Slurp
1779
  open my $fh, '<', $file
1780
    or croak qq/Can't open file "$file": $!/;
cleanup
Yuki Kimoto authored on 2013-11-16
1781
  my $content = do { local $/; scalar <$fh> };
copy gitweblite soruce code
root authored on 2012-11-23
1782
  close $fh;
1783
  
1784
  return $content;
1785
}
1786

            
1787
sub _unquote {
1788
  my ($self, $str) = @_;
1789
  
1790
  # Unquote function
1791
  my $unq = sub {
1792
    my $seq = shift;
1793
    my %escapes = (
1794
      t => "\t",
1795
      n => "\n",
1796
      r => "\r",
1797
      f => "\f",
1798
      b => "\b",
1799
      a => "\a",
1800
      e => "\e",
1801
      v => "\013",
1802
    );
1803

            
1804
    if ($seq =~ m/^[0-7]{1,3}$/) { return chr oct $seq }
1805
    elsif (exists $escapes{$seq}) { return $escapes{$seq} }
1806
    
1807
    return $seq;
1808
  };
1809
  
1810
  # Unquote
1811
  if ($str =~ m/^"(.*)"$/) {
1812
    $str = $1;
1813
    $str =~ s/\\([^0-7]|[0-7]{1,3})/$unq->($1)/eg;
1814
  }
1815
  
1816
  return $str;
1817
}
1818

            
1819
1;