Sharing code online is pretty easy these days. But keeping in sync your repos on multiples places is a bit harder. You will easily find scripts and commands to import/export stuff somewhere. Same thing for read-only mirrors, pretty easy. But having a transparent workflow to be able to push your code on multiple places is not that easy. But hey, it's not hard neither.

You can decide to use GitHub, which the most used solution this days, but maybe, just in case of long outages or because you don’t want to be tied to GitHub that much (for political reasons, or just because they had been acquired by Microsoft and you are afraid of the Skype syndrome), you may want to have not-read-only mirrors of your repos somewhere else.

Here is a nice trick to keep in sync real git repos on multiple places like GitLab and BitBucket, that you can pull and push to, without any efforts after a quick initial setup. Not read-only mirrors. Real repos. And this just be relying on git pull and push features.

Reminder: to be safe setup SSH and Two factor Auth (2FA) for all places (except for BitBucket, cause it’s not compatible with the CLI tool).

Git Tooling

In order to facilitate the setup, we will install some CLI tools for each services.

Now you can use git push to push to all remotes and use git pull --all to pull from all remotes.

My 2 cents: use an alias to pull --all by default.

If you have a single remote this won’t change anything and will work if you have more than one.

In my .bashrc/.zshrc

alias g="git"

In my .gitconfig

g = pull --all

p = push

Now I use g g to pull and g p to push.

Pulling from multiple remotes with different updates

One edge case can be problematic: a commit in master in one repo (eg: pull request on github), and another in another distant repo (eg: merge request on gitlab). You may be able to fetch all those things (if you use pull --rebase by default) but when you will want to push back... You will have a failure unless you force push.

This is the only (edge case) that can be problematic. If you accept PR/MR with care, you should not face this very often.

Note about force push

If you encounter this case and want to force push, be sure that your branch is not protected on

GitLab protect the master branch by default. So force push will not work if you don't change configuration.

I always make one force push or two for the first commit of a project, when CI fail etc (don't juge me). Now you have been warned.

For existing GitHub repos

I didn't find or setup an automated way to do this technique for all repos at once. So each time I work on a project that I want to "backup", I check my memo and run the appropriate command for the places where my repo is missing.

Good question. For that, I don’t have the silver bullet. I think I will use GitHub as the main repo. But if there is outage, I will have fallbacks! That’s the idea of this approach: not being tied that much to a single service.

Commit from web UI

Not a problem. I tried. You commit on the web (eg: comment, notes in README etc). You pull via CLI, you push. Done. The origin you edited on the web will be up to date already, but others will be updated.

tl;dr

Once Install some CLI tools

brew install hub

gem install gitlab

pip install bitbucket-cli

Note: be sure to have tokens as env var, see the beginning of this post for details.

(Also, configure a git alias that will do pull --all if you want to pull all remote by default.)