72 lines
3.8 KiB
Markdown
72 lines
3.8 KiB
Markdown
---
|
||
title: How to properly mirror a git repository « Plataformatec Blog
|
||
tags:
|
||
- IT
|
||
- IT/Development/Git
|
||
source: http://blog.plataformatec.com.br/2013/05/how-to-properly-mirror-a-git-repository/
|
||
---
|
||
|
||
# [How to properly mirror a git repository « Plataformatec Blog](http://blog.plataformatec.com.br/2013/05/how-to-properly-mirror-a-git-repository/)
|
||
|
||
When people talk about mirroring a git repository, usually we have a simple answer in mind:
|
||
|
||
> Just git clone the repo and you’re set!!
|
||
|
||
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 `master`) 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.
|
||
|
||
## Mirroring a git repository without a local copy
|
||
|
||
If you haven’t cloned the repository before, you can mirror it to a new home by
|
||
|
||
$ git clone --mirror git@example.com/upstream-repository.git
|
||
$ cd upstream-repository.git
|
||
$ git push --mirror git@example.com/new-location.git
|
||
|
||
This will get all the branches and tags that are available in the upstream repository and will replicate those into the new location.
|
||
|
||
### Warning
|
||
|
||
Don’t use `git push --mirror` in repositories that weren’t cloned by `--mirror` 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 `git clone --mirror` is prefered over `git clone --bare` because the former also clones git notes and some other attributes.
|
||
|
||
## Mirroring a git repository if you already have a local working copy
|
||
|
||
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 `git add` 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 `git branches -r`. If you pay attention to that list, tough, you may notice that you have a lot of branches that were already deleted in the upstream repository. Why?
|
||
|
||
### Cleaning old references to remote branches
|
||
|
||
By default, when you do a `git fetch` or `git pull`, git will not delete the references to branches that were deleted in the upstream repository (you may view them in your `.git/refs/remotes` dir). We need to clean those old references before mirroring them to a new location.
|
||
|
||
To do so, run
|
||
|
||
$ git fetch --prune
|
||
|
||
This will update your references to the origin repository and also clean the stale branches reported by `git branch -r`.
|
||
|
||
### Finally, mirroring the repository to a new location
|
||
|
||
Now we’re ready to send those updated references back to the `origin` repository:
|
||
|
||
$ git push --prune git@example.com:/new-location.git +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/*
|
||
|
||
Ok, what just happened here?!
|
||
|
||
We want those references inside the `.git/refs/remotes/origin` to be the LOCAL references in the new location. The local references there will be stored in the `refs/heads` dir. Same thing happens to tags.
|
||
|
||
The `+` sign indicates that we want to **overwrite** any reference there may already exist.
|
||
|
||
`--prune` means we want to delete any reference that may exist there if we don’t have such reference in our `refs/remotes/origin/*` (and tags) references.
|
||
|
||
## Conclusion
|
||
|
||
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 [excelent book written by Scott Chacon and available for free](http://git-scm.com/book).
|