How to back up your Git repositories

Alberto de Murga
4 min readDec 30, 2021

Making backups is important. You don’t want to lose all your information because of a broken device or a stolen account. One proposed solution is the 3–2–1 method (3 copies, at least in 2 different devices, and 1 of them off-site) and you should make at least one full backup every year (that could match the World Backup Day). What to back up is up to you. You can backup your contacts, emails, messages, social networks content… and your code.

Backing up code is a bit tricky question. Most of the people host their code on their computer, probably with Git and maybe on Github. But having one copy is having no copies. You don’t want to depend on Github exclusively for your code, and it is wise to have at least one extra copy. The question is then, how to make that extra copy.

Photo by Siyuan Hu on Unsplash

Pushing to an additional remote

This is the easiest method with less friction, and it will backup both your code and the git commit history. However, it will require a remote git repository hosted somewhere else, like Gitlab, sourcehut or your own. The issue with this method is that it will not provide you with an offline copy of the code.

Pros:

  • The easiest and fastest method
  • Preserves git commit history

Cons:

  • Requires an external server
  • Not offline.
$ git remote add backup <remote empty repository>

Use git bundle

This functionality of git is used to make offline transfers without a server in between. Essentially, it will pick up a branch and .pack it. You can then take the bundle and use it as an origin for a new repository. You can even update the bundle and pull from it.

Pros:

  • Preserves git commit history.
  • Allows updating the bundle to pull changes.
  • Offline.

Cons:

  • Requires creating a new repository to see the contents.
  • You can easily mess it up when you try to pull changes from the bundle.
# You can also use --all instead of a branch for bundling
# all branches
$ git bundle create path/to/file.bundle branch_name
# Verify the content of the bundle.
$ git bundle verify file.bundle
# Add the bundle as origin for a new repository.
$ git init backup-repo
$ cd backup-repo
$ git remote add origin path/to/file.bundle
$ git pull origin master

Use git archive

Similar to git bundle, this functionality is used to generate releases of source code. It will generate a compressed file with the tracked files of the given commit or tag.

Pros:

  • Easy handle: it is just a zip.
  • Offline

Cons:

  • It does not preserve the git commit history.
$ git archive --output=backup.zip HEAD

Copy/paste your repositories

Trust me, don’t. Copy-pasting will try to move every single file one by one. This means every single file in the git commit history and/or the vendored dependencies (looking at you, node_modules). This operation will take an awful amount of time, making it unfeasible for moving more than a project. It might still work for very small projects but as soon as you have a decently sized project, you will regret this decision.

Pros

  • “Easy”
  • Preserves vendored dependencies.

Cons

  • You will regret very fast taking this decision.

Zip the repository

An improvement over the previous solution. Instead of copy-pasting, the repository is first zipped before moving it. It is a less bad solution than copy-pasting, but still worse than using git archive. You need to exclude/remove the git commit history files and/or the vendored dependency files by yourself, although this method allows you to keep them if you want.

Pros:

  • Allows you keep (or not) vendored dependencies.
  • Offline

Cons:

  • You need to include/exclude files one by one.
  • Barely better than copy-pasting.
$ zip -r -9 backup.zip path/to/repo

Conclusion

As far as you make a backup copy, it doesn’t matter what method you choose. I use a combination of an additional remote repository and git archive. It gives a remote copy and an offline copy I can put in my cloud storage providers and my little NAS.

Did you like this post? Let me know on Twitter!

Update (January 26th, 2022)

First of all, I would like to apologise for such a late edit of this article. Most of the reactions happened during the first week since the publication of this article, but due to the Christmas holidays and the fact that I was visiting my family for first time since the start of the pandemic did not help.

Among those reactions, there were a some of them that grabbed my attention and I think they add some interesting approaches to this topic. Thank you very much to everyone who participated in the conversation.

  • ClashTheBunny suggests a StackOverflow thread in which I learnt that you can add more than one push URL to a Git repository, making even easier to push the repository to several origins at the same time.
git remote set-url --add --push origin git://original/repo.git
git remote set-url --add --push origin git://another/repo.git
  • John Kaniarz suggests to use a local remote repository instead of using a bundle.

--

--

Alberto de Murga

Software engineer at @bookingcom. I like to make things, and write about what I learn. I am interested in Linux, git, JavaScript and Go, in no particular order.