5

I'm trying to get my head around git mirroring. Given a working copy, how do I determine whether it is a mirror (or is mirroring) another repository?

Cheers.

user5877732
  • 371
  • 3
  • 19

3 Answers3

7

try:

git config --list | grep remote

remote.origin.url=<git remote url>
remote.origin.fetch=+refs/*:refs/*
remote.origin.mirror=true

I don't understand the subtleties listed above, but this worked for me.

git_student
  • 71
  • 1
  • 1
3

There are in fact two kinds of mirrors, as noted in the git remote documentation:

When a fetch mirror is created with --mirror=fetch, the refs will not be stored in the refs/remotes/ namespace, but rather everything in refs/ on the remote will be directly mirrored into refs/ in the local repository. This option only makes sense in bare repositories, because a fetch would overwrite any local commits.

When a push mirror is created with --mirror=push, then git push will always behave as if --mirror was passed.

A fetch mirror (which is what you get if you use git clone --mirror) is detectable by its two key settings, core.bare and its fetch line:

$ git remote add --mirror=fetch rfetch ssh://upstream.host/path/to/repo.git
$ git config --get-all remote.rfetch.fetch
+refs/*:refs/*
$ 

Detecting a push mirror is simpler:

$ git remote add --mirror=push rpush ssh://upstream.host/path/to/repo.git
$ git config --get --bool remote.rpush.mirror
true

If a specific remote.remote.fetch is set to +refs/*:refs/* but the repository does not have core.bare set to true (which you can discover using git config --get --bool core.bare or git rev-parse --is-bare-repository; both do the same thing), you have a confused repository (such as the one I made to illustrate the above :-) ). If there is more than one remote.remote section, and any of them have fetch=+refs/*:refs/*, you have a weird-at-best repository (in theory a fetch mirror with multiple remotes could work as a sort of union repository, but all remotes would need to use different references, e.g., only one could have a master branch). You can find all the remotes using git config --get-regexp or git config --list and extracting items that match regular expression ^remote\.. Here awk is actually perhaps the most suitable processor if writing scripts:

$ git config --list | awk -F. '$1 == "remote" { if (!r[$2]++) print $2 }'
rfetch
rpush
$ 

Having obtained a list of remotes, you can then probe each one for its mirror-ness as either fetch or push mirror. If any is a fetch mirror, core.bare should be true.

torek
  • 448,244
  • 59
  • 642
  • 775
-1

Git uses a peer to peer architecture. A git repository that is a mirror will appear and act just like it's source. To tell them apart, you could look in the '.git/config' file, because config files are not pushed, but it won't explicitly indicate it is a mirror.

Gregg
  • 2,444
  • 1
  • 12
  • 21