Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • A lot of good developers use git, but I don't think using Git makes you a good developer.

    In my experience the good people submit patches no matter what source control I'm using.

    Still, I'm really enjoying git now that I've gotten over the hump of learning the basics. It took a little while to get used to, but that I'm easily managing several branches at the same time on some projects, I'm happy with git.

    I have a github_creator script [] on Github. I make my repositories locally and set up github as a remote (not origin). I just run the script in a working copy and it automatically creates the git repo, sets up the remote, and pushes to it. I also replicate my git stuff in a few different places so I don't rely on someone else's service:

    use warnings;
    use strict;
    use Cwd;
    use Config::IniFiles;
    use File::Basename;
    use File::Path;
    use File::Spec::Functions qw(catfile);
    use Log::Log4perl qw(:easy);
    use Net::SSH::Expect;
    { # for debugging
    rmtree( [ 'Foo-Bar', 'Git' ], 0, 0 );
    `module_cooker Foo::Bar`;
    chdir 'Foo-Bar';
    my $dirname = basename( cwd() );
    DEBUG "Local dir is $dirname";
    my $repo_name = "$dirname\.git";
    unless( -d ".git" )
        INFO `git init`;
        INFO `git add .`;
        INFO `git commit -a -m "* Initial module creation"`;
    my %remotes = map { $_, 1 } map { chomp $_; $_ } `git remote 2>/dev/null`;
    my $basename = basename( $0 );
    my $Config = Config::IniFiles->new( -file => "/Users/brian/bin/$basename.ini" );
    unless( eval { $Config->isa( 'Config::IniFiles' ) } )
        die "Could not find config file [$basename.ini]\n";
    HOST: foreach my $remote_name ( $Config->Sections )
        my( $host, $user, $git_dir, $remote_git ) = map {
            $Config->val( $remote_name, $_ ) } qw( host user dir git );
        INFO "Remote is $remote_name";
        INFO "Processing $host";
        next HOST if exists $remotes{ $remote_name };
        INFO `git remote add $remote_name ssh://$user\@$host$git_dir/$repo_name`;
        my $path = catfile( $git_dir, $repo_name );
        DEBUG "path is $path\n";
        my $ssh = get_ssh_session( $host, $user );
        my $cwd = $ssh->exec( "pwd" ) || '';
        DEBUG "at login, pwd is $cwd\n";
        $ssh->exec( "mkdir -p $path" );
        my $pwd = $ssh->exec( "cd $path; pwd" );
        DEBUG "after cd, pwd is $pwd\n";
        my $output = $ssh->exec( "$remote_git --bare init" );
        DEBUG "git says [$output]\n";
        my $push = `/usr/local/bin/git push $remote_name master`;
    sub get_ssh_session
        my( $host, $user ) = @_;
                host    => $host,
                user    => $user,
                raw_pty => 1,
                no_terminal => 1,

    Pushing to them all is easy (although maybe there is a hidden git command to do all this):

    use Term::ANSIColor;
    my $status = `git status`;
    my( $branch ) = $status =~ m/# On branch (\w+)/g;
    print "Pushing branch $branch\n";
    foreach my $remote ( map { chomp; $_ } `git remote` )
            print colored( "Processing remote $remote\n", 'red' );
            `git push --all $remote @ARGV`;
            `git push --tags $remote`;

    I should probably store these scripts in some repo, but I haven't. Do whatever you like with them.