{"thread":{"id":"3194","subject":"(unknown)","startedAt":"2006-01-30T18:50:26Z","lastAt":"2006-01-30T18:50:26Z","messageCount":1,"participants":["Mark Wooding"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"15269","messageId":"17374.24562.614471.779986@metalzone.distorted.org.uk","threadId":"3194","inReplyTo":null,"subject":"(unknown)","fromName":"Mark Wooding","fromEmail":"mdw@distorted.org.uk","sentAt":"2006-01-30T18:50:26Z","receivedAt":"2006-01-30T18:50:26Z","isPatch":false,"sender":{"key":"mdw@distorted.org.uk","avatar":null},"body":"git-http-fetch seems buggy.  I /think/ it's getting confused by a\ncombination of a large top-level tree (lots of blobs directly attached)\nattached to the top commit, together with most of the things being\npacked.\n\nTo illustrate the bug, create a repository with the following shell\nscript.  (It will create a working tree called `funt' with a little GIT\nhistory inside.)\n\n----\n#! /bin/sh\n\nset -e\nmkdir funt\ncd funt\ngit-init-db \nyes | nl | head -200 | while read n hunoz; do echo file $n >foo.$n; done\ngit-add *\necho Boo. | git-commit -F - -a\ngit-repack\ngit-prune-packed \necho Censored >foo.197\necho Ouch. | git-commit -F - -a\ngit-update-server-info\n----\n\nThen put the repository somewhere your web server will let you get to\nit, and try to clone it, say using\n\n  git-clone http://boyle.nsict.org/~mdw/funt.git\n\n(Yes, that repository exists and is live; the server is fairly\nwell-connected.)  You ought to be greeted with text like this:\n\n  error: Unable to find b4f495485ca9ae825ec8c504cdcf24652342f43c under\n  http://boyle.nsict.org/~mdw/funt/.git/\n\n  Cannot obtain needed commit b4f495485ca9ae825ec8c504cdcf24652342f43c\n  while processing commit 351c72525b9ee5b2321c65598ce82a4e79015012.\n\nIf you're very lucky, git-http-fetch will segfault.\n\nWhat's going on here?\n\nThink about the repository layout for a bit.  There's a `big' pack file,\nand a little commit.  The commit has an unpacked tree attached, but\nalmost all of its leaves are in the pack.  The commit's parent is\npacked.\n\nSo git-http-fetch starts by filling its queue with prefetches for blob\nobjects which are packed (and so it gets 404s for them).  This is fine.\nHowever! when it comes to collect the parent commit, it realises it\nneeds to fetch the pack list.  Unfortunately, something goes wrong in\nrun_active_slot.  As far as I can make out, the slot used to collect\n.../info/packs is being /reused/ by fill_active_slots (called by\nstep_active_slots) before fetch_indices is returned to.  Since the\nprefetch which got the new slot is for an object which got packed, it\nfails with a 404, which is written back to the slot.  The result is that\nfetch_indices thinks that the pack list doesn't exist (even though it\nactually does, and libcurl fetched it just fine, thanks).  This is\nmarked as a permanent error, and that parent commit can't be found.\n\nThe segfault is I think due to this reuse too, but it only happens\nsometimes and I'm not entirely clear on why.\n\nI'm afraid I don't have a patch.  I've spent a little while trying to\nfix this bug myself, but my changes just seem to cause wedging, or fd\nleaks, or segfaults, or all three, so it's obvious I don't understand\nthe code well enough.\n\n-- [mdw]\n"}]}