)]}'
{
  "commit": "c553c72eed64b5f7316ce227f6d5d783eae6f2ed",
  "tree": "9f0cada94f231acfb1dd7bd77729e5ddf4717d0a",
  "parents": [
    "bfb6b53c05daedc4084a5f716804a83781826230"
  ],
  "author": {
    "name": "Stefan Beller",
    "email": "sbeller@google.com",
    "time": "Tue Dec 15 16:04:10 2015 -0800"
  },
  "committer": {
    "name": "Junio C Hamano",
    "email": "gitster@pobox.com",
    "time": "Wed Dec 16 12:06:08 2015 -0800"
  },
  "message": "run-command: add an asynchronous parallel child processor\n\nThis allows to run external commands in parallel with ordered output\non stderr.\n\nIf we run external commands in parallel we cannot pipe the output directly\nto the our stdout/err as it would mix up. So each process\u0027s output will\nflow through a pipe, which we buffer. One subprocess can be directly\npiped to out stdout/err for a low latency feedback to the user.\n\nExample:\nLet\u0027s assume we have 5 submodules A,B,C,D,E and each fetch takes a\ndifferent amount of time as the different submodules vary in size, then\nthe output of fetches in sequential order might look like this:\n\n time --\u003e\n output: |---A---| |-B-| |-------C-------| |-D-| |-E-|\n\nWhen we schedule these submodules into maximal two parallel processes,\na schedule and sample output over time may look like this:\n\nprocess 1: |---A---| |-D-| |-E-|\n\nprocess 2: |-B-| |-------C-------|\n\noutput:    |---A---|B|---C-------|DE\n\nSo A will be perceived as it would run normally in the single child\nversion. As B has finished by the time A is done, we can dump its whole\nprogress buffer on stderr, such that it looks like it finished in no\ntime. Once that is done, C is determined to be the visible child and\nits progress will be reported in real time.\n\nSo this way of output is really good for human consumption, as it only\nchanges the timing, not the actual output.\n\nFor machine consumption the output needs to be prepared in the tasks,\nby either having a prefix per line or per block to indicate whose tasks\noutput is displayed, because the output order may not follow the\noriginal sequential ordering:\n\n |----A----| |--B--| |-C-|\n\nwill be scheduled to be all parallel:\n\nprocess 1: |----A----|\nprocess 2: |--B--|\nprocess 3: |-C-|\noutput:    |----A----|CB\n\nThis happens because C finished before B did, so it will be queued for\noutput before B.\n\nTo detect when a child has finished executing, we check interleaved\nwith other actions (such as checking the liveliness of children or\nstarting new processes) whether the stderr pipe still exists. Once a\nchild closed its stderr stream, we assume it is terminating very soon,\nand use `finish_command()` from the single external process execution\ninterface to collect the exit status.\n\nBy maintaining the strong assumption of stderr being open until the\nvery end of a child process, we can avoid other hassle such as an\nimplementation using `waitpid(-1)`, which is not implemented in Windows.\n\nSigned-off-by: Stefan Beller \u003csbeller@google.com\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "13fa452e8c3d5a5e20e24a969d53ce7ade4019bf",
      "old_mode": 33188,
      "old_path": "run-command.c",
      "new_id": "51fd72c4273c3ee59246285e40c9a5f9bd0e2f98",
      "new_mode": 33188,
      "new_path": "run-command.c"
    },
    {
      "type": "modify",
      "old_id": "12bb26c2a6155750203babfec47b08e8bde0ad27",
      "old_mode": 33188,
      "old_path": "run-command.h",
      "new_id": "d5a57f922781de57d8ee6ae56f90af1456ccd5d5",
      "new_mode": 33188,
      "new_path": "run-command.h"
    },
    {
      "type": "modify",
      "old_id": "9acf628726fe0c648279fb724f1917435db206f7",
      "old_mode": 33261,
      "old_path": "t/t0061-run-command.sh",
      "new_id": "12228b4aa6cb6a393a006130b31c73625911cec6",
      "new_mode": 33261,
      "new_path": "t/t0061-run-command.sh"
    },
    {
      "type": "modify",
      "old_id": "89c7de2c600ce2781ce666324e703d555937740a",
      "old_mode": 33188,
      "old_path": "test-run-command.c",
      "new_id": "fbe0a27ef3295fe3312fb72a478571bfb450cb25",
      "new_mode": 33188,
      "new_path": "test-run-command.c"
    }
  ]
}
