Skip to content

Instantly share code, notes, and snippets.

@aclk
Forked from MoOx/README.md
Created June 5, 2018 06:49
Show Gist options
  • Save aclk/9b928405b5bf382fd3ae1dff16fc8c61 to your computer and use it in GitHub Desktop.
Save aclk/9b928405b5bf382fd3ae1dff16fc8c61 to your computer and use it in GitHub Desktop.

Revisions

  1. @MoOx MoOx revised this gist Jun 5, 2018. 1 changed file with 1 addition and 303 deletions.
    304 changes: 1 addition & 303 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,303 +1 @@
    ---
    title: How to keep in sync your Git repos on GitHub, GitLab & Bitbucket easily
    tags:
    - git
    - github
    - gitlab
    - bitbucket
    authors:
    - MoOx
    ---

    GitHub is nice, but maybe, just in case of long outage or because you don’t want to be tied to GitHub that much, you may want to have mirrors or your repos somewhere else.
    Here is a nice way to keep not just read only mirrors, but real git repos on GitLab and BitBuckets as well.

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

    [tl;dr?](#tl-dr)

    ## Git Tooling

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

    ### Github

    We will use [hub](https://github.com/github/hub).

    For macOS, it’s easy.

    ```console
    brew install hub
    ```

    See [Hub installation instruction page](https://github.com/github/hub#installation) for others OSes.

    You will need a [GitHub token](https://github.com/settings/tokens/new).

    Place it in your home folder in a ``.github_token`` file,
    and load it in your `.bash/zshrc` like this:

    ```sh
    if [[ -f $HOME/.github_token ]]
    then
    export GITHUB_TOKEN=$(cat $HOME/.github_token)
    fi
    ```

    ### GitLab

    [GitLab CLI](http://narkoz.github.io/gitlab/cli) is available via [rubygem](https://rubygems.org/):

    ```console
    (sudo) gem install gitlab
    ```

    #### ``Please set an endpoint to API``

    GitLab requires a token and an endpoint.

    For the token,
    [grab you GitLab private token here](https://gitlab.com/profile/account)
    and use the same solution as GitHub.
    Here is an example using GitLab “official” online instance that you should add in your ``.bash/zshrc``:

    ```sh
    if [[ -f $HOME/.gitlab_token ]]
    then
    export GITLAB_API_PRIVATE_TOKEN=$(cat $HOME/.gitlab_token)
    fi
    export GITLAB_API_ENDPOINT="https://gitlab.com/api/v3"
    ```

    ### BitBucket

    [BitBucket CLI](https://bitbucket.org/zhemao/bitbucket-cli) is available via [pip](https://pip.pypa.io/en/stable/):

    ```sh
    (sudo) pip install bitbucket-cli
    ```

    BitBucket does not work well with a token…
    2fa is not convenient (and [impossible to use with ssh](https://bitbucket.org/zhemao/bitbucket-cli/issues/25/create-issue-ssh-not-taken-in))
    So you will have to enter login/pwd all the time or [put that in clear in a .bitbucket file](https://bitbucket.org/zhemao/bitbucket-cli#markdown-header-configuration)

    ---

    Now that we have all the tools, let's start by creating a repo on each services.

    ## Create a repo on GitHub, GitLab & Bitbucket using CLI

    The commands below assume that your username is the same on each services.
    If that's not the case, just adjust the command by replacing all variables.

    We will create/reuse a folder, init a local git repo, and push it to all those services.

    ### Your git repo exists

    Just go into your repo and do

    ```console
    GIT_REPO_NAME=$(basename $(pwd))
    ```

    ### You don't have a git repo yet

    ```console
    GIT_REPO_NAME="your-repo"
    mkdir $GIT_REPO_NAME && cd $GIT_REPO_NAME
    git init
    ```

    ### Create repo on GitHub via CLI

    ```console
    hub create
    ```

    This command create the repo and add the remote automatically.

    ### Create repo on GitLab via CLI

    ```console
    gitlab create_project $GIT_REPO_NAME "{visibility_level: 20}"
    ```

    (Public visibility).
    [Source](http://stackoverflow.com/a/31338095/988941)

    We will add the remote later, it's part of the trick ;)

    ### Create repo on BitBucket via CLI

    ```
    bb create --protocol=ssh --scm=git --public $GIT_REPO_NAME
    ```

    [Source](http://stackoverflow.com/a/12795747/988941)

    ## Configuring remotes

    Depending on what you want or need, you will have multiple choice to configure your repo.

    For a single main repo and simple “mirrors”, you can use this

    ```console
    git remote set-url origin --add https://gitlab.com/${USER}/${GIT_REPO_NAME}.git
    git remote set-url origin --add https://bitbucket.org/${USER}/${GIT_REPO_NAME}.git
    ```

    You can check with

    ```console
    git remote -v
    origin https://github.com/MoOx/your-repo.git (fetch)
    origin https://github.com/MoOx/your-repo.git (push)
    origin https://gitlab.com/MoOx/your-repo.git (push)
    origin https://bitbucket.org/MoOx/your-repo.git (push)
    ```

    Now you can just use ``git push`` 🙂.

    ---

    ⚠️ Note: to enforce ssh instead of https here is a simple trick

    ```console
    git config --global url.ssh://[email protected]/.insteadOf https://github.com/
    git config --global url.ssh://[email protected]/.insteadOf https://gitlab.com/
    git config --global url.ssh://[email protected]/.insteadOf https://bitbucket.org/
    ```

    ---

    **Problem is: ``git pull`` will only pull from the first url.**

    There is inconsitencies with ``git push --all`` (push all branches to default
    remote) and ``git pull --all`` (pull from the first url of the default remote).

    [Here is a detailed post on configuring multiples remote for push, pull or both](https://astrofloyd.wordpress.com/2015/05/05/git-pushing-to-and-pulling-from-multiple-remote-locations-remote-url-and-pushurl/).

    _tl;dr: we will have to add other remotes to be able to push._

    ```console
    git remote add origin-gitlab https://gitlab.com/${USER}/${GIT_REPO_NAME}.git
    git remote add origin-bitbucket https://bitbucket.org/${USER}/${GIT_REPO_NAME}.git
    ```

    You can double check with:

    ```
    git remote -v
    origin ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin-gitlab ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin-gitlab ssh://[email protected]/MoOx/your-repo.git (push)
    origin-bitbucket ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin-bitbucket ssh://[email protected]/MoOx/your-repo.git (push)
    ```

    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.

    ⚠️ You might need a warning that will ask you to do

    ```
    git branch --set-upstream-to=origin/master master
    ```

    I use ``gg`` to pull and ``gp`` to push :)

    ## Pulling from multiple remotes with different updates

    Un cas de figure peut être problématique: un commit dans la master sur un repo, un autre commit dans une autre master d’un autre repo, on fetch le tout en local, on veut pousser… Et bam. On va être obligé de force pusher.
    A part ce cas de figure (qui je l’accorde n’est pas terrible à gérer, mais devrait rester rarissime), je ne vois pas d’autre soucis potentiel.
    Avec un peu de discipline et de rigueur, on devrait s’en tirer :)

    ### Note about force push

    open https://gitlab.com/${USER}/${GIT_REPO_NAME}/protected_branches

    GitLab protect the master branch **by default**. So force push will not work.
    I always make one force push or two for the first commit of a project, when CI fail etc (I know I should not).
    **Now you have been warned.**


    ## For existing GitHub repo

    Je n’ai encore rien tester mais voici 2 outils qui devrait pouvoir aider.

    https://pypi.python.org/pypi/github2gitlab
    https://github.com/xuhdev/backup-on-the-go

    A la limite ajouter les repos au fur et à mesure est aussi une solution, celle que j’adopterais.

    ## FAQ

    ### Handling issues and Pull/Merge request

    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 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, you push. Done.
    The origin you edited on the web will be up to date already, but other will be updated.

    ## tl;dr (with all CLI tools installed and configured)

    0. If you GitHub/GitLab/BitBucket is not exactly your $USER

    ```
    USER=MoOx
    ```

    1. For New repo (if your repo already exist on GitHub, go to 2.)

    ```
    GIT_REPO_NAME=your-repo
    mkdir $GIT_REPO_NAME && cd $GIT_REPO_NAME
    git init
    hub create
    ```

    2. For existing GitHub repo

    ```console
    GIT_REPO_NAME=$(basename $(pwd))
    gitlab create_project $GIT_REPO_NAME "{visibility_level: 20}"
    bb create --protocol=ssh --scm=git --public $GIT_REPO_NAME
    git remote set-url origin --add https://gitlab.com/${USER}/${GIT_REPO_NAME}.git
    git remote set-url origin --add https://bitbucket.org/${USER}/${GIT_REPO_NAME}.git
    git remote add origin-gitlab https://gitlab.com/${USER}/${GIT_REPO_NAME}.git
    git remote add origin-bitbucket https://bitbucket.org/${USER}/${GIT_REPO_NAME}.git
    ```

    3. Check that everything is ok

    ```
    git remote -v
    origin ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin-bitbucket ssh://[email protected]/MoOx/your-repo.git (push)
    origin-bitbucket ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin-gitlab ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin-gitlab ssh://[email protected]/MoOx/your-repo.git (push)
    ```

    😇 Now you can just ``git push`` and ``git pull``!

    ## Bonus: badges

    You can add some nices badges to show the redundancy on your project README

    ```
    [![Repo on GitHub](https://img.shields.io/badge/repo-GitHub-3D76C2.svg)](https://github.com/MoOx/your-repo)
    [![Repo on GitLab](https://img.shields.io/badge/repo-GitLab-6C488A.svg)](https://gitlab.com/MoOx/your-repo)
    [![Repo on BitBucket](https://img.shields.io/badge/repo-BitBucket-1F5081.svg)](https://bitbucket.org/MoOx/your-repo)
    ```
    https://moox.io/blog/keep-in-sync-git-repos-on-github-gitlab-bitbucket/
  2. @MoOx MoOx revised this gist Sep 25, 2017. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,3 @@
    # How to keep in sync your Git repos on GitHub, GitLab & Bitbucket easily

    ---
    title: How to keep in sync your Git repos on GitHub, GitLab & Bitbucket easily
    tags:
  3. @MoOx MoOx created this gist Sep 25, 2017.
    305 changes: 305 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,305 @@
    # How to keep in sync your Git repos on GitHub, GitLab & Bitbucket easily

    ---
    title: How to keep in sync your Git repos on GitHub, GitLab & Bitbucket easily
    tags:
    - git
    - github
    - gitlab
    - bitbucket
    authors:
    - MoOx
    ---

    GitHub is nice, but maybe, just in case of long outage or because you don’t want to be tied to GitHub that much, you may want to have mirrors or your repos somewhere else.
    Here is a nice way to keep not just read only mirrors, but real git repos on GitLab and BitBuckets as well.

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

    [tl;dr?](#tl-dr)

    ## Git Tooling

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

    ### Github

    We will use [hub](https://github.com/github/hub).

    For macOS, it’s easy.

    ```console
    brew install hub
    ```

    See [Hub installation instruction page](https://github.com/github/hub#installation) for others OSes.

    You will need a [GitHub token](https://github.com/settings/tokens/new).

    Place it in your home folder in a ``.github_token`` file,
    and load it in your `.bash/zshrc` like this:

    ```sh
    if [[ -f $HOME/.github_token ]]
    then
    export GITHUB_TOKEN=$(cat $HOME/.github_token)
    fi
    ```

    ### GitLab

    [GitLab CLI](http://narkoz.github.io/gitlab/cli) is available via [rubygem](https://rubygems.org/):

    ```console
    (sudo) gem install gitlab
    ```

    #### ``Please set an endpoint to API``

    GitLab requires a token and an endpoint.

    For the token,
    [grab you GitLab private token here](https://gitlab.com/profile/account)
    and use the same solution as GitHub.
    Here is an example using GitLab “official” online instance that you should add in your ``.bash/zshrc``:

    ```sh
    if [[ -f $HOME/.gitlab_token ]]
    then
    export GITLAB_API_PRIVATE_TOKEN=$(cat $HOME/.gitlab_token)
    fi
    export GITLAB_API_ENDPOINT="https://gitlab.com/api/v3"
    ```

    ### BitBucket

    [BitBucket CLI](https://bitbucket.org/zhemao/bitbucket-cli) is available via [pip](https://pip.pypa.io/en/stable/):

    ```sh
    (sudo) pip install bitbucket-cli
    ```

    BitBucket does not work well with a token…
    2fa is not convenient (and [impossible to use with ssh](https://bitbucket.org/zhemao/bitbucket-cli/issues/25/create-issue-ssh-not-taken-in))
    So you will have to enter login/pwd all the time or [put that in clear in a .bitbucket file](https://bitbucket.org/zhemao/bitbucket-cli#markdown-header-configuration)

    ---

    Now that we have all the tools, let's start by creating a repo on each services.

    ## Create a repo on GitHub, GitLab & Bitbucket using CLI

    The commands below assume that your username is the same on each services.
    If that's not the case, just adjust the command by replacing all variables.

    We will create/reuse a folder, init a local git repo, and push it to all those services.

    ### Your git repo exists

    Just go into your repo and do

    ```console
    GIT_REPO_NAME=$(basename $(pwd))
    ```

    ### You don't have a git repo yet

    ```console
    GIT_REPO_NAME="your-repo"
    mkdir $GIT_REPO_NAME && cd $GIT_REPO_NAME
    git init
    ```

    ### Create repo on GitHub via CLI

    ```console
    hub create
    ```

    This command create the repo and add the remote automatically.

    ### Create repo on GitLab via CLI

    ```console
    gitlab create_project $GIT_REPO_NAME "{visibility_level: 20}"
    ```

    (Public visibility).
    [Source](http://stackoverflow.com/a/31338095/988941)

    We will add the remote later, it's part of the trick ;)

    ### Create repo on BitBucket via CLI

    ```
    bb create --protocol=ssh --scm=git --public $GIT_REPO_NAME
    ```

    [Source](http://stackoverflow.com/a/12795747/988941)

    ## Configuring remotes

    Depending on what you want or need, you will have multiple choice to configure your repo.

    For a single main repo and simple “mirrors”, you can use this

    ```console
    git remote set-url origin --add https://gitlab.com/${USER}/${GIT_REPO_NAME}.git
    git remote set-url origin --add https://bitbucket.org/${USER}/${GIT_REPO_NAME}.git
    ```

    You can check with

    ```console
    git remote -v
    origin https://github.com/MoOx/your-repo.git (fetch)
    origin https://github.com/MoOx/your-repo.git (push)
    origin https://gitlab.com/MoOx/your-repo.git (push)
    origin https://bitbucket.org/MoOx/your-repo.git (push)
    ```

    Now you can just use ``git push`` 🙂.

    ---

    ⚠️ Note: to enforce ssh instead of https here is a simple trick

    ```console
    git config --global url.ssh://[email protected]/.insteadOf https://github.com/
    git config --global url.ssh://[email protected]/.insteadOf https://gitlab.com/
    git config --global url.ssh://[email protected]/.insteadOf https://bitbucket.org/
    ```

    ---

    **Problem is: ``git pull`` will only pull from the first url.**

    There is inconsitencies with ``git push --all`` (push all branches to default
    remote) and ``git pull --all`` (pull from the first url of the default remote).

    [Here is a detailed post on configuring multiples remote for push, pull or both](https://astrofloyd.wordpress.com/2015/05/05/git-pushing-to-and-pulling-from-multiple-remote-locations-remote-url-and-pushurl/).

    _tl;dr: we will have to add other remotes to be able to push._

    ```console
    git remote add origin-gitlab https://gitlab.com/${USER}/${GIT_REPO_NAME}.git
    git remote add origin-bitbucket https://bitbucket.org/${USER}/${GIT_REPO_NAME}.git
    ```

    You can double check with:

    ```
    git remote -v
    origin ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin-gitlab ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin-gitlab ssh://[email protected]/MoOx/your-repo.git (push)
    origin-bitbucket ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin-bitbucket ssh://[email protected]/MoOx/your-repo.git (push)
    ```

    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.

    ⚠️ You might need a warning that will ask you to do

    ```
    git branch --set-upstream-to=origin/master master
    ```

    I use ``gg`` to pull and ``gp`` to push :)

    ## Pulling from multiple remotes with different updates

    Un cas de figure peut être problématique: un commit dans la master sur un repo, un autre commit dans une autre master d’un autre repo, on fetch le tout en local, on veut pousser… Et bam. On va être obligé de force pusher.
    A part ce cas de figure (qui je l’accorde n’est pas terrible à gérer, mais devrait rester rarissime), je ne vois pas d’autre soucis potentiel.
    Avec un peu de discipline et de rigueur, on devrait s’en tirer :)

    ### Note about force push

    open https://gitlab.com/${USER}/${GIT_REPO_NAME}/protected_branches

    GitLab protect the master branch **by default**. So force push will not work.
    I always make one force push or two for the first commit of a project, when CI fail etc (I know I should not).
    **Now you have been warned.**


    ## For existing GitHub repo

    Je n’ai encore rien tester mais voici 2 outils qui devrait pouvoir aider.

    https://pypi.python.org/pypi/github2gitlab
    https://github.com/xuhdev/backup-on-the-go

    A la limite ajouter les repos au fur et à mesure est aussi une solution, celle que j’adopterais.

    ## FAQ

    ### Handling issues and Pull/Merge request

    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 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, you push. Done.
    The origin you edited on the web will be up to date already, but other will be updated.

    ## tl;dr (with all CLI tools installed and configured)

    0. If you GitHub/GitLab/BitBucket is not exactly your $USER

    ```
    USER=MoOx
    ```

    1. For New repo (if your repo already exist on GitHub, go to 2.)

    ```
    GIT_REPO_NAME=your-repo
    mkdir $GIT_REPO_NAME && cd $GIT_REPO_NAME
    git init
    hub create
    ```

    2. For existing GitHub repo

    ```console
    GIT_REPO_NAME=$(basename $(pwd))
    gitlab create_project $GIT_REPO_NAME "{visibility_level: 20}"
    bb create --protocol=ssh --scm=git --public $GIT_REPO_NAME
    git remote set-url origin --add https://gitlab.com/${USER}/${GIT_REPO_NAME}.git
    git remote set-url origin --add https://bitbucket.org/${USER}/${GIT_REPO_NAME}.git
    git remote add origin-gitlab https://gitlab.com/${USER}/${GIT_REPO_NAME}.git
    git remote add origin-bitbucket https://bitbucket.org/${USER}/${GIT_REPO_NAME}.git
    ```

    3. Check that everything is ok

    ```
    git remote -v
    origin ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin ssh://[email protected]/MoOx/your-repo.git (push)
    origin-bitbucket ssh://[email protected]/MoOx/your-repo.git (push)
    origin-bitbucket ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin-gitlab ssh://[email protected]/MoOx/your-repo.git (fetch)
    origin-gitlab ssh://[email protected]/MoOx/your-repo.git (push)
    ```

    😇 Now you can just ``git push`` and ``git pull``!

    ## Bonus: badges

    You can add some nices badges to show the redundancy on your project README

    ```
    [![Repo on GitHub](https://img.shields.io/badge/repo-GitHub-3D76C2.svg)](https://github.com/MoOx/your-repo)
    [![Repo on GitLab](https://img.shields.io/badge/repo-GitLab-6C488A.svg)](https://gitlab.com/MoOx/your-repo)
    [![Repo on BitBucket](https://img.shields.io/badge/repo-BitBucket-1F5081.svg)](https://bitbucket.org/MoOx/your-repo)
    ```