File Coverage

blib/lib/App/Git/Workflow/Command/Take.pm
Criterion Covered Total %
statement 61 64 95.3
branch 7 12 58.3
condition 1 3 33.3
subroutine 11 11 100.0
pod 2 2 100.0
total 82 92 89.1


line stmt bran cond sub pod time code
1             package App::Git::Workflow::Command::Take;
2              
3             # Created on: 2015-06-05 11:38:28
4             # Create by: Ivan Wills
5             # $Id$
6             # $Revision$, $HeadURL$, $Date$
7             # $Revision$, $Source$, $Date$
8              
9 2     2   233673 use strict;
  2         12  
  2         60  
10 2     2   11 use warnings;
  2         4  
  2         47  
11 2     2   2072 use Pod::Usage ();
  2         116375  
  2         63  
12 2     2   2634 use Data::Dumper qw/Dumper/;
  2         15242  
  2         159  
13 2     2   1260 use English qw/ -no_match_vars /;
  2         7528  
  2         12  
14 2     2   1714 use App::Git::Workflow;
  2         114662  
  2         113  
15 2     2   939 use App::Git::Workflow::Command qw/get_options/;
  2         25364  
  2         119  
16 2     2   946 use Path::Tiny;
  2         12733  
  2         97  
17 2     2   1031 use File::Copy qw/copy/;
  2         4764  
  2         1314  
18              
19             our $VERSION = 0.8;
20             our $workflow = App::Git::Workflow->new;
21             our ($name) = $PROGRAM_NAME =~ m{^.*/(.*?)$}mxs;
22             our %option;
23              
24             sub run {
25 2     2 1 21474 my ($self) = @_;
26              
27 2         29 get_options( \%option, 'quiet|q', 'ours|mine', 'theirs', 'add|a!', );
28              
29             my @conflicts = (
30 2         11 map { /^ \s+ both \s (?:added|modified): \s+(.*)$/xms; $1 }
  2         31  
31 2         1571 grep { /^ \s+ both \s (?:added|modified): \s+/xms }
  22         199  
32             $workflow->git->status()
33             );
34              
35 2 100       17 if ( !@ARGV ) {
36 1         11 @ARGV = ('./');
37             }
38              
39             CONFLICT:
40 2         105 for my $conflict (@conflicts) {
41              
42             PATH:
43 2         6 for my $path (@ARGV) {
44 2         11 $path =~ s{^[.]/}{};
45 2 50       32 next PATH unless $conflict =~ /^\Q$path\E/;
46              
47 2         15 resolve($conflict);
48              
49 2 50       17 if ( $option{add} ) {
50 0         0 $workflow->git->add($path);
51             }
52              
53 2         12 next CONFLICT;
54             }
55             }
56              
57 2         9 return;
58             }
59              
60             sub resolve {
61 2     2 1 11 my ($file) = @_;
62              
63 2         117 print "Resolving $file\n";
64              
65 2         30 my %states = (
66             ours => qr/^<<<<<<</,
67             theirs => qr/^=======/,
68             keep => qr/^>>>>>>>/,
69             );
70 2         9 my $state = 'keep';
71 2 50       13 my $side = $option{theirs} ? 'theirs' : 'ours';
72 2         23 my $read = path($file)->openr;
73 2         559 my $tmp = path( $file . '.tmp' );
74 2         90 my $write = $tmp->openw;
75              
76             LINE:
77 2         437 while ( my $line = <$read> ) {
78 110         229 for my $check ( keys %states ) {
79 330 50       816 if ( $line =~ /$states{$check}/ ) {
80 0         0 $state = $check;
81 0         0 next LINE;
82             }
83             }
84              
85 110 50 33     235 print {$write} $line if $state eq 'keep' || $state eq $side;
  110         330  
86             }
87              
88 2         66 close $write;
89 2         73 unlink $file;
90 2         31 copy $tmp, $file;
91 2         1102 unlink $tmp;
92              
93 2         255 return;
94             }
95              
96             1;
97              
98             __DATA__
99              
100             =head1 NAME
101              
102             App::Git::Workflow::Command::Take - Resolve merge conflicts by only taking one side of each conflicted section
103              
104             =head1 VERSION
105              
106             This documentation refers to git-take-mine version 0.8
107              
108             =head1 SYNOPSIS
109              
110             git-take-mine [option] [path_or_file]
111              
112             OPTIONS:
113             -q --quiet Suppress notifying of files changed
114             --ours Take choanges from current branch throwing away other branches changes
115             --theirs Take changes from merging branch throwing away current branches changes
116              
117             -v --verbose Show more detailed option
118             --VERSION Prints the version information
119             --help Prints this help information
120             --man Prints the full documentation for git-take-mine
121              
122             =head1 DESCRIPTION
123              
124             C<git take> provides a way of quickly resolving conflicts by taking only one
125             side of the conflict. It does this differently to C<git checkout --ours> /
126             C<git checkout --theirs> as it only takes the conflicted part not the whole
127             of one side of the merge. Where this can come in handy is for merging things
128             with version number (eg pom.xml) where only the version number conflicts and
129             there may be other changes in the file that should be taken.
130              
131             =head1 SUBROUTINES/METHODS
132              
133             =head2 C<run ()>
134              
135             Finds the conflicted files to resolve
136              
137             =head2 C<resolve ($file)>
138              
139             Resolves conflicts in C<$file> in favor of C<--ours> or C<--theirs>.
140              
141             =head1 DIAGNOSTICS
142              
143             =head1 CONFIGURATION AND ENVIRONMENT
144              
145             =head1 DEPENDENCIES
146              
147             =head1 INCOMPATIBILITIES
148              
149             =head1 BUGS AND LIMITATIONS
150              
151             There are no known bugs in this module.
152              
153             Please report problems to Ivan Wills (ivan.wills@gmail.com).
154              
155             Patches are welcome.
156              
157             =head1 AUTHOR
158              
159             Ivan Wills - (ivan.wills@gmail.com)
160              
161             =head1 LICENSE AND COPYRIGHT
162              
163             Copyright (c) 2015 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077).
164             All rights reserved.
165              
166             This module is free software; you can redistribute it and/or modify it under
167             the same terms as Perl itself. See L<perlartistic>. This program is
168             distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
169             without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
170             PARTICULAR PURPOSE.
171              
172             =cut