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/configto 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
<repository_name>/hooks/post-receive and add the following line:
exec git push --mirror --quiet firstname.lastname@example.org:<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
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.
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 email@example.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> firstname.lastname@example.org:<username>/<repository_name>
You can ensure that the remote has been added (both pull and fetch) by using
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