sub _prepare_sub_dir()

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 );
}