Subject: Re: [PATCH] Teach remote machinery about remotes.default config variable

From: Mark Levedahl <[email-masked]>
Date: Mon, 14 Jan 2008 23:55:47 -0500

Junio C Hamano wrote:
> Mark Levedahl <[email-masked]> writes:
>
>   
>> ... if what
>> we need to fetch from is in fact not origin (even though the master
>> project knows what server to access), submodule update in fact doesn't
>> even work ...
>>     
>
> This is an interesting point.
>
> Perhaps git-submodule.sh::modules_update should use $url it
> obtains from the configuration in the upper level when running
> git-fetch in the submodule.
>   
yes, I like this change, it works very nicely. but that last patch is 
only a partial solution...
> If you view the problem this way, your earlier "git fetch while
> the HEAD is detached always uses 'origin'" may turn out to be a
> non-issue.
>
> Which again brings us back to Johannes's earlier point.  If the
> issue is about submodule, maybe what needs to be fixes is in
> git-submodule, and not the defaulting to 'origin' git-fetch and
> friends do.
>   
Nope, git submodule *still* requires origin (e.g., execute git submodule 
init or update on a detached head). We are dancing around the issue, not 
fixing the root cause. This is perhaps illuminated by splitting projects 
into two camps:

Camp1 - there is no need to distinguish the upstream servers (or there 
is only one), calling it/all origin is fine.
Camp2 - there is a need to distinguish servers, they are not identical, 
uniform naming across project is required (but folks might still like to 
be able to have a default, and probably want to change that default on 
occasion), .

So far, git is written as if the whole world is in Camp1, and the 
problems appear for Camp2. The underlying issue is that git has 
convolved the referencing, naming, and designation of a default remote 
into *one* thing when it is really three things. For git, the default 
remote is named origin, which is also how it is designated as the 
default, and is also how you reference the default in commands. 
Non-default remotes have an arbitrary nickname, are not default as they 
are not called origin, and are referenced by using their nicknames.

To serve Camp2 (and not impact Camp1), origin should be a handle that 
dereferences to the name of the default remote, and designation of the 
default remote should be by a separate config item rather than a special 
name for the remote. Assume core.origin names the default remote:

For Campl, we have
    core.origin=origin
with the default remote having nickname origin.

For Camp2, we could have
    core.origin=<whatever>
with the default remote having nickname <whatever>

At the command line, "git fetch" dereferences to $(git config 
core.origin), which is origin for Camp1, but <whatever> for Camp2. So, 
Camp1 users don't notice anything is different, and Camp2 users don't 
have a number of different servers all referred to as "origin".

The key is that in Camp2, a given remote now can have  the *same* 
nickname for all members of the project, regardless of which remote they 
have made their default. "git fetch" and "git fetch origin" still work, 
they just dereference core.origin (perhaps verbosely to warn that the 
remote being updated is *not* actually named origin), then update the 
remotes/$(git config core.origin)/* branches.

Obviously, Camp1 with core.origin=origin is the default, and everything 
in user land works exactly as it does today. Camp2 with 
core.origin~=default is only mentioned in the graduate level git course 
and shielded with "Caution, Sharp Knives!" signs. Fine, I need the knives.

Mark