Skip to content
How I mirror my GitHub repositories on GitLab (thanks to Framagit)

How I mirror my GitHub repositories on GitLab (thanks to Framagit)

Published: at 01:37 PMSuggest Changes

For more than 10 years, I use git and I publish my open-source projects on GitHub. The platform is great, its tooling too. But I don’t know what tomorrow will bring, especially for a service from Microsoft.

Thus, I prefer not to put all my eggs in one basket. So, some months ago I looked after an open-source alternative. I didn’t want to rely only on my local repositories or on a self-hosted service. Of course, GitLab was one of the first to come to mind, but I needed a managed service.

I already use Heptapod at work (GitLab with Mercurial support), but in a personal context I mostly rely on Framasoft. So, I finally chose to create an account on Framagit. But once it’s done, how to backup my repositories?

Degoogleify Framasoft

Create a mirror repo with a GitLab push remote

There is a GitLab Mirror option, but I want to rely on a lower layer. Thus, on my main computer, I have GitHub/ and GitLab/ folders. In the first, I simply clone my repositories. In the second, I do the same using the --mirror flag. As stated in the official git documentation:

Set up a mirror of the source repository. This implies --bare. Compared to --bare, --mirror not only maps local branches of the source to local branches of the target, it maps all refs (including remote-tracking branches, notes etc.) and sets up a refspec configuration such that all these refs are overwritten by a git remote update in the target repository.

Then, I create an empty GitLab repository and use it as a push remote:

git clone --mirror https://github.com/user/repo.git
cd repo.git
git remote set-url --push gitlab git@framagit.org:user/repo.git

Fetch/Push the content (via an alias)

To sync your mirror from its local folder, you only need to:

git fetch --prune && git push --mirror

You can use an alias declared in .bashrc or .zshrc to perform this sync action on multiple repositories from a single command:

function sync_git() {
  GITLAB_DIR="/path/to/gitlab/directory"

  # Declare an array of repo subdirectories
  declare -a REPO_DIRS=("repo1" "repo2" "repo3")

  # Go in each of them and sync
  for repo_dir in "${REPO_DIRS[@]}"; do
      echo "Entering ${GITLAB_DIR}/${repo_dir}.git"
      cd "${GITLAB_DIR}/${repo_dir}.git"

      git fetch --prune && git push --mirror

      echo
  done

  printf "%s \e[32m✓\e[0m\n" "Script completed"
}

After saving the file, reload your shell with exec bash or exec zsh.

Go further

You can launch this command manually or on a regular basis through CRON for example (but you’ll need a git authentication not asking for a passphrase).

For my needs, I use this script in a more complete alias to update my system and tools (brew, bun, npm, rustup, v, etc.), with additional commands to clone some repositories I need to have locally, up to date.

The most important

Don’t forget to support Framasoft. This is how their great actions are funded, along with services such as Framagit.


Previous Post
How I've upgraded this blog to Astro(Paper) 4.0
Next Post
How this blog was built