Subject: Re: Alternates and push

From: "Shawn O. Pearce" <[email-masked]>
Date: Mon, 8 Sep 2008 07:56:54 -0700

Daniel Barkalow <[email-masked]> wrote:
> On Sun, 7 Sep 2008, Junio C Hamano wrote:
> > 
> > Oops, I forgot to Cc Daniel.  Shawn also CC'ed because he will have the
> > same issue with the smart CGI based http-push he is building.

Not just the smart CGI based http-push thingy.  JGit is impacted
anytime we start talking about network transport.  ;-)
 
> > The sending end, however, has a safety to silently ignore malformed refs
> > it learns from the receiving end over the wire.  So the current sender
> > won't work with asterisk in there '*', nor full-pathname, because
> > typically it contains "/.git/" in the string, which would make it an
> > invalid refname to be ignored.
> > 
> > Also, the sending end remembers the objects we have per refname, so
> > sending two records with the same refname pointing at two different
> > objects will not work well either (the current code is loose and does not
> > check duplicates, but that is not a feature by design but is an accident).

Cute. Learn something new every day.

JGit doesn't do the check_ref_format(), but it does do duplicate
detection.  If the remote side sends us duplicate advertisements
JGit freaks out and aborts the transfer.  This is largely just a
function of JGit hashing the advertised refs for O(1) access later
on during processing.  We avoid a lot of ugly O(N^2) loops that way.

> I think we should use a really invalid ref name, like "^" or something 
> like that, so that it's clearly not an actually available ref, but just a 
> way for the remote to mention that it has the object, and the remote 
> doesn't have to try to make it unique.

I agree.  How about just calling all of these ".have"?

According to check_ref_format() it fails, so older clients will
just ignore it.  Attempts by bad clients to push or delete ".have"
should also fail automatically in receive-pack's own test at the
start of the update() function.

Using a constant name for all instances hides what the underlying
alternates really have, in case their branches aren't public, but
their databases are.  It also makes it easier for hashing clients
like JGit to collect these object IDs into a table of known objects,
but ignoring the name component.

Sadly no matter what we do here JGit's duplicate detection is in
direct opposite behavior with git.git's ignoring check_ref_format()
failures.  So we'll have to patch JGit no matter what we do.

-- 
Shawn.