Back up your repositories as mirror repositories

Though Git is distributed and every clone essentially is a backup, there are some tricks that can be useful when backing up Git repositories. A normal Git repository has a working copy of the files it tracks and the full history of the repository in the .git folder of that repository. The repositories on the server, the one you push to and pull from, will usually be bare repositories. A bare repository is a repository without a working copy. Roughly, it is just the .git folder of a normal repository. A mirror repository is almost the same as a bare repository, except it fetches all the references under refs/*, where a bare only fetches the references that fall under refs/heads/*. We'll now take a closer look at a normal, a bare, and a mirror clone of the Jgit repository.

Getting ready

We'll start by creating three clones of the Jgit repository, a normal, a bare, and a mirror clone. When we create the first clone, we can use that as a reference repository for the other clones. In this way, we can share the objects in the database, and we don't have to transfer the same data three times:

$ git clone https://git.eclipse.org/r/jgit/jgit
$ git clone --reference jgit --bare https://git.eclipse.org/r/jgit/jgit
$ git clone --mirror --reference jgit https://git.eclipse.org/r/jgit/jgit jgit.mirror

How to do it...

  1. One of the differences between a normal repository and a bare/mirror one is that there are no remote branches in a bare repository; all the branches are created locally. We can see this in the three repositories by listing the branches with the git branch as follows:
    $ cd jgit
    $ git branch
    * master
    
    $ cd ../jgit.git # or cd ../jgit.mirror
    $ git branch
    * master
      stable-0.10
      stable-0.11
      stable-0.12
    ...
    
  2. To see the difference between the bare and mirror repositories, we need to list the different refspecs fetch and the different refs namespaces. List the fetch refspec for origin in the mirror repository (jgit.mirror):
    $ git config remote.origin.fetch
    +refs/*:refs/*
    
  3. List the different refs namespaces in the mirror repository:
    $ git show-ref | cut -f2 -d " " | cut -f1,2 -d / | sort -u
    refs/cache-automerge
    refs/changes
    refs/heads
    refs/meta
    refs/notes
    refs/tags
    
  4. There is no explicit refspec fetch in the configuration for origin in the bare repository (jgit.git). When no configuration entry is found, Git uses the default refspec fetch, as it does in a normal repository. We can check the remote URL of origin using the following command:
    $ git config remote.origin.url
    https://git.eclipse.org/r/jgit/jgit
    
  5. List the different refs namespaces in the bare repository using the following command:
    $ git show-ref | cut -f2 -d " " | cut -f1,2 -d / | sort -u
    refs/heads
    refs/tags
    
  6. Finally, we can list the refspec fetch and refs namespaces for the normal repository (jgit):
    $ git config remote.origin.fetch
    +refs/heads/*:refs/remotes/origin/*
    $ git show-ref | cut -f2 -d " " | cut -f1,2 -d / | sort -u
    refs/heads
    refs/remotes
    refs/tags
    
  7. The mirror repository has four ref namespaces not found in the normal or the bare repositories, refs- cache-automerge, changes, meta, and notes. The normal repository is the only one that has the refs/remote namespace.

How it works…

The normal and bare repositories are pretty similar, only the mirror sticks out. This is due to the refspec fetch on the mirror repository, +refs/*:refs/*, which will fetch all refs from the remote and not just refs/heads/* and refs/tags/* as a normal repository (and bare) does. The many different ref namespaces on the Jgit repository is because the Jgit repository is managed by Gerrit Code Review that uses different namespaces for some repository specific content, such as changes branches for all commits submitted for code review, metadata on code review score, and so on.

The mirror repositories are good to know when you would like a quick way to back up a Git repository, and make sure you have everything included without needing more access than the Git access to the machine that hosts the Git repository.

There's more…

The repositories on GitHub store extra information in some refs namespaces. If a repository has had a pull request made, the pull request will be recorded in the refs/pull/* namespace. Let's look at it in the following code:

$ git clone --mirror [email protected]:jenkinsci/extreme-feedback-plugin.git
$ cd extreme-feedback-plugin.git
$ git show-ref | cut -f2 -d " " | cut -f1,2 -d / | sort -u
refs/heads
refs/meta
refs/pull
refs/tags
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset