Subject: Re: when is a remote a branch?

From: Jakub Narebski <[email-masked]>
Date: Sun, 12 Nov 2006 18:31:18 +0100

Petr "Pasky" Baudis wrote:
> On Sun, Nov 12, 2006 at 05:11:41PM CET, Jakub Narebski wrote:
>> Read Documentation/repository-layout.txt (ot it's HTML version, either
>> locally ot at www.kernel.org).
>> 
>>  branches::
>>          A slightly deprecated way to store shorthands to be used
>>          to specify URL to `git fetch`, `git pull` and `git push`
>>          commands is to store a file in `branches/'name'` and
>>          give 'name' to these commands in place of 'repository'
>>          argument.
>> 
>> You can store only one branch to fetch per shorthand. I'm not sure about
>> where it is stored which branch to download, and how to name this branch 
>> locally.
> 
> I think the above is quite confusing description. This really is not
> about any "shorthands" at all, but just about branches (how the name
> implies, after all).

Well, it is a shorthand in a way that you can just use "git fetch"
or "cg fetch" to fetch correct branch without need for URL.

But I agree that the description (although of deprecated feature)
could be better.

> Git and Cogito share the same models of branches. These branches are
> 'heads' with commit pointers stored in refs/heads/, etc. 

Not exactly. "Live" branches (i.e. branches you can commit to) are head
refs stored in refs/heads/. But in repository cloned with git-clone
--use-separate-remotes tracking heads (tracking branches) would be at
refs/remotes/<remotename>/. You can fetch to such a ref, but you can't
checkout it, nor commit to it.

> The branches/ 
> directory says that some branches do not correspond to local development
> (and should never be used for that) but instead they correspond to a
Does that _should_ is enforced in Cogito? Is it enforced in Git?

> particular branch in some remote repository. Such branches are called
> "REMOTE BRANCHES".

I'd rather call them "tracking branches", at least in git. So if there
is branch 'localbranch' in refs/heads/ (?), and there is corresponding
branches file branches/localbranch, which contains a single URL
  git://host.domain/path/to/repository#remotebranch
it is AFAICU equivalent to having some remotes file, named e.g. 'repo',
with the following contents:
  URL: git://host.domain/path/to/repository
  Pull: remotebranch:localbranch
  Push: remotebranch:localbranch
or equivalent entry in git config.

> So it's "if branch X has corresponding .git/branch/X file, it's not a
> local branch but instead a REMOTE BRANCH corresponding to the URL stored
> in that file". That simple. The URL is address of the repository plus
> optionally a '#branchname' if the branch name in the remote repository
> should not default to remote HEAD or master.

The whole concept of branches file (and marking some branches as "remote"
branches) is IMHO from the times where there were most common to have one
live branch per repository, and we fetched and pushed single branches.
This simple picture changed with more widespread use of multiple heads,
and with the introduction of tags (I think).
 
> In addition, Git (not Cogito at this point) supports a completely
> different and unrelated abstraction called REMOTES. They don't have
> anything to do with branches. Instead, a REMOTE represents a repository
> URL and a set of local/remote branch pairs to handle on pulls and
> pushes; it has no other obvious mapping to branches and branches can be
> even shared between various REMOTES etc. (this is changing lately with
> the refs/remotes/ hierarchy, but I think that's still not in wide use).

Remote is usually a repository. It is single URL (although it would be
nice to be able to specify alternate URLs for the same repository, or
for different mirrors of the same repository) representing repository
to fetch from/to push to, together with branches we want to fetch (which
parts of DAG we want to fetch), and local names of those branches,
following fetched contents.

By the way, with introduction of branches and remotes in config file,
you can say:
 [branch "localbranch"]
	remote = someremote

 [remote "someremote"]
	fetch = remotebranch:localbranch
	push  = remotebranch:localbranch

and that would be equivalent to example branches file from the beginning
of this email.
-- 
Jakub Narebski