git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Bad objects error since upgrading GitHub servers to 1.6.1

From
Shawn O. Pearce <spearce@spearce.org>
Date
Jan 28, 2009, 16:09 UTC
Message-ID
<20090128160900.GJ1321@spearce.org>
In-Reply-To
<7vd4e7x5ov.fsf@gitster.siamese.dyndns.org>
Junio C Hamano <gitster@pobox.com> wrote:
> 
> I've been toying with an idea for an alternative solution, and need
> somebody competent to bounce it around with.
Heh, then we need to wait for Nico... :-)
 
Show 11 quoted lines
> pack-objects ends up doing eventually
> 
>     rev-list --objects $send1 $send2 $send3 ... --not $have1 $have2 ...
> 
> which lists commits and associated objects reachable from $sendN,
> excluding the ones that are reachable from $haveN.
> 
> The tentative solution Björn Steinbrink and I came up with excludes
> missing commit from $haveN to avoid rev-list machinery to barf, but it
> violates the ref-object contract as I explained to Björn in my other
> message.

Oh, OK, I now _finally_ understand what you were trying to say by the reachability thing. I kept scratching my head trying to understand you, and was going to say something stupid on list; but waited because I just didn't get what the big deal was...

Its the crash in rev-list that you were worried about.
> Checking if each commit is reachable from any of the refs is quite
> expensive, and it would especially be so if it is done once per ".have"
> and real ref we receive from the other end.
Yup.
 
Show 6 quoted lines
> An alternative is to realize that rev-list traversal already does
> something quite similar to what is needed to prove if these ".have"s are
> reachable from refs when listing the reachable objects.  This computation
> is what it needs to do anyway, so if we teach rev-list to ignore missing
> or broken chain while traversing negative refs, we do not have to incur
> any overhead over existing code.
EXACTLY.
JGit does this.

The functional equivilant of rev-list in JGit will by default throw an exception if any object is missing when we try to walk it. That includes things we've painted UNINTERESTING, as it is a sure sign of repository corruption.

However; our equivilant of pack-objects can toggle what you are calling "ignore-missing-negative" when it starts enumeration. Any UNINTERESTING object which is missing or failed to parse is simply tossed aside. Yes, the pack may be larger than necessary like in Peff's example of:

       Q-R
      /
  D--E
      \
       A-C

If the other side has C reachable, we are pushing R, and we have C but are missing A, we'll "over push" D-E, but its still a clean and valid push. Its no worse than we were before the ".have" came about, or if C hadn't been downloaded locally at all. (Of course your tell-me-more extension would help fix this over-push, but lets not get off topic.)

IMHO, this corruption of A is harmless if C isn't reachable.

It isn't really local corruption unless C was reachable by a ref. But we don't tend to see much corruption like that, and if it did exist, it would show up during *other* operations that access a larger set of local refs, such as "git gc".

> I have a mild suspicion that it may even be the right thing to ignore them
> unconditionally, and it might even match the intention of Linus's original
> code.  That would make many hunks in this patch much simpler.

I don't think its right to ignore broken UNINTERESTING chains all of the time. Today we would see fatal errors if I asked for

  git log R ^C

and A was missing, but R and C are both local refs. I still want to see that fatal error. Its a local corruption that should be raised quickly to the user. In fact by A missing we'd compute the wrong result and produce D-E too, which is wrong.

IMHO, the *only* time this missing uninteresting A is safe is during send-pack, upload-pack, or bundle creation, where you are bringing the other side up to R by transferring any amount of data necessary to reach that goal. Which is why JGit enables this. (Though at the API level we do let the caller flag if they want the error to be fatal instead, but AFAIK nobody sets it for "fatal".)

FWIW, Linus' most recent message on this thread about hoisting the
UNINTERESTING test up sooner makes sense too.
 
Show 6 quoted lines
> The evidences behind this suspicion are found in a handful of places in
> revision.c.  mark_blob_uninteresting() does not complain if the caller
> fails to find the blob.  mark_tree_uninteresting() does not, either.
> mark_parents_uninteresting() does not, either, and it even has a comment
> that strongly suggests the original intention was not to care about
> missing UNINTERESTING objects.
That feels wrong to me... given the "git log R ^C" example I give above.
 
-- 
Shawn.
Previous: Jeff KingNext: Nicolas Pitre
Message 39 of 43 in “Bad objects error since upgrading GitHub servers to 1.6.1”
  1. PJ HyettJan 27, 2009
  2. PJ HyettJan 27, 2009
  3. Johannes SchindelinJan 27, 2009
  4. Shawn O. PearceJan 27, 2009
  5. Junio C HamanoJan 27, 2009
  6. PJ HyettJan 28, 2009
  7. PJ HyettJan 28, 2009
  8. Junio C HamanoJan 28, 2009
  9. Junio C HamanoJan 28, 2009
  10. send-pack: Filter unknown commits from alternates of the remoteBjörn Steinbrink, Jan 28, 2009
  11. Junio C HamanoJan 28, 2009
  12. Junio C HamanoJan 28, 2009
  13. Björn SteinbrinkJan 28, 2009
  14. Junio C HamanoJan 28, 2009
  15. Junio C HamanoJan 28, 2009
  16. Junio C HamanoJan 28, 2009
  17. PJ HyettJan 28, 2009
  18. Shawn O. PearceJan 28, 2009
  19. Junio C HamanoJan 28, 2009
  20. Shawn O. PearceJan 28, 2009
  21. Stephen BannaschJan 28, 2009
  22. Shawn O. PearceJan 28, 2009
  23. Junio C HamanoJan 28, 2009
  24. Junio C HamanoJan 28, 2009
  25. Shawn O. PearceJan 28, 2009
  26. Junio C HamanoJan 28, 2009
  27. Junio C HamanoJan 28, 2009
  28. 1/2 send-pack: do not send unknown object name from ".have" to pack-objectsJunio C Hamano, Jan 28, 2009
  29. Linus TorvaldsJan 28, 2009
  30. Junio C HamanoJan 28, 2009
  31. Jeff KingJan 28, 2009
  32. Junio C HamanoJan 28, 2009
  33. Jeff KingJan 28, 2009
  34. Shawn O. PearceJan 28, 2009
  35. Jeff KingJan 28, 2009
  36. Junio C HamanoJan 28, 2009
  37. Junio C HamanoJan 28, 2009
  38. Jeff KingJan 28, 2009
  39. Shawn O. PearceJan 28, 2009
  40. Nicolas PitreJan 28, 2009
  41. Jeff KingJan 28, 2009
  42. Linus TorvaldsJan 28, 2009
  43. Björn SteinbrinkJan 28, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.