For my next adventure, I'm going to write a distribution that allows a user to easily back up all of their Github repos, issues, PRs, wikis etc, but since hearing about the near disaster at Gitlab, I thought I'd expedite writing this one.

I've put together a quick script just so I could begin getting used to the various APIs I'd need, and am sharing it here in the event someone else finds it useful.

Currently, it'll clone all repositories under the $user variable, and will skip over repos you've forked (ie. only your own true repos will be included). Remove the if (! exists $content->{parent}) check to also back up the repos you've forked.

There's a blurb below the code for users who require a proxy. Also note that Github limits the number of API calls an unauthorized user can make, so you'll likely want to create a Github token.

use warnings; use strict; use Data::Dumper; use Git::Repository; use File::Copy qw(move); use File::Path qw(rmtree); use Pithub; my $user = 'stevieb9'; my $token = '...'; my $bak = 'backups'; my $stg = 'backups.stg'; my $gh = Pithub->new( user => $user, token => $token ); my $result = $gh->repos->list(user => $user); my @repos; while (my $row = $result->next){ print "$row->{name}\n"; push @repos, $row->{name}; } # prepare the staging dir if (-d $stg){ rmtree $stg or die $!; mkdir $stg or die $!; } for (@repos){ my $content = $gh->repos() ->get(user => $user, repo => $_) ->content; if (! exists $content->{parent}){ print "backing up $content->{full_name}...\n"; Git::Repository->run( clone => $content->{clone_url} => "$stg/$content->{name}", { quiet => 1} ); } } # move staging into the backup dir if (-d $bak){ rmtree $bak or die $!; } move $stg, $bak or die $!;

That'll create a backups.stg dir in your current working directory, clone all of your repos into it, then when done, moves the staging dir over top of a backups dir.

If you are behind a proxy server, you'll need to add the following lines, and change your Pithub call to new():

use LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->env_proxy; my $gh = Pithub->new( ua => $ua, # <-- add this user => $user, token => $token );

Output:

backing up stevieb9/app-envcontrol... backing up stevieb9/app-rpi-envui... backing up stevieb9/async-event-interval... backing up stevieb9/berrybrew... backing up stevieb9/bit-manip... backing up stevieb9/bit-manip-pp... backing up stevieb9/business-isp... backing up stevieb9/cgi-application-plugin-pagebuilder... backing up stevieb9/cisco-acl-count... backing up stevieb9/config... backing up stevieb9/csharp-template... backing up stevieb9/devel-examine-subs... backing up stevieb9/devel-trace-method... backing up stevieb9/devel-trace-subs... backing up stevieb9/dht11-env-control... backing up stevieb9/dnmfarrell-berrybrew... backing up stevieb9/file-edit-portable... backing up stevieb9/File-Portable... backing up stevieb9/freeradius-database... backing up stevieb9/github-backup... backing up stevieb9/mock-sub... backing up stevieb9/netstat-session-stats... backing up stevieb9/nginx-autoconfig... backing up stevieb9/p5-app-copyrightimage... backing up stevieb9/p5-brew-build-script... backing up stevieb9/p5-hook-output-tiny... backing up stevieb9/p5-logging-simple... backing up stevieb9/p5-net-ping... backing up stevieb9/p5-plugin-simple... backing up stevieb9/p5-rpi-dht11-envcontrol... backing up stevieb9/p5-rpi-wiringpi-constant... backing up stevieb9/p5-test-brewbuild-plugin-testagainst... backing up stevieb9/p5-test-brewbuild-revdeps... backing up stevieb9/patches... backing up stevieb9/perl6-log-simple... backing up stevieb9/rpi-adc-ads... backing up stevieb9/rpi-adc-ads_pp... backing up stevieb9/rpi-adc-mcp3008... backing up stevieb9/rpi-bmp180... backing up stevieb9/rpi-dac-mcp4922... backing up stevieb9/rpi-dht11... backing up stevieb9/rpi-digipot-mcp4xxxx... backing up stevieb9/rpi-hcsr04... backing up stevieb9/rpi-shiftreg-sn74hc595... backing up stevieb9/rpi-spi... backing up stevieb9/rpi-wiringpi... backing up stevieb9/scripts... backing up stevieb9/sftp-log-format... backing up stevieb9/sftp-user... backing up stevieb9/svn-repl-wrapper... backing up stevieb9/tcpdump-pcap-sort... backing up stevieb9/test-brewbuild... backing up stevieb9/test-fail... backing up stevieb9/wiringpi-api... backing up stevieb9/wrap-sub... backing up stevieb9/xen-conf-generate...

update: s/anauthorized/unauthorized/


In reply to Back up all of your Github repos by stevieb

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.