)]}'
{
  "commit": "4c324c00501c2da41987498f8c966b022306b244",
  "tree": "b9879484a7aa71bf54fcbc41377525ef4b855919",
  "parents": [
    "fe61935007b6803ce116e233316e4ff51de02be6"
  ],
  "author": {
    "name": "Johannes Sixt",
    "email": "johannes.sixt@telecom.at",
    "time": "Sun Nov 04 20:46:48 2007 +0100"
  },
  "committer": {
    "name": "Junio C Hamano",
    "email": "gitster@pobox.com",
    "time": "Mon Nov 05 22:47:28 2007 -0800"
  },
  "message": "upload-pack: Use finish_{command,async}() instead of waitpid().\n\nupload-pack spawns two processes, rev-list and pack-objects, and carefully\nmonitors their status so that it can report failure to the remote end.\nThis change removes the complicated procedures on the grounds of the\nfollowing observations:\n\n- If everything is OK, rev-list closes its output pipe end, upon which\n  pack-objects (which reads from the pipe) sees EOF and terminates itself,\n  closing its output (and error) pipes. upload-pack reads from both until\n  it sees EOF in both. It collects the exit codes of the child processes\n  (which indicate success) and terminates successfully.\n\n- If rev-list sees an error, it closes its output and terminates with\n  failure. pack-objects sees EOF in its input and terminates successfully.\n  Again upload-pack reads its inputs until EOF. When it now collects\n  the exit codes of its child processes, it notices the failure of rev-list\n  and signals failure to the remote end.\n\n- If pack-objects sees an error, it terminates with failure. Since this\n  breaks the pipe to rev-list, rev-list is killed with SIGPIPE.\n  upload-pack reads its input until EOF, then collects the exit codes of\n  the child processes, notices their failures, and signals failure to the\n  remote end.\n\n- If upload-pack itself dies unexpectedly, pack-objects is killed with\n  SIGPIPE, and subsequently also rev-list.\n\nThe upshot of this is that precise monitoring of child processes is not\nrequired because both terminate if either one of them dies unexpectedly.\nThis allows us to use finish_command() and finish_async() instead of\nan explicit waitpid(2) call.\n\nThe change is smaller than it looks because most of it only reduces the\nindentation of a large part of the inner loop.\n\nSigned-off-by: Johannes Sixt \u003cjohannes.sixt@telecom.at\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n",
  "tree_diff": [
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "cc8949e3eff7b8d7802c5cdea5eddc7c2f1f9a53",
      "new_mode": 33261,
      "new_path": "t/t5530-upload-pack-error.sh"
    },
    {
      "type": "modify",
      "old_id": "67994680f2f48e573f78c592c853422e6d8995cf",
      "old_mode": 33188,
      "old_path": "upload-pack.c",
      "new_id": "7e04311027176fc87c1de7dd619000d2a75d4eb9",
      "new_mode": 33188,
      "new_path": "upload-pack.c"
    }
  ]
}
