Skip to main content

Restore from Your Own Storage

If you use your own storage provider (BYOS), every backup file GitSec writes stays in your storage. You can restore a repository from these files to GitHub, GitLab or Bitbucket yourself, with Git and your cloud provider's tools, even without access to GitSec.

Use the Restore Wizard when you can

If you can still sign in to GitSec, the Restore Wizard is the easier way: it creates the repository and restores pull requests, issues and other scopes for you (depending on the target provider). Use this page when GitSec is not available to you, for example after your subscription ends.

What You Need​

  • Read access to the storage that holds the backups (AWS S3, Azure Blob, Google Drive, Onedrive or Huawei OBS).
  • Git installed on your computer.
  • An account on the target provider that can create repositories, and a way to push to it: an SSH key or an access token.
  • Enough free disk space for the backup file and the extracted repository.

How Backups Are Organized​

GitSec stores the files of each backup in its own folder:

<owner>_<repository>/<date>_<execution-id>/<scope>/<file>
PartMeaning
<owner>_<repository>The GitHub owner, GitLab namespace or Bitbucket workspace, and the repository name. For GitLab subgroups, / is replaced with _ (for example group_subgroup_repo).
<date>_<execution-id>When the backup started, in UTC, as yyyyMMdd-HHmmss, followed by the backup's execution ID.
<scope>One folder per backed-up scope: SourceCode, RepositoryMetadata, PullRequests, PullRequestComments, Issues, Releases, Collaborators.

On AWS S3 and Huawei OBS the folders start at the bucket root. On Azure Blob they are inside the Folder Path you set when you connected the storage. On Onedrive they are inside Apps > GitSec, and on Google Drive inside the folder GitSec created.

To find a specific backup, match the date and the execution ID in the folder name. The execution ID is shown for each backup snapshot in step 2 of the Restore Wizard.

What Each Scope Contains​

FolderFilesCan be restored with Git?
SourceCodeOne .tar file named <owner>_<repository>_<date>_source.tar. It contains a full mirror of the repository: all branches, tags and commit history.Yes. This is the file you restore.
RepositoryMetadataGitHub: an archive of the files on the default branch, without history. The file is named ..._repository.tar.gz but is a plain tar archive; extract it with tar -xf. GitLab and Bitbucket: a JSON file with repository settings.No. Keep it for reference.
PullRequests, PullRequestComments, Issues, Releases, CollaboratorsJSON files, one or more per scope.No. Keep them for reference or import them with your own scripts using the target provider's API.
note

Your own storage is created and controlled by you, and GitSec gets only the minimum permissions it needs to manage backup files there. For this reason, GitSec keeps backups in your storage as regular files: they are not encrypted by GitSec and not compressed, so you can open and restore them with your own tools. To protect them at rest, turn on your storage provider's encryption, for example SSE-S3 or SSE-KMS on AWS S3. Backups on GitSec Storage are always encrypted by GitSec.

Step 1: Download the Source Code Archive​

Open the backup folder you want to restore and download the .tar file in its SourceCode folder.

StorageHow to download
AWS S3From the S3 console, or with the AWS CLI: aws s3 cp "s3://<bucket>/<path>/<file>_source.tar" .
Azure BlobFrom the Azure portal (Storage accounts > your container), or with the Azure CLI: az storage blob download --connection-string "<connection-string>" --container-name <container> --name "<path>/<file>_source.tar" --file <file>_source.tar. If you use a SAS URL, pass --blob-url "<SAS URL that includes the blob path>" instead of the connection string, container and name.
Huawei OBSFrom the OBS console, or with obsutil (run obsutil config first): obsutil cp "obs://<bucket>/<path>/<file>_source.tar" ./<file>_source.tar
Google DriveOpen the GitSec folder in Google Drive, browse to the backup folder and download the file.
OnedriveOpen Apps > GitSec in Onedrive, browse to the backup folder and download the file.

Step 2: Extract the Repository​

The archive contains a bare Git repository without a top-level folder. Extract it into a new, empty folder:

mkdir my-repo.git
tar -xf <file>_source.tar -C my-repo.git

Check that the repository is complete and see its branches and tags:

git -C my-repo.git fsck
git -C my-repo.git branch -a
git -C my-repo.git tag

Note the default branch; you will need it in Step 5:

git -C my-repo.git symbolic-ref --short HEAD

Step 3: Create an Empty Repository on the Target Provider​

Create a new repository and leave it empty: do not add a README, license or .gitignore. Otherwise the first push is rejected.

  • GitHub: Click New repository, choose the owner, enter a name, and do not add a README, .gitignore or license.
  • GitLab: Click New project > Create blank project, choose the group or your personal namespace, and clear Initialize repository with a README. This works for both GitLab.com and Self-Managed GitLab.
  • Bitbucket: Click Create > Repository, choose the workspace and project, and set both Include a README? and Include .gitignore? to No.

Copy the repository's clone URL (HTTPS or SSH).

Step 4: Push the Branches and Tags​

Push every branch and every tag to the new repository:

cd my-repo.git
git push <clone-url> 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*'

When you push over HTTPS, use an access token as the password: a personal access token on GitHub or GitLab, an API token on Bitbucket.

Avoid git push --mirror

A mirror backup also contains the provider's internal references, such as refs/pull/* on GitHub or refs/merge-requests/* on GitLab. git push --mirror tries to push them too, and the target provider rejects them with errors such as deny updating a hidden ref. Pushing only branches and tags, as shown above, avoids this.

Step 5: Check the Restored Repository​

  1. Set the default branch you noted in Step 2 in the repository settings, if the provider chose another one.
  2. Compare the branch and tag counts with the output of Step 2, for example with git ls-remote --heads --tags <clone-url>.
  3. Re-create what Git does not carry: branch protection rules, webhooks, CI/CD settings and secrets, and member access.

Limitations​

  • Only code and history are restored this way. Pull requests, issues, releases, collaborators and repository settings are stored as JSON files and cannot be imported with Git. To restore them automatically, use the Restore Wizard; see What Can Be Restored? for what each provider supports.