App-SnerpVortex
view release on metacpan or search on metacpan
lib/SVN/Dump/Replayer/Git.pm view on Meta::CPAN
### Git helpers.
sub git_commit {
my ($self, $revision) = @_;
unless ($self->current_rw()) {
confess(
"attempting a commit on read-only entity ",
$self->current_branch()
);
}
$self->push_dir($self->replay_base());
# Every directory added is exploded into its constituent files.
# Try to avoid "git-add --all". It traverses the entire project
# tree, which quickly gets expensive.
if (scalar keys %{$self->directories_needing_add()}) {
foreach my $dir (keys %{$self->directories_needing_add()}) {
# TODO - Use File::Find when shell characters become an issue.
foreach my $file (`find $dir -type f`) {
chomp $file;
$self->files_needing_add()->{$file} = 1;
}
}
$self->directories_needing_add({});
$self->needs_commit(1);
}
$self->git_env_setup($revision);
my $needs_status = 1;
if (scalar keys %{$self->files_needing_add()}) {
# TODO - Break it up if the files list is too big.
$self->do_or_die("git", "add", "-f", keys(%{$self->files_needing_add()}));
$self->files_needing_add({});
$self->needs_commit(1);
$needs_status = 0;
}
unless ($self->needs_commit()) {
$self->log("skipping git commit");
$self->pop_dir();
return;
}
my $git_commit_message_file = "/tmp/git-commit-$$.txt";
my $message = $revision->message();
$message = "(no message)" unless defined $message and length $message;
open my $tmp, ">", $git_commit_message_file or confess $!;
print $tmp $message or confess $!;
close $tmp or confess $!;
$self->git_env_setup($revision);
# Some changes seem to alter no files. We can detect whether a
# commit is needed using git-status. Otherwise, if we guess wrong,
# git-commit will fail if there's nothing to commit. We bother
# checking git-commit because we do want to catch errors.
# TODO - git-status is slow after a while. Can we do something
# smart to avoid it in all cases?
if (
!$needs_status or
$self->do_sans_die("git status >/dev/null 2>/dev/null")
) {
$self->do_or_die(
"git", "commit",
($self->verbose() ? () : ("-q")),
"--allow-empty", "-F", $git_commit_message_file
);
}
unlink $git_commit_message_file;
# Map between Subversion revisions and Git commits.
chomp(my $git_id = qx(git rev-list -n 1 HEAD));
$self->arborist()->map_revisions($revision->id(), $git_id);
$self->needs_commit(0);
$self->pop_dir();
# Check for the need to GC.
$self->revisions_until_gc( $self->revisions_until_gc() - 1 );
if ($self->revisions_until_gc() < 1) {
$self->do_git_gc();
$self->revisions_until_gc( $self->revisions_between_gc() );
}
return;
}
sub do_git_gc {
my $self = shift;
$self->push_dir($self->replay_base());
$self->do_or_die("git", "gc", ($self->verbose() ? () : ("--quiet")));
$self->pop_dir();
}
### Helper methods.
#sub qualify_change_path {
# my ($self, $change) = @_;
# return $self->calculate_path($change->path());
#}
sub calculate_path {
my ($self, $path) = @_;
my $full_path = $self->replay_base() . "/" . $path;
$full_path =~ s!//+!/!g;
return $full_path;
}
sub git_env_setup {
my ($self, $revision) = @_;
( run in 1.435 second using v1.01-cache-2.11-cpan-39bf76dae61 )