in lib/ES/Repo.pm [152:244]
sub _prepare_sub_dir {
#===================================
my ( $self, $title, $branch, $path, $dest ) = @_;
my $source_root = $self->{sub_dirs}->{$branch};
unless ( $self->{keep_hash} ) {
$self->_extract_from_dir( $source_root, $dest, $path );
return $dest;
}
my $no_uncommitted_changes = eval {
local $ENV{GIT_WORK_TREE} = $source_root;
local $ENV{GIT_DIR} = $ENV{GIT_WORK_TREE} . '/.git';
run qw(git diff-index --quiet HEAD --);
1;
};
unless ( $no_uncommitted_changes ) {
unless ( $@ =~ /\n---out---\n\n---err---\n\n---------\n/) {
# If the error message isn't empty then something went wrong checking.
die "failed to check for outstanding commits: $@";
}
printf(" - %40.40s: Not merging the subbed dir for [%s][%s][%s] because it has uncommitted changes.\n",
$title, $self->{name}, $branch, $path);
$self->_extract_from_dir( $source_root, $dest, $path );
return $dest;
}
my $resolved_branch = $self->_resolve_branch( $title, $branch, $path );
unless ( $resolved_branch ) {
printf(" - %40.40s: Not merging the subbed dir for [%s][%s][%s] because it is new.\n",
$title, $self->{name}, $branch, $path);
$self->_extract_from_dir( $source_root, $dest, $path );
return $dest;
}
local $ENV{GIT_DIR} = "$source_root/.git";
my $subbed_head = run qw(git rev-parse HEAD);
delete local $ENV{GIT_DIR};
my $merge_branch = "${resolved_branch}_${subbed_head}_$path";
$merge_branch =~ s|/|_|g;
$merge_branch =~ s|\*|splat|g;
$merge_branch =~ s|:\(glob\)|_glob_|g;
$merge_branch =~ s|\.$||g; # Fix funny shaped paths
# Check if we've already merged this path by looking for the merged_branch
# in the source repo. This is safe because:
# 1. We prune all branches from the source repo before the build.
# 2. The merge branch contains the hash of the subbed head.
my $already_built = eval {
local $ENV{GIT_DIR} = $self->{git_dir};
run qw(git rev-parse), $merge_branch;
1;
};
if ( $already_built ) {
# Logging here would be pretty noisy.
$self->_extract_from_ref( $dest, $merge_branch, $path );
return;
}
# Merge the HEAD of the subbed dir into the commit that last successfully
# built the docs.
printf(" - %40.40s: Merging the subbed dir for [%s][%s][%s] into the last successful build.\n",
$title, $self->{name}, $branch, $path);
my $work = Path::Class::dir( '/tmp/mergework' );
$work->rmtree;
run qw(git clone --no-checkout), $self->{git_dir}, $work;
my $original_pwd = Cwd::cwd();
chdir $work;
my $merged = eval {
run qw(git remote add subbed_repo), $source_root;
run qw(git fetch subbed_repo), $subbed_head;
run qw(git remote remove subbed_repo);
unless ($path eq '.') {
run qw(git config core.sparseCheckout true);
$self->_write_sparse_config( $work, $path );
}
run qw(git checkout -b), $merge_branch, $resolved_branch;
run qw(git merge -m merge), $subbed_head;
run qw(git push origin -f), $merge_branch; # Origin here is just our clone.
1;
};
chdir $original_pwd;
unless ( $merged ) {
printf(" - %40.40s: Failed to merge the subbed dir for [%s][%s][%s] into the last successful build:\n%s",
$title, $self->{name}, $branch, $path, $@);
$dest->rmtree;
$self->_extract_from_dir( $source_root, $dest, $path );
return $dest;
}
printf(" - %40.40s: Merged the subbed dir for [%s][%s][%s] into the last successful build.\n",
$title, $self->{name}, $branch, $path);
$self->_extract_from_ref( $dest, $merge_branch, $path );
}