|home| |posts| |projects| |cv| |bookmarks| |github|

Git Repo Backup Using Mirror Clone"

Why?

If you host your git repos on a 3rd-party server, the hosting company may decide to remove your repo(see youtube-dl DMCA takedown by Github).

If your repo is not popular(i.e. no forks or clones besides your own) or it is private and you lose all your local clones, you lose your work!

So, it's a good idea to have a backup for your repositories.

Possible solutions

Self-host

Host your repositories on a server you control, therefore the problem is solved.

It's an option(with to much maintenance overhead for me) but I'm not gonna talk about it here.

Third-party hosting(github, gitlab etc.) + private mirror

A simpler option is to host your repositories on someone else's servers(Github, Gitlab etc.) and then create regular backups(mirror clone + regular git fetch) on a computer you own.

Create backup(git clone --mirror)

From git-clone docs:

--bare

Make a bare Git repository.

That is, instead of creating <directory> and placing the administrative files in <directory>/.git, make the <directory> itself the $GIT_DIR.

This obviously implies the --no-checkout because there is nowhere to check out the working tree.

Also the branch heads at the remote are copied directly to corresponding local branch heads, without mapping them to refs/remotes/origin/.

When this option is used, neither remote-tracking branches nor the related configuration variables are created.

--mirror

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.

So, you create a mirror for a existing git repository by running the command:

git clone --mirror repo_uri /path/where/to/save/the/repo

Restore repository from backup

git clone /mirror_repo_uri /path_for_full_repo

Automated backup with cron

If you have multiple repos cloned in the same directory, you can write a script like this one:

#!/bin/bash

set -e

repos_dir="/path/to/where/you/cloned/your/repos"

cd $repos_dir

dirs=$(ls)

for d in $dirs
do
        cd $d
        pwd
        git fetch --all
        cd -
done

And then add the following crontab entry:

0 */1 * * * /path/to/script/from/above

This setup will update your mirror repos every hour.