24 days of Perl code from RJBS! Feed

Gimme Everything You Got

Git::Megapull - 2009-12-21

Priming Your New Workstation's ~/code

...or ~/src or whatever you use. Personally, I have ~/code/hub/, in which I have a clone of all the repositories that I host on GitHub. If you checked, you saw that I have a lot of repositories there. This can be a real pain when I set up a new workstation. (That doesn't happen often, but if Santa wants to bring me a brand new MacBook, I will leave out extra milk and cookies.) It's also a big pain to get all my repos up to date, which I like to do before travel, or as a backup procedure. I wanted one command that would ensure I had every repo cloned and up to date. That command is git megapull. When run, it finds all your remote repositories and, for each, checks whether you have a matching directory in cwd. If you don't, the repository is cloned. If you do, its origin is fetched and the master branch is merged. It also tells you if you have directories lying around that don't correspond to remote repositories.

There are three switches to git megapull. -c will only clone repositories; existing clones will not be updated. -b will create bare repositories when cloning, which is great for making backups.

The third switch is -s or --source. It tells megapull how to get a listing of your remote repositories. Git::Megapull comes with a source for GitHub, so you can run git megapull -s Github (or put "GitHub" in the megapull.source entry of your ~/.gitconfig) to find and clone all your repositories from GitHub using their API.

Providing Other Sources

Once I had this tool working on my laptop and a few other workstations, I wanted it at work, where we use gitosis. This was pretty easy to throw together; a source just needs to return a hashref of names and cloneable URIs.


1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 

 

use strict;
use warnings;
package Git::Megapull::Source::Pobox;
use base 'Git::Megapull::Source';

sub repo_uris {
  my ($self) = @_;

  my @repos
    = `ssh git.pobox.com 'gfind ~git/repositories -type d -mindepth 1 -maxdepth 1'`;
  chomp @repos;

  s/\.git//g for @repos;
  s{\A.+/repositories/}{}g for @repos;

  my %repo_uri;
  $repo_uri{ $_ } = "git\@git.pobox.com:$_.git" for @repos;
  
  return \%repo_uri;
}

1;

 

See Also