What's inside a Git backup archive
No proprietary format: unzip it and you have a repository Git accepts. Optionally with your issues, pull requests and releases alongside it.
A zipped bare mirror
Nothing exotic — a standard Git bundle, compressed, sitting in a bucket you control.
Nothing to decode
The archive is a zip of a bare git clone --mirror of the repository. Unzip it and the result is a directory an ordinary git clone accepts — no proprietary format, no vendor tool required to read it.
Written straight to your storage
Each sync — triggered the moment you push, for GitHub, GitLab and Bitbucket sources — streams the archive straight to your destination. GitReplica keeps no permanent copy of your source code once the upload confirms.
What's in the file
The code, and — if you turn it on — everything around the code that isn't stored in Git.
The bare mirror
Every branch, tag, note and the full commit graph — the same git clone --mirror semantics used everywhere else in GitReplica. LFS pointer files are included; the LFS object content itself is not.
gitreplica-metadata/
Optional per binding. Issues, pull requests, reviews, comments, labels, milestones and release notes as JSON, plus a manifest.json describing the snapshot. Release binary files are never downloaded.
A timestamped name
Each archive is written as a new object keyed by repository name and UTC timestamp. Nothing is ever overwritten — every successful sync adds one more archive.
Object keys and keeping the right number
Predictable paths, and two ways to stop them from accumulating forever.
backups/acme/api/api-2026-08-13T09-14-02Z.zip
backups/acme/api/api-2026-08-12T09-13-58Z.zip
backups/acme/web/web-2026-08-13T09-14-05Z.zip
Keep the last N
Set a retention count on the binding and GitReplica prunes older archives automatically after each successful upload, keeping only the most recent N.
Or use your bucket's lifecycle rules
Leave retention off and every archive stays until you delete it — or let your bucket's own lifecycle policy expire objects on a schedule you already manage.
Restoring is a push
No import wizard, no support ticket — the same two Git commands you'd use to move any repository.
Download the archive you want
Archives are plain objects in your bucket — no export step, no vendor tool. Grab the one you need with any S3 or Azure client.
Unzip it
Unzipping produces a bare repository directory, exactly as git clone --mirror would have created it locally.
Push it anywhere
Point it at a new remote and run git push --mirror <new-remote>. Every branch, tag and note goes back in one command.
Verify
If the archive included a metadata snapshot, compare branch and tag counts against manifest.json to confirm the restore matched what was captured.
Storage you already own
The archive lands in a bucket with your name on it, not a GitReplica-hosted vault.
S3 and S3-compatible
Amazon S3, Cloudflare R2, Backblaze B2, Wasabi, DigitalOcean Spaces, Hetzner, OVH, Scaleway, Google Cloud Storage via HMAC keys, or any other custom S3-compatible endpoint. See the full S3 setup guide →
Azure Blob Storage
Connect with an account key or a connection string. Same push-triggered archives, same per-binding retention as any S3-compatible destination.
Git backup archive questions
What format is a Git backup archive?
A Git backup archive is a zip file containing a bare git clone --mirror of the repository — every branch, tag, note and the full commit graph. There's no proprietary format: unzip it and the result is a directory an ordinary git clone accepts. If the metadata snapshot was turned on for that binding, the same zip also contains a gitreplica-metadata/ folder with issues, pull requests, reviews, comments, labels, milestones and release notes as JSON, plus a manifest.json describing what was captured.
What is the repository metadata snapshot?
The metadata snapshot is an optional, per-binding setting on object-storage destinations. When it's on, each archive also captures issues, pull requests, reviews, comments, labels, milestones and release notes as JSON — never release binary files. On a GitHub App installation, the App needs Issues and Pull requests read permission for that data to be included; on Bitbucket, the connected account needs the matching consumer scopes. If either is missing, the backup still succeeds — the sync log records a warning and the archive ships with just the bare mirror.
How many archives are kept?
As many as you configure. Set a retention count on the binding and GitReplica prunes older archives automatically after each successful upload, keeping only the most recent N. Leave retention off and every archive stays until you delete it, or until your bucket's own lifecycle rules expire it.
How do I restore from an archive?
Download the archive from your bucket and unzip it — you now have a bare repository. Push it anywhere with git push --mirror <new-remote> to restore every ref, then compare branch and tag counts against the manifest to confirm the restore matched what was captured.
Keep reading
Git backup to S3
Push-triggered archives into your own S3 or S3-compatible bucket.
Git disaster recovery
Outage, lockout, force-push, deletion — and the recovery path for each.
Back up a Git repository
Why a clone isn't a backup, and the four ways teams actually do it.
Git archive examples
Practical ZIP, TAR, folder, tag, prefix, and export-ignore examples.
Automated GitHub backup
Back up GitHub repositories to another provider or storage you control.
git push --mirror explained
What it copies, force-updates and deletes — and how to verify before running it.
Put an archive in your own bucket tonight.
Connect a storage destination, create a binding, and your next push is archived. Free for open source and private non-commercial use.
Get started free