fetch: add new fetch.default configuration
authorFelipe Contreras <felipe.contreras@gmail.com>
Sat, 18 May 2013 01:38:54 +0000 (20:38 -0500)
committerFelipe Contreras <felipe.contreras@gmail.com>
Wed, 18 May 2016 22:55:21 +0000 (17:55 -0500)
commit35ba6954b49fe4c61b0675631f959ca0c8e5038a
tree720c0968ebb55fa0e702f33db34cf57bb76d83be
parentce8dcf4541c1cc84fd05163a3f4a803347bb1d63
fetch: add new fetch.default configuration

When the user has an upstream branch configured to track a remote
tracking branch:

  % git checkout --set-upstream-to github/master

Doing a 'git fetch' without any arguments would try to fetch 'github',
because it's configured as current branch's remote
(branch.<current>.remote).

However, if we do something slightly different:

  % git checkout --set-upstream-to master

Doing a 'git fetch' without any arguments would try to fetch the remote
'.', for the same reason.

But, unlike the in the first instance, the second command would not
update any remote tracking branch, in fact, it would not update any
branch at all. The only effect is that it would update FETCH_HEAD.

FETCH_HEAD is a special symbol that is used to store the result of a
fetch. It can be used by other commands of git, specially 'git merge'.

It is however, barely mentioned in the documentation, and can be
considered a plumbing concept at best, that few Git users would benefit
from using, and indeed, quite likely very few use it, or are even aware
of it.

So when the user is presented with a message like this:

  % git fetch
  From .
   * branch            master     -> FETCH_HEAD

The vast majority of them would have absolutely no idea what's going on.
Many of them would probably just shrug, and manually specify the remote
the want to fetch from, which is 'origin' in many cases, *if* they
manage to notice the '.' at all.

If the user has say, twenty branches, ten with a local upstream
(branch.<name>.remote = '.'), and ten without an upstream. The user
might get used to typing 'git fetch' and expect Git to fetch from
'origin' which would happen 50% of the time, but the other 50%, the user
would be forced to specify the remote.

This inconsistency would be simply one more to join the list of
incomprehensible quirks the user has to put up when using Git, so quite
likely he simply gets used to it, only to complain later in forums or
social media, outside of the dwelling distance of the typical Git
developer.

But we can do better.

We can add a new 'fetch.default' configuration variable (one more to
join the many necessary to force Git to behave in sane manner), so the
user can specify what she wants to be performed when the remote is not
specified in the 'git fetch' command.

This configuration would probably be welcomed by 99% of the user
population, who have no clue what FETCH_HEAD is, and do set local
upstream branches, only to find out weird inconsistent behavior
depending on which branch they happen to be sitting at.

We add documentation and testing as expected, and also introduce other
changes necessary to make the configuration enter into effect when it's
needed.

The default (FETCH_DEFAULT_UNSPECIFIED), allows the current behavior to
be unmodified, so remote_get(NULL) is called, and the current rules to
determine the default branch remain.

The new option "simple" allows Git to always fetch from "origin", which
is what most users would expect, and it's 100% consistent.

Alternatively, the user can manually specify the current behavior with
"current" (alluding to the current branch), so that the behavior changes
depending on which branch the user happens to be sitting at. This would
allow the user to retain this behavior, if she so wishes,
in case Git developers regain their senses and set a default that most
users would appreciate ("simple").

If the user wants, for whatever strange reason swimming in his/her head,
he can still fetch from a local ('.') remote (even stating that as an
English sentence doesn't make any sense).

  % git fetch .
  From .
   * branch            master     -> FETCH_HEAD

And to any number of weird hacks with FETCH_HEAD.

The average user lucky enough to find the 'fetch.default' configuration,
however, would never have to enter the word of "local remote"
strangeness, and would remain comfortably in the place where locals are
locals, and remotes are remotes, and 'git fetch' is always consistent,
and always does something useful.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Documentation/config.txt
Documentation/git-fetch.txt
builtin/fetch.c
cache.h
config.c
environment.c
t/t5513-fetch-track.sh