Mirror a repository on Github

Posted on

I like having control on data that I produce, this means that most of the time, I will prefer to host them on my own server. Nevertheless, we can’t deny that using well known platforms helps giving some attraction to what you did. This is exactly the case of Github by mirroring some of my projects on their server.

Basically, my public repositories are hosted at code.berjon.net and I want some of them mirrored on Github. I will give the steps for mirroring a repository that is host on your own server (I’m using Gogit as my solution on top of Git server). Some other systems can be used of course but you’ll need to refer to the documentation of the solution of your choice (Bitbucket, etc …).

Git is great, powerful and versatile tool that we can put in a good use to create our mirrors. This is the following steps:

  • On the server hosting your repo, create an ssh key without password using the git user (if your server host the repo using this user)
  • deploy it on your Github account by going in the settings of the repo that will host your mirror.
  • Test your ssh connection with Github.
  • You can eventually setup you ~/.ssh/config to match more easily shortcut such as done below.

First of all, create a bare repository on Github (if you don’t know, I invite you to read the documentation at this subject). Once done, you have two possibilities, if you use a solution on the top of your Git server, you can probably create a post-receive hook dedicated in the configuration of the repository you want to mirror. Otherwise, you have to connect to your server to do it manually. For solution by hand, you have to create a post-receive file in <repository_name>/hooks/post-receive and add the following line:

exec git push --mirror --quiet git@github.com:<username>/<repository_name>

Do not forget to activate it by setting the executable permission using chmod +x <repository_name>/hooks/post-receive.

Then, we need to setup the communication channel between your server and Github server. The best way is to use a secured connection through a SSH channel. First thing to do is to create a SSH key without password (we want to have an automatic process).

ssh-keygen -t rsa

Just need to follow the steps and everything should be find. Now, we need to tell Github to authorize the connection when we ask for the connection for this precise repository that we create to host the mirror. We need to copy the public key using the “deploy key” option in the configuration of the repository. As it is specific to Github, I prefer you to refer to the official documentation to perform this operation. Despite it’s not mandatory, it could be useful (if you need to run some test with ease to debug some connection error for example and especially if you want to ensure that the proper SSH key will be used), you can now edit your SSH configuration on your server as by editing the file ~/.ssh/config:

Host <host>  
IdentityFile /home/git/.ssh/<ssh_key_name>  
HostName github.com  
User <user> 

Don’t forget to adapt the name, otherwise, it won’t work correctly. In a common configuration, the following names would be probably used.

  • <host>: github
  • <ssh_key_name>: github_rsa
  • <user>: git

Let’s test the connection and it’s a mandatory step for the first time as you have to accept the fingerprint the first time otherwise you’ll be rejected and you won’t have any idea why before take a lot of time to dig up the issue. Github shows how to proceed:

ssh -T git@github.com

If it’ s the first time, you should be asked to check the fingerprint. Once done, or you’ll have message saying you are successfully connected, otherwise you’ll get an error. In this case, check your modification and refer to the documentation such as the denial of connection that is quite common.

From that point, you should be able to push your work to your server as usual and get it automatically mirrored after each push to Github. It has it’s pros and cons. This solution let you to have contributions from anyone on your own Git instance without have to give any specific access or requiring any additional configuration on the contributor side, the issue is that you won’t be able to accept any pull request from Github users (you can but that’s a kind of a nightmare to merge then from the original repository). Another single user solution, that you could use if you don’t have access to the server hosting your repository for example, is by tweaking the remotes. I give an example below.

You add your github repository to the list of remote you have:

git remote add <alias> git@github.com:<username>/<repository_name>  

You can ensure that the remote has been added (both pull and fetch) by using the command git remote -v. Then you can update the mirror by pushing the data with the magic argument –mirror:

git push --mirror <remote_name>  

Now, each time you want to push the data, you have to do twice (once for your original repository and once for your mirror). If it’s a pain for you, you can create an alias in your ~/.gitconfig file that will push in both places.