App-Sqitch
view release on metacpan or search on metacpan
lib/App/Sqitch/Command/checkout.pm view on Meta::CPAN
my $git = $self->client;
my $engine = $target->engine;
$engine->with_verify( $self->verify );
$engine->log_only( $self->log_only );
$engine->lock_timeout( $self->lock_timeout );
# What branch are we on?
my $current_branch = $sqitch->probe($git, qw(rev-parse --abbrev-ref HEAD));
hurl {
ident => 'checkout',
message => __x('Already on branch {branch}', branch => $branch),
exitval => 1,
} if $current_branch eq $branch;
# Instantitate a plan without calling $target->plan.
my $from_plan = App::Sqitch::Plan->new(
sqitch => $sqitch,
target => $target,
);
# Load the branch plan from Git, assuming the same path.
my $to_plan = App::Sqitch::Plan->new(
sqitch => $sqitch,
target => $target,
)->parse(
# Git assumes a relative file name is relative to the repo root, even
# when you're in a subdirectory. So we have to prepend the currrent
# directory path ./ to convince it to read the file relative to the
# current directory. See #560 and
# https://git-scm.com/docs/gitrevisions#Documentation/gitrevisions.txt-emltrevgtltpathgtemegemHEADREADMEememmasterREADMEem
# for details.
# XXX Handle missing file/no contents.
scalar $sqitch->capture(
$git, 'show', "$branch:"
. File::Spec->catfile(File::Spec->curdir, $target->plan_file)
)
);
# Find the last change the plans have in common.
my $last_common_change;
for my $change ($to_plan->changes){
last unless $from_plan->get( $change->id );
$last_common_change = $change;
}
hurl checkout => __x(
'Branch {branch} has no changes in common with current branch {current}',
branch => $branch,
current => $current_branch,
) unless $last_common_change;
$sqitch->info(__x(
'Last change before the branches diverged: {last_change}',
last_change => $last_common_change->format_name_with_tags,
));
# Revert to the last common change.
$engine->set_variables( $self->_collect_revert_vars($target) );
$engine->plan( $from_plan );
try {
$engine->revert( $last_common_change->id, ! $self->no_prompt, $self->prompt_accept );
} catch {
# Rethrow unknown errors or errors with exitval > 1.
die $_ if ! eval { $_->isa('App::Sqitch::X') }
|| $_->exitval > 1
|| $_->ident eq 'revert:confirm';
# Emite notice of non-fatal errors (e.g., nothing to revert).
$self->info($_->message)
};
# Check out the new branch.
$sqitch->run($git, 'checkout', $branch);
# Deploy!
$engine->set_variables( $self->_collect_deploy_vars($target) );
$engine->plan( $to_plan );
$engine->deploy( undef, $self->mode);
return $self;
}
1;
__END__
=head1 Name
App::Sqitch::Command::checkout - Revert, change checkout a VCS branch, and redeploy
=head1 Synopsis
my $cmd = App::Sqitch::Command::checkout->new(%params);
$cmd->execute;
=head1 Description
If you want to know how to use the C<checkout> command, you probably want to
be reading C<sqitch-checkout>. But if you really want to know how the
C<checkout> command works, read on.
=head1 Interface
=head2 Class Methods
=head3 C<options>
my @opts = App::Sqitch::Command::checkout->options;
Returns a list of L<Getopt::Long> option specifications for the command-line
options for the C<checkout> command.
=head2 Instance Methods
=head3 C<execute>
$checkout->execute;
Executes the checkout command.
=head1 See Also
( run in 0.591 second using v1.01-cache-2.11-cpan-0b5f733616e )