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?
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 agit 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.