Introduction

Since I am running a self-hosted Git server, using the powerful software Gitea, and want to use Travis CI I need to mirror my repositories to GitHub because Travis does not support self-hosted Git. Since I couldn't find an easy and short documentation on how to do this I decided to hack this myself.

Here I show how I did this very easily.

Prerequisites

  • A Git repository under /home/git/hanez/helloworld.git managed by user "git"
  • A HTTP(S) interface for accesing your repository from GitHub like https://git.unixpeople.org/hanez/helloworld.git (needed to import the project to GitHub)
  • A GitHub account

Import the repository to your GitHub account

Just use the import function on GitHub by entering the HTTP(S) URL of your self-hosted repository. E.g. https://git.unixpeople.org/hanez/helloworld.git

I just give the new repository the same name as the original ("helloworld") but you can name it what you want at GitHub but take care to use this name when adding this as the "remote" repository name below.

Become user "git" on your Git server

$ su - git

Generate SSH keys

Create default SSH-key if not already done

I do this to be sure the directory /home/git/.ssh exists with the right permissions.

$ ssh-keygen

Create deploy key for your project

Go to SSH configuration directory and create key for the repository to mirror. Since you need a deploy key for each project you have to create a key for each repository you want to mirror. It is not possible to use a key for multiple projects on GitHub.

$ cd ~/.ssh
$ ssh-keygen -f id_rsa.helloworld

Add the content of "~/.ssh/id_rsa.helloworld.pub" as deploy key at GitHub

Now you need to add the public SSH-key to the repository at GitHub in the settings of the mirror repository. In this case I go to the "helloworld" repository and select "Settings" and then "Deploy keys" to add the key.

Change directory to bare repository

$ cd ~/hanez/helloworld.git

Add "remote" to repository config

$ git remote add --mirror=push github git@github.com:hanez/helloworld.git

This will make my "config" look like this:

$ cat config
[core]
        repositoryformatversion = 0
        filemode                = true
        bare                    = true
[remote "github"]
        url = git@github.com:hanez/helloworld.git
        mirror = true

Create post-receive hook

First change directory

cd ~/hanez/helloworld.git/hooks/post-receive.d

Create the hook

Since we need to select the right SSH-key at this place a simple "git push" would not do the job because it will use the default SSH-key from the "git" user. A simple hack using the SSH-agent will do the job right. In this case this requires "bash" installed on your system.

$ cat <<EOF >> github
#!/usr/bin/env bash
ssh-agent bash -c 'ssh-add /home/git/.ssh/id_rsa.helloworld; git push --quiet github' &
EOF

Make the hook executable

$ chmod +x github

Conclusion

Now on every push to your self-hosted Git repository the code will be pushed over to the mirror repository at GitHub.

You see, it is very easy to mirror your self-hosted Git repository to GitHub. Now you can use services like Travis CI or Docker Hub to rebuild code or containers even when not using GitHub as your primary source code management platform.

Sure you could do all of this task locally by adding hooks to your local repository but this expects that every user who pushes changes needs to setup this. In my case it is just done without user interaction.

I believe this is very useful to many so I decided to publish my workflow here... ;)