/usr/local/CPAN/VCI/VCI/VCS/Git/Directory.pm
package VCI::VCS::Git::Directory;
use Moose;
extends 'VCI::Abstract::Directory';
with 'VCI::VCS::Git::Committable';
# XXX This should probably be optimized to not build a File object for
# every file in the whole tree--it's a bit slow on the kernel sources
# (over 20,000 files).
sub _build_contents {
my $self = shift;
my @path_part;
@path_part = ('--', $self->path->stringify) unless $self->path->is_empty;
my $files = $self->project->x_do('ls-tree',
['-r', $self->revision, @path_part]);
@$files = map { s/^\d+ \w+ \S+\s+//; $_ } @$files;
# Get the directory names from the output
my %dirs;
foreach my $line (@$files) {
# XXX This assumes the path separator is always /.
if ($line =~ m|^(.+)/[^/]+$|) {
$dirs{$1} = 1;
}
}
# Make sure that every dir has a parent in the list.
my @new_dirs;
my @check_dirs = keys %dirs;
my $found_parent = 1;
while ($found_parent) {
$found_parent = 0;
foreach my $dir (@check_dirs) {
# If this directory has a parent... (XXX path separator assumption)
if ($dir =~ m|^(.+)/[^/]+$|) {
my $parent_dir = $1;
# And that parent isn't already in the list...
if (!$dirs{$parent_dir}) {
push(@new_dirs, $parent_dir);
$found_parent = 1;
}
}
}
$dirs{$_} = 1 foreach @new_dirs;
@check_dirs = @new_dirs;
}
$self->_set_contents_from_list([keys %dirs], $files, $self->path->stringify);
return $self->{contents};
}
__PACKAGE__->meta->make_immutable;
1;