Automatically mirror Gitlab repositories to Github

This blogpost describes how to periodically mirror specific Gitlab repositories to your Github account or organization using the glab and gh cli tools

Please contact us if anything is not clearly described, does not work, seems incorrect or if you require support.

Table of contents

The Problem with mirroring from Gitlab to Github

We want to mirror some of our public Gitlab repositories to github for better visibility. There is a gitlab function available for that at Settings -> Repository -> Repository mirroring, which is documented here, but sadly it gives this error when used with github:

13: push to mirror: git push: exit status 128, stderr: "remote Support for password authentication was removed on August 13, 2021.\nremote: Please see for information on currently recommended modes of authentication.\nfatal: Authentication failed for: ''\n".

Gitlab Mirror Repository to Github Error

Installing the Gitlab CLI glab

So lets just script it. This will not be triggered automatically, but you can setup a cronjob on your gitlab server that does it once a day. Gitlab has a CLI tool for administration. A .deb package can be downloaded for Ubuntu and Debian Linux based workstations at the download page. For most Ubuntu and Debian based servers, choose "glab__Linux_x86_64.deb".

sudo dpkg -i glab_1.36.0_Linux_x86_64.deb

After installation you have to authenticate against your gitlab instance. This configuration will be saved below "~/.config/glab-cli/". In order to authenticate you will need a token, which can be generated here:

You only need to select the "api" and "read_repository" permission:

Create a Gitlab API token

glab auth login
? What GitLab instance do you want to log into? GitLab Self-hosted Instance
? GitLab hostname:
? API hostname:
- Logging into
? How would you like to login? Token

Tip: you can generate a Personal Access Token here,write_repository
The minimum required scopes are 'api' and 'write_repository'.
? Paste your authentication token: **************************
? Choose default git protocol SSH
? Choose host API protocol HTTPS
- glab config set -h git_protocol ssh
✓ Configured git protocol
- glab config set -h api_protocol https
✓ Configured API protocol

If we check it now it wont work:

glab repo list
Showing 0 of 0 projects (Page 1 of 1)

For whatever reason the configuration created by "glab auth login", which is located at "~/.config/glab-cli/config.yml", is setup to only talk to by default, not your personal gitlab instance. Lets fix that by replacing all occurances of with your Gitlabs hostname:

# Change this to your gitlab instance

    # Change this too
        # And this as well

Or in one line:

sed -i 's/' ~/.config/glab-cli/config.yml

Now the repositories should be visible:

glab repo list
Showing 30 of 372 projects (Page 1 of 12)

ansible-roles/role-imgproxy                      Ansible role to install and configure imgproxy on Debian Linux                                                   
ansible-roles/role-golang                          Ansible role to install and configure golang on Debian Linux    
ansible-roles/role-systemd-journal-remote  Ansible role to install and configure systemd-journal-remote on Debian Linux                                     

Installing the Github CLI gh

Next we need a cli client for github to automatically create repositores there. There is a github cli called "gh", which can simply be installed by apt:

sudo apt install gh

The configuration is very similar to the glab cli tool (but works right away). In our case, gitlab is not able to start a browser from the cli, so we copy paste the auth code to the URL displayed:

gh auth login
? What account do you want to log into?
? What is your preferred protocol for Git operations? HTTPS
? Authenticate Git with your GitHub credentials? Yes
? How would you like to authenticate GitHub CLI? Login with a web browser

! First copy your one-time code: D946-B977
Press Enter to open in your browser... 
2024/02/15 23:44:52.178314 cmd_run.go:1055: WARNING: cannot start document portal: Expected portal at "/run/user/1000/doc", got "/home/user/.cache/doc"
/user.slice/user-1000.slice/session-2.scope is not a snap cgroup
! Failed opening a web browser at
  exit status 4
  Please try entering the URL in your browser manually

✓ Authentication complete.
- gh config set -h git_protocol https
✓ Configured git protocol
✓ Logged in as blunix0815

Lets check if the setup was successful:

gh repo list

There are no repositories in @blunix0815

gh repo list Blunix-GmbH

Showing 30 of 47 repositories in @Blunix-GmbH

Blunix-GmbH/role-borgbackup-server            Ansible role to install and configure borgbackup server on Debian Linux 

Setting up the Gitlab to Github mirror script

The following script uses the "glab" and "gh" cli tools to iterate over all repositories on the Blunix gitlab instance, create the same project on github, clone the project from gitlab and push the master or main branch to github.

# Replicate all repositories from to

# List all repos below
# Example output of glab repo list:
# ansible-roles/role-ssh                                          Ansible role for managing OpenSSH-Server and users authorized_keys
glab repo list --all --group ansible-roles --per-page 1000 | while read line; do

    # Skip "Showing of 51 projects (Page 1 of 1)"
    [[ "$line" == Showing* ]] && continue
    # Skip empty lines
    [[ "$line" == "" ]] && continue

    # Extract repo name
    repo_name=$(echo $line | cut -d ' ' -f 1 | cut -d '/' -f 2)

    # Extract repo url
    repo_url=$(echo $line | cut -d ' ' -f 2)

    # Extract description
    repo_description=$(echo $line | cut -d ' ' -f 3-)

    # Give the user some information about current repo
    echo "Processing repo \"$repo_name\" with url \"$repo_url\""

    # Abort on empty description
    if [[ "$repo_description" == "" ]]; then
        echo "Description empty, aborting!"
        exit 1

    # Create repo on github
    gh repo create --disable-issues --disable-wiki --homepage --public --description "$repo_description" Blunix-GmbH/$repo_name

    # Clone repo from gitlab
    git clone $repo_url

    # Push to github
    cd $repo_name
    git remote add github$repo_name
    git push github master
    cd ..
    rm -rf $repo_name


Make it executable like so:

chmod 700 /usr/local/sbin/

The following command will setup a cronjob for the script that will be executed daily at 5am:

(crontab -l 2>/dev/null; echo "0 5 * * * /usr/local/sbin/") | crontab 

Questions? Requests? Suggestions?

We are looking forward to hearing from you!

Are you looking for
Linux Emergency Support,
Linux Consulting for Projects,
Linux Managed Hosting,
Qubes OS Consulting and Support or
Linux Trainings and Workshops?