remote: separate the concept of push and fetch mirrors
authorJeff King <peff@peff.net>
Wed, 30 Mar 2011 19:53:19 +0000 (15:53 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 Mar 2011 20:47:53 +0000 (13:47 -0700)
commita9f5a3558dcf83440c60ae5a2e2b56c80d65bb0b
tree98937f314b51230a2ee144b8ecbd4779f9c2eee2
parent13fc2c1877a50dde5ea43e2f37420ebfb2f7dad1
remote: separate the concept of push and fetch mirrors

git-remote currently has one option, "--mirror", which sets
up mirror configuration which can be used for either
fetching or pushing. It looks like this:

  [remote "mirror"]
    url = wherever
    fetch = +refs/*:refs/*
    mirror = true

However, a remote like this can be dangerous and confusing.
Specifically:

  1. If you issue the wrong command, it can be devastating.
     You are not likely to "push" when you meant to "fetch",
     but "git remote update" will try to fetch it, even if
     you intended the remote only for pushing. In either
     case, the results can be quite destructive. An
     unintended push will overwrite or delete remote refs,
     and an unintended fetch can overwrite local branches.

  2. The tracking setup code can produce confusing results.
     The fetch refspec above means that "git checkout -b new
     master" will consider refs/heads/master to come from
     the remote "mirror", even if you only ever intend to
     push to the mirror. It will set up the "new" branch to
     track mirror's refs/heads/master.

  3. The push code tries to opportunistically update
     tracking branches. If you "git push mirror foo:bar",
     it will see that we are updating mirror's
     refs/heads/bar, which corresponds to our local
     refs/heads/bar, and will update our local branch.

To solve this, we split the concept into "push mirrors" and
"fetch mirrors". Push mirrors set only remote.*.mirror,
solving (2) and (3), and making an accidental fetch write
only into FETCH_HEAD. Fetch mirrors set only the fetch
refspec, meaning an accidental push will not force-overwrite
or delete refs on the remote end.

The new syntax is "--mirror=<fetch|push>". For
compatibility, we keep "--mirror" as-is, setting up both
types simultaneously.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-remote.txt
builtin/remote.c
t/t5505-remote.sh