Skip to content

Instantly share code, notes, and snippets.

@ap
Last active December 28, 2015 21:19
Show Gist options
  • Save ap/7564279 to your computer and use it in GitHub Desktop.
Save ap/7564279 to your computer and use it in GitHub Desktop.
ribasushi’s gitize
#!/usr/bin/env perl
use warnings;
use strict;
use Git::Raw ();
use Archive::Peek::Libarchive ();
use Getopt::Std 'getopts';
getopts 'd:', \my %opt;
my $git = Git::Raw::Repository->open( $opt{'d'} // die 'need git directory, specify using -d' );
sub splitname { $_[0] =~ m!(.*)/(.*)! ? ( $1, $2 ) : ( '.', $_[0] ) }
sub by_depth { my @d = map { tr!/!! } $a, $b; $d[0] <=> $d[1] }
my @parent;
for my $z (sort { (stat $a)[9] <=> (stat $b)[9] } @ARGV) {
my %builder;
Archive::Peek::Libarchive->new( filename => $z )->iterate( sub {
$_[0] =~ s!^[^/]+!.!;
my ( $path, $name ) = splitname $_[0];
my $builder = $builder{ $path } //= Git::Raw::TreeBuilder->new( $git );
$builder->insert( $name, $git->blob( $_[1] ), 0100644 );
} );
for my $path ( reverse sort by_depth keys %builder ) {
my $tree = $builder{ $path }->write;
my ( $parent, $name ) = splitname $path;
if ( '.' ne $name ) {
my $builder = $builder{ $parent } //= Git::Raw::TreeBuilder->new( $git );
$builder->insert( $name, $tree, 040000 );
}
else {
my $who = Git::Raw::Signature->new( 'BackPAN', 'root@localhost', (stat $z)[9], 0 );
my $commit = $git->commit( "Extract of CPAN dist $z", $who, $who, \@parent, $tree, undef );
Git::Raw::Reference->create( "refs/heads/$z", $git, $commit, 'force' );
@parent = $commit;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment