How to properly mirror a git repository
Tags: git, mirror
Published: 2019-06-21 17:38:22

---
title: How to properly mirror a git repository
published: true
description: 
canonical_url: http://blog.plataformatec.com.br/2013/05/how-to-properly-mirror-a-git-repository/
tags: git, mirror
---

When people talk about mirroring a git repository, usually we have a simple answer in mind:
<blockquote>Just git clone the repo and you're set!!</blockquote>
However, what we want with mirroring is to replicate the state of an origin repository (or upstream repository). By state, we mean all the branches (including <code>master</code>) and all the tags as well.

You'll need to do this when migrating your upstream repository to a new "home", like when switching services like GitHub.

As with most tools, there's a lot of ways to accomplish that, but I'll be focusing on two of them. The difference lays on whether you already have a working copy of that repository or not.
<h2>Mirroring a git repository without a local copy</h2>
If you haven't cloned the repository before, you can mirror it to a new home by
<pre lang="bash">$ git clone --mirror git@example.com/upstream-repository.git
$ cd upstream-repository.git
$ git push --mirror git@example.com/new-location.git
</pre>
This will get all the branches and tags that are available in the upstream repository and will replicate those into the new location.
<h3>Warning</h3>
Don't use <code>git push --mirror</code> in repositories that weren't cloned by <code>--mirror</code> as well. It'll overwrite the remote repository with your local references (and your local branches). This is not what we want. Read the next section to discover what to do in these cases.

Also <code>git clone --mirror</code> is preferred over <code>git clone --bare</code> because the former also clones git notes and some other attributes.
<h2>Mirroring a git repository if you already have a local working copy</h2>
By working copy, we mean a "normal" repository, in which you have the files that are being tracked into git and where you perform commands like <code>git add</code> and so on.

In this case, you may have a lot of local branches and tags that you don't want to copy to the new location. But you do have references to remote branches. You can view them with <code>git branches -r</code>. If you pay attention to that list, though, you may notice that you have a lot of branches that were already deleted in the upstream repository. Why?
<h3>Cleaning old references to remote branches</h3>
By default, when you do a <code>git fetch</code> or <code>git pull</code>, git will not delete the references to branches that were deleted in the upstream repository (you may view them in your <code>.git/refs/remotes</code> dir). We need to clean those old references before mirroring them to a new location.

To do so, run
<pre lang="bash">$ git fetch --prune
</pre>
This will update your references to the origin repository and also clean the stale branches reported by <code>git branch -r</code>.
<h3>Finally, mirroring the repository to a new location</h3>
Now we're ready to send those updated references back to the <code>origin</code> repository:
<pre lang="bash">$ git push --prune git@example.com:/new-location.git +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/*
</pre>
Ok, what just happened here?!

We want those references inside <code>.git/refs/remotes/origin</code> to be the LOCAL references in the new location. The local references there will be stored in the <code>refs/heads</code> dir. The same thing happens to tags.

The <code>+</code> sign indicates that we want to <strong>overwrite</strong> any reference there may already exist.

<code>--prune</code> means we want to delete any reference that may exist there if we don't have such reference in our <code>refs/remotes/origin/*</code> (and tags) references.
<h2>Conclusion</h2>
Git is certainly not an easy tool to learn. Although when you do, it turns into a very powerful and flexible tool.

If you want to learn more about it, please see the <a href="http://git-scm.com/book">excellent book written by Scott Chacon and available for free</a>.

What about you? Have any tips on git you want to share?