When cloning a repo with --mirror, and adding more remotes later,
get_stale_heads for origin will mark all refs from other repos as stale.
Add a warning to the documentation, and warn the user when we detect
such things during git remote add.

Signed-off-by: Dennis Kaarsemaker <den...@kaarsemaker.net>
 Documentation/git-remote.txt |  6 +++++-
 builtin/remote.c             | 17 +++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 581bb4c..d7457df 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -71,7 +71,11 @@ 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.
+because a fetch would overwrite any local commits. If you want to add extra
+remotes to a repository created with `--mirror=fetch`, you will need to change
+the configuration of the mirrored remote to fetch only `refs/heads/*`,
+otherwise `git remote prune <remote>` will remove all branches for the extra
 When a push mirror is created with `--mirror=push`, then `git push`
 will always behave as if `--mirror` was passed.
diff --git a/builtin/remote.c b/builtin/remote.c
index 5e54d36..a4f9cb8 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -112,6 +112,21 @@ enum {
 #define MIRROR_PUSH 2
+static int check_overlapping_refspec(struct remote *remote, void *priv)
+       char *refspec = priv;
+       int i;
+       for (i = 0; i < remote->fetch_refspec_nr; i++) {
+               if(strcmp(refspec, remote->fetch[i].dst) &&
+                  (!fnmatch(refspec, remote->fetch[i].dst, 0) ||
+                   !fnmatch(remote->fetch[i].dst, refspec, 0))) {
+                       warning(_("Overlapping refspecs detected: '%s' and 
+                               refspec, remote->fetch[i].dst);
+               }
+       }
+       return 0;
 static int add_branch(const char *key, const char *branchname,
                const char *remotename, int mirror, struct strbuf *tmp)
@@ -123,6 +138,8 @@ static int add_branch(const char *key, const char 
                strbuf_addf(tmp, "refs/heads/%s:refs/remotes/%s/%s",
                                branchname, remotename, branchname);
+       for_each_remote(check_overlapping_refspec, strchr((const 
char*)tmp->buf, ':') + 1);
        return git_config_set_multivar(key, tmp->buf, "^$", 0);

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to