)]}'
{
  "commit": "ad7a403268735b98566cff4b082710bbb0d9f417",
  "tree": "c2d0c08361b8292fbde420b3ed5bbd312967a33a",
  "parents": [
    "5fa0f5238b0cd46cfe7f6fa76c3f526ea98148d9"
  ],
  "author": {
    "name": "Jeff King",
    "email": "peff@peff.net",
    "time": "Tue Nov 12 21:07:19 2019 -0500"
  },
  "committer": {
    "name": "Junio C Hamano",
    "email": "gitster@pobox.com",
    "time": "Wed Nov 13 16:13:03 2019 +0900"
  },
  "message": "send-pack: check remote ref status on pack-objects failure\n\nWhen we\u0027re pushing a pack and our local pack-objects fails, we enter an\nerror code path that does a few things:\n\n  1. Set the status of every ref to REF_STATUS_NONE\n\n  2. Call receive_unpack_status() to try to get an error report from\n     the other side\n\n  3. Return an error to the caller\n\nIf pack-objects failed because the connection to the server dropped,\nthere\u0027s not much more we can do than report the hangup. And indeed, step\n2 will try to read a packet from the other side, which will die() in the\npacket-reading code with \"the remote end hung up unexpectedly\".\n\nBut if the connection _didn\u0027t_ die, then the most common issue is that\nthe remote index-pack or unpack-objects complained about our pack (we\ncould also have a local pack-objects error, but this ends up being the\nsame; we\u0027d send an incomplete pack and the remote side would complain).\n\nIn that case we do report the error from the other side (because of step\n2), but we fail to say anything further about the refs. The issue is\ntwo-fold:\n\n  - in step 1, the \"NONE\" status is not \"we saw an error, so we have no\n    status\". It generally means \"this ref did not match our refspecs, so\n    we didn\u0027t try to push it\". So when we print out the push status\n    table, we won\u0027t mention any refs at all!\n\n    But even if we had a status enum for \"pack-objects error\", we\n    wouldn\u0027t want to blindly set it for every ref. For example, in a\n    non-atomic push we might have rejected some refs already on the\n    client side (e.g., REF_STATUS_REJECT_NODELETE) and we\u0027d want to\n    report that.\n\n  - in step 2, we read just the unpack status. But receive-pack will\n    also tell us about each ref (usually that it rejected them because\n    of the unpacker error).\n\nSo a much better strategy is to leave the ref status fields as they are\n(usually EXPECTING_REPORT) and then actually receive (and print) the\nfull per-ref status.\n\nThis case is actually covered in the test suite, as t5504.8, which\nwrites a pack that will be rejected by the remote unpack-objects. But\nit\u0027s racy. Because our pack is small, most of the time pack-objects\nmanages to write the whole thing before the remote rejects it, and so it\nreturns success and we print out the errors from the remote. But very\noccasionally (or when run under --stress) it goes slow enough to see a\nfailure in writing, and git-push reports nothing for the refs.\n\nWith this patch, the test should behave consistently.\n\nThere shouldn\u0027t be any downside to this approach. If we really did see\nthe connection drop, we\u0027d already die in receive_unpack_status(), and\nwe\u0027ll continue to do so. If the connection drops _after_ we get the\nunpack status but before we see any ref status, we\u0027ll still print the\nremote unpacker error, but will now say \"remote end hung up\" instead of\nreturning the error up the call-stack. But as discussed, we weren\u0027t\nshowing anything more useful than that with the current code. And\nanyway, that case is quite unlikely (the connection dropping at that\npoint would have to be unrelated to the pack-objects error, because of\nthe ordering of events).\n\nIn the future we might want to handle packet-read errors ourself instead\nof dying, which would print a full ref status table even for hangups.\nBut in the meantime, this patch should be a strict improvement.\n\nHelped-by: SZEDER Gábor \u003cszeder.dev@gmail.com\u003e\nSigned-off-by: Jeff King \u003cpeff@peff.net\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "6dc16c3211631402432207dcf99b1ef4e87f012b",
      "old_mode": 33188,
      "old_path": "send-pack.c",
      "new_id": "d87da377507437cdc6e03851d4af18054ab5cf0c",
      "new_mode": 33188,
      "new_path": "send-pack.c"
    }
  ]
}
