App-Git-Workflow-Command-BranchConflicts
view release on metacpan or search on metacpan
lib/App/Git/Workflow/Command/BranchConflicts.pm view on Meta::CPAN
package App::Git::Workflow::Command::BranchConflicts;
# Created on: 2015-04-12 06:56:18
# Create by: Ivan Wills
# $Id$
# $Revision$, $HeadURL$, $Date$
# $Revision$, $Source$, $Date$
use strict;
use warnings;
use Pod::Usage ();
use Data::Dumper qw/Dumper/;
use English qw/ -no_match_vars /;
use App::Git::Workflow;
use App::Git::Workflow::Command qw/get_options/;
use Capture::Tiny qw/capture_stderr/;
our $VERSION = 0.6;
our $workflow = App::Git::Workflow->new;
our ($name) = $PROGRAM_NAME =~ m{^.*/(.*?)$}mxs;
our %option;
sub run {
my ($self) = @_;
get_options(
\%option,
'remote|r',
'both|a',
'merge|m=s',
'since|s=s',
'ignore|i=s',
'quiet|q',
);
my ($type, @arg) = $option{remote} ? (qw/remote -r/) : $option{both} ? (qw/both -a/) : ();
my @branches
= $option{merge}
? map {/^\s+(.*)$/; $1} $workflow->git->branch(@arg, '--no-merged', $option{merge})
: $workflow->branches($type);
my %conflicts;
# check all branches for conflicts with other branches
while (@branches > 1) {
my $first_branch = shift @branches;
next if $option{since} && !$workflow->git->log(qw/-n1 --since/, $option{since}, $first_branch);
print "Checking $first_branch\n" if $option{verbose};
$self->checkout_branch($first_branch);
for my $branch (@branches) {
next if $option{since} && !$workflow->git->log(qw/-n1 --since/, $option{since}, $branch);
if ( $self->merge_branch_conflicts($branch) ) {
push @{ $conflicts{$first_branch} }, $branch;
}
}
$workflow->git->reset('HEAD');
$workflow->git->clean('-xfd');
$workflow->git->checkout('.');
capture_stderr {
$workflow->git->checkout('-');
};
}
if (%conflicts) {
print "Conflicting branches:\n";
for my $branch (sort keys %conflicts) {
print " $branch\n", map {" $_\n"} @{ $conflicts{$branch} };
}
}
else {
print "No conflicts.\n";
}
$self->cleanup();
return;
}
my @checkouts;
sub checkout_branch {
my ($self, $branch) = @_;
my $local = 'branch-conflicts-' . sprintf '%03i', scalar @checkouts;
capture_stderr {
$workflow->git->checkout('-b', $local, '--no-track', $branch);
};
push @checkouts, $local;
return $local;
}
sub merge_branch_conflicts {
my ($self, $branch) = @_;
capture_stderr {
eval { $workflow->git->merge('--no-commit', $branch) };
};
my $status = $workflow->git->status;
eval { $workflow->git->merge('--abort'); };
if ($option{ignore}) {
$status =~ s/both (?:added|modified): \s+ $option{ignore}//;
}
return $status =~ /both (?:added|modified)/;
}
sub cleanup {
while ( my $branch = shift @checkouts) {
$workflow->git->branch('-D', $branch);
}
return;
}
1;
__DATA__
=head1 NAME
App::Git::Workflow::Command::BranchConflicts - Module to find git branches that would conflict if merged
=head1 VERSION
This documentation refers to App::Git::Workflow::Command::BranchConflicts version 0.6
=head1 SYNOPSIS
git-branch-conflicts [--remote|-r|--all|-a] [(--merge|-m) branch] [(--since|-s) date] [(--ignore|-i) regex]
OPTIONS:
-r --remote List all remote branches
-a --all List all branches
-m --merge[=]branch
Operate only on branches not merged with this branch
-s --since[=]date
Only look at branches that have changes since this date
-i --ignore[=]regex
Ignore any files matching this regex that conflict during
test merges (e.g. pom.xml changes)
-q --quiet quite output
--verbose Show more detailed option
--version Prints the version information
--help Prints this help information
--man Prints the full documentation for git-branch-grep
=head1 DESCRIPTION
=head1 SUBROUTINES/METHODS
=head2 C<run ()>
( run in 1.388 second using v1.01-cache-2.11-cpan-39bf76dae61 )