File Coverage

blib/lib/App/SCM/Digest/SCM/Git.pm
Criterion Covered Total %
statement 84 97 86.6
branch 5 14 35.7
condition 1 2 50.0
subroutine 18 19 94.7
pod 0 13 0.0
total 108 145 74.4


line stmt bran cond sub pod time code
1             package App::SCM::Digest::SCM::Git;
2              
3 8     8   61241 use strict;
  8         29  
  8         188  
4 8     8   36 use warnings;
  8         15  
  8         197  
5              
6 8     8   303 use App::SCM::Digest::Utils qw(system_ad);
  8         18  
  8         308  
7              
8 8     8   2037 use autodie;
  8         78227  
  8         32  
9 8     8   44950 use List::Util qw(first);
  8         17  
  8         7701  
10              
11             sub new
12             {
13 20     20 0 8031 my ($class) = @_;
14              
15 20         90226 my $res = system("git --version >/dev/null");
16 20 50       299 if ($res != 0) {
17 0         0 die "Unable to find git executable.";
18             }
19              
20 20         194 my $self = {};
21 20         113 bless $self, $class;
22 20         548 return $self;
23             }
24              
25             sub clone
26             {
27 10     10 0 85 my ($self, $url, $name) = @_;
28              
29 10         145 my $res = system_ad("git clone $url $name");
30              
31 2         1310 return 1;
32             }
33              
34             sub open_repository
35             {
36 7     7 0 376 my ($self, $path) = @_;
37              
38 7         72 chdir $path;
39              
40 4         2229 return 1;
41             }
42              
43             sub is_usable
44             {
45 2     2 0 6 my ($self) = @_;
46              
47 2         5315 my @branches = `git branch -l`;
48 2 50       101 return (@branches ? 1 : 0);
49             }
50              
51             sub prune
52             {
53 8     8 0 15 my ($self) = @_;
54              
55 8   50     32 my $original_branch = $self->branch_name() || '';
56 8         51 my $current_branch = $original_branch;
57              
58 8         48593 my @lines = `git remote prune origin`;
59 8         107 for my $line (@lines) {
60 0         0 chomp $line;
61 0 0       0 if (my ($branch) = ($line =~ /^ \* \[pruned\] origin\/(.*)$/)) {
62 0 0       0 if ($branch eq $current_branch) {
63 0         0 my @branches = @{$self->branches()};
  0         0  
64             my $other_branch =
65 0     0   0 first { $_->[0] ne $current_branch }
66 0         0 @branches;
67 0         0 $self->checkout($other_branch->[0]);
68 0         0 $current_branch = $other_branch->[0];
69             }
70 0         0 system_ad("git branch -D $branch");
71 0 0       0 if ($branch eq $original_branch) {
72 0         0 $original_branch = undef;
73             }
74             }
75             }
76 8 50       64 if ($original_branch) {
77 8         84 $self->checkout($original_branch);
78             }
79              
80 8         50 return 1;
81             }
82              
83             sub pull
84             {
85 8     8 0 29 my ($self) = @_;
86              
87 8         51 $self->prune();
88              
89 8         71 system_ad("git pull -X theirs");
90              
91 8         5854 return 1;
92             }
93              
94             sub branches
95             {
96 5     5 0 1889 my ($self) = @_;
97              
98             my @branches =
99 8         47 map { s/^\s+//; s/^origin\///; s/\s+$//; $_ }
  8         30  
  8         21  
  8         33  
100 12         79 grep { !/ -> / }
101 5         14430 map { chomp; $_ }
  12         70  
  12         45  
102             `git branch -r`;
103              
104 5         18 my @results;
105 5         40 my $current_branch = $self->branch_name();
106 5         36 for my $branch (@branches) {
107 8         65 $self->checkout($branch);
108 8         57 $self->pull();
109 8         31196 my $commit = `git log -1 --format="%H" $branch`;
110 8         95 chomp $commit;
111 8         125 push @results, [ $branch => $commit ];
112             }
113 5 100       32 if ($current_branch ne 'HEAD') {
114 4         38 $self->checkout($current_branch);
115             }
116              
117 5         83 return \@results;
118             }
119              
120             sub branch_name
121             {
122 16     16 0 911 my ($self) = @_;
123              
124             # todo: This prints a warning if there are no branches; there is
125             # probably a better way of dealing with this problem.
126 16         55704 my $branch = `git rev-parse --abbrev-ref HEAD 2>/dev/null`;
127 16         141 chomp $branch;
128              
129 16         257 return $branch;
130             }
131              
132             sub checkout
133             {
134 24     24 0 124 my ($self, $branch) = @_;
135              
136 24         323 system_ad("git checkout $branch");
137              
138 24         29318 return 1;
139             }
140              
141             sub commits_from
142             {
143 3     3 0 1016 my ($self, $branch, $from) = @_;
144              
145 3         23 $self->checkout($branch);
146 3         9753 my @new_commits = reverse map { chomp; $_ } `git rev-list $from..HEAD`;
  3         50  
  3         21  
147              
148 3         81 return \@new_commits;
149             }
150              
151             sub has
152             {
153 2     2 0 1172 my ($self, $id) = @_;
154              
155 2         7680 my $res = system("git show -s $id >/dev/null 2>&1");
156              
157 2         86 return ($res == 0);
158             }
159              
160             sub show
161             {
162 1     1 0 7 my ($self, $id) = @_;
163              
164 1         3560 my @data = `git show -s $id`;
165              
166 1         27 return \@data;
167             }
168              
169             sub show_all
170             {
171 1     1 0 968 my ($self, $id) = @_;
172              
173 1         3548 my @data = (`git show $id`);
174              
175 1         27 return \@data;
176             }
177              
178             1;
179              
180             __END__
181              
182             =head1 NAME
183              
184             App::SCM::Digest::SCM::Git
185              
186             =head1 DESCRIPTION
187              
188             Git L<App::SCM::Digest::SCM> implementation.
189              
190             =cut