Self-hosting your Git means the server is the canonical copy. Developers’ clones soften the blow of losing it - every clone has the history - but a clone is not a backup of the server: hooks, server config, access rules and anything outside the refs live nowhere else. A backup plan has to cover both, and it only counts if a restore has been rehearsed.
Mirror the repositories#
git clone --mirror git@yourserver:app.git
A mirror clone copies every ref - branches, tags, notes - and none of the working-tree state. To refresh it:
git -C app.git remote update
Two lines in a nightly cron and every repository on the server has a current, complete copy somewhere else. On a small server, loop over the bare repos directory and mirror each one.
Bundle for portability#
For a single-file, copy-anywhere backup of one repo:
git bundle create app-2026-10-21.bundle --all
A bundle is a real Git pack: git clone app-2026-10-21.bundle app reconstructs the repository on any machine with Git and nothing else. Bundles are the right shape for weekly off-site copies - one dated file per repo, uploaded to object storage or another box.
Copy what Git does not track#
The repositories are the obvious half. The other half lives next to them: server hooks (your deploy and protection scripts), the Git host’s own configuration, user and access data. A plain rsync -a of those directories into the same off-site destination covers it. Losing the repos is painful; losing the hooks and config is what turns a restore into a rebuild.
Rehearse the restore#
A backup you have never restored is a hope, not a plan. Once a month, pick one bundle or mirror and restore it to scratch space: clone from it, run the test suite, check the latest commits are there. Ten minutes, and the night the server actually dies becomes an inconvenience instead of an incident.
The honest summary: mirror nightly, bundle weekly off-site, rsync the config, restore monthly. Four small habits, and the machine your whole team depends on stops being a single point of failure.
Share this post
Keep reading
Annotating Commits with git notes: Metadata Without Rewriting History
Some things belong on a commit but not in it: review links, benchmark results, the ticket nobody remembered to reference. git notes adds them after the fact, no rebase required.
Cherry-Picking: One Commit Without the Branch
Cherry-pick copies a single commit onto your branch and leaves the rest behind. Right for hotfixes across release branches, wrong as a sync strategy.
Cleaning Untracked Files Without Regret
git clean deletes files no commit has ever held - there is no reflog for them. One dry-run flag and one .env warning make it safe.