Backup guide

Back up a Git repository — properly

Most "backups" are a stale clone of one branch. Here's what a real Git backup contains, and the four ways teams create one.

01 — The problem

Why git clone is not a backup

A clone captures a single moment. Without something that reruns it automatically, that moment gets further from true every day.

One branch, not the repository

A default git clone brings down one branch's tip and a working tree. Every other branch, every tag, and repository notes are left on the server — invisible until the day you go looking for them.

Stale the moment someone pushes

A backup taken once is accurate for exactly as long as nobody commits. On a repository anyone is actively working in, that's minutes, not days.

--mirror fixes the refs, not the freshness

git clone --mirror captures every ref — branches, tags, notes, the full graph — but only for the instant it runs. It solves completeness. It does nothing about how current the copy stays afterward.

02 — Compare

Four ways to back up a repository

Every approach on this list can produce a working backup. They differ in what happens the day you need to prove it.

Feature Manual clone Cron script Provider export Git Replica
Runs automatically
Captures every ref
Freshness Whenever you remember Up to the interval Provider's schedule Seconds after each push
Cross-provider
Restore effort Manual Manual Import job Single git push
Ongoing maintenance Yours Yours — scripts, creds, alerts Provider's None
03 — Completeness

What a complete backup contains

A backup that's missing refs, or missing context, isn't incomplete by accident — it's incomplete by definition.

Every ref

Branches, tags, notes and the full commit graph, using git clone --mirror semantics. Provider-internal refs like refs/pull/* are deliberately excluded — every provider rejects pushes to them, so keeping them would only break the restore.

Repository metadata

Issues, pull requests, reviews, comments, labels, milestones and release notes, optionally captured as JSON alongside the code when the destination is object storage. See what's inside an archive →

The archive itself

Timestamped per repository and retained on the rules you set — never silently overwritten, never shared across repositories.

One more thing "complete" doesn't cover: Git LFS pointer files are included in every backup, but the LFS object content they point to is not.

04 — How it works

Four steps to an automatic backup

Connect once. Everything after the first push runs without you.

Connect a source account

GitHub, GitLab or Bitbucket over OAuth, or any Git server reachable over HTTPS or SSH.

Create a binding

Pick the source repository and a destination — another Git host, or an object-storage bucket.

Pushes trigger the sync

The moment you push, GitHub, GitLab and Bitbucket sources fire a webhook and the backup starts. Custom and self-hosted remotes sync hourly, daily or weekly, or on demand.

Watch the sync log

Every step is recorded, with email on failure so a broken backup doesn't go unnoticed.

05 — Destinations

Where the backup should live

A replica and an archive both keep your code safe — they just answer different follow-up questions on the day something breaks.

Another Git host

A live, clonable replica somebody can work from today — point CI at it, or keep going if the primary host is unreachable. See how mirroring works →

Object storage

Point-in-time archives with retention, written to a bucket you own. See backups to S3 →

FAQ

Backup questions

Is git clone enough to back up a repository?

No. A default git clone gives you one branch's tip and a working tree — every other branch, tag and note is left behind. Running git clone --mirror fixes that by capturing every ref, but only for the instant it runs; the moment someone pushes again, that mirror is stale. A real backup needs full-ref coverage and something that reruns automatically after every push, not a command you remember to type.

What does a complete Git backup include?

Every ref in the repository — branches, tags, notes and the full commit graph, using the same semantics as git clone --mirror. Provider-internal refs such as refs/pull/* and refs/merge-requests/* are deliberately excluded, since every provider rejects pushes to them. A complete backup can also optionally include the repository's metadata — issues, pull requests, reviews, comments, labels, milestones and release notes — captured as JSON alongside the code when the destination is object storage. Git LFS pointer files replicate; the LFS object content itself does not.

How often should Git repositories be backed up?

As often as the repository changes, which is why a fixed interval is the wrong starting point. GitHub, GitLab and Bitbucket sources back up on every push, the moment your provider delivers the webhook. Self-hosted and custom remotes don't support webhooks, so they sync on a schedule instead — hourly, daily or weekly — or on demand before a risky operation. Push-triggered wherever it's available, with a schedule as the floor everywhere else.

How do I restore a repository from a backup?

It depends on where the backup lives. If it's a replica on another Git host, point your remote at it — it's already a working repository. If it's an archive in object storage, download the zip, unzip it, and run git push --mirror against a new remote; every ref goes back in a single push. Either way, restoring is an ordinary Git operation, not a proprietary import process.

Back up your first repository in two minutes.

Connect a provider account, create a binding, and your next push is protected. Free for open source and private non-commercial use.

Get started free