Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Mirroring a Mercurial repository onto Github

by tobyink (Canon)
on Nov 03, 2012 at 22:51 UTC ( #1002149=CUFP: print w/replies, xml ) Need Help??

I've never really gotten along with git. Its feature set is good, but its usability is horrible. Mercurial on the other hand has roughly the same features, but is much more enjoyable to use, which is why it is my version control system of choice.

However, in recent years Github's popularity has exploded. So, how to get my code onto Github without using git?

Firstly, there's the hggit mercurial extension that allows you to push to a git repository. Install it and add these lines to .hgrc:

[extensions] hggit= bookmarks=

Then you need to create a bookmark for hggit to use as the basis for the master git head:

$ hg bookmark -r default master

And now you can just push:

$ hg push git+ssh://

So where does Perl come into it? Well, I want to automate the creation of the Github repository, and setting up the bookmark. Here's my script to do that...

#!/usr/bin/env perl use v5.14; use constant { GH_USER => 'tobyink', GH_PASS => 'A BIG SECRET', }; use Acme::Constructor::Pythonic qw( Pithub Path::Class::File Path::Class::Dir ); use Cwd; BEGIN { package PithubX::Base; use Pithub::Base (); use Moo::Role; around _request_for => sub { my ($orig, $self, @args) = @_; my $req = $self->$orig(@args); $req->headers->remove_header('Authorization'); $req->headers->authorization_basic(::GH_USER, ::GH_PASS); return $req; }; 'Moo::Role'->apply_roles_to_package( 'Pithub::Base', 'PithubX::Base', ); }; my $gh = Pithub(user => GH_USER, token => 1); my $name = (Dir(cwd)->dir_list)[-1]; while ( not $gh->repos->get(repo => $name)->response->is_success ) { say "creating github repo '$name'"; $gh->repos->create(data => { name => $name, has_wiki => 0, has_downloads => 0, }); } unless (`hg bookmarks` =~ /master/) { say "creating 'master' bookmark"; system "hg bookmark -r default master"; } my $url = sprintf('git+ssh://', GH_USER, $name +); system "hg push $url";

One interesting part of the script is the PithubX::Base package which acts as a monkey-patch for Pithub::Base, swapping out the OAuth authentication for HTTP basic auth because that seemed easier than figuring out how to get an OAuth authentication token.

I've saved that as github-mirror. But so that I don't have to remember to run it, I've also added it as a hook in my .hgrc so that whenever I push changes to my mercurial repo, github-mirror runs too:

[hooks] preoutgoing = /home/tai/bin/github-mirror
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://1002149]
Approved by McDarren
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2020-08-04 23:18 GMT
Find Nodes?
    Voting Booth?
    Which rocket would you take to Mars?

    Results (35 votes). Check out past polls.