)]}'
{
  "commit": "eac14f8909d986a38d9eab4a7f926af41dd64a4f",
  "tree": "bfb6232a7c07c07defe9e8272b8879ee35cada6d",
  "parents": [
    "1c950a594c40db7a946616cbc6cc5f9e25926a20"
  ],
  "author": {
    "name": "Karsten Blees",
    "email": "blees@dcon.de",
    "time": "Sat Jan 14 22:24:19 2012 +0100"
  },
  "committer": {
    "name": "Junio C Hamano",
    "email": "gitster@pobox.com",
    "time": "Tue Jun 10 13:32:59 2014 -0700"
  },
  "message": "Win32: Thread-safe windows console output\n\nWinansi.c has many static variables that are accessed and modified from\nthe [v][f]printf / fputs functions overridden in the file. This may cause\nmulti threaded git commands that print to the console to produce corrupted\noutput or even crash.\n\nAdditionally, winansi.c doesn\u0027t override all functions that can be used to\nprint to the console (e.g. fwrite, write, fputc are missing), so that ANSI\nescapes don\u0027t work properly for some git commands (e.g. git-grep).\n\nInstead of doing ANSI emulation in just a few wrapped functions on top of\nthe IO API, let\u0027s plug into the IO system and take advantage of the thread\nsafety inherent to the IO system.\n\nRedirect stdout and stderr to a pipe if they point to the console. A\nbackground thread reads from the pipe, handles ANSI escape sequences and\nUTF-8 to UTF-16 conversion, then writes to the console.\n\nThe pipe-based stdout and stderr replacements must be set to unbuffered, as\nMSVCRT doesn\u0027t support line buffering and fully buffered streams are\ninappropriate for console output.\n\nDue to the byte-oriented pipe, ANSI escape sequences and multi-byte UTF-8\nsequences can no longer be expected to arrive in one piece. Replace the\nstring-based ansi_emulate() with a simple stateful parser (this also fixes\ncolored diff hunk headers, which were broken as of commit 2efcc977).\n\nOverride isatty to return true for the pipes redirecting to the console.\n\nExec/spawn obtain the original console handle to pass to the next process\nvia winansi_get_osfhandle().\n\nAll other overrides are gone, the default stdio implementations work as\nexpected with the piped stdout/stderr descriptors.\n\nGlobal variables are either initialized on startup (single threaded) or\nexclusively modified by the background thread. Threads communicate through\nthe pipe, no further synchronization is necessary.\n\nThe background thread is terminated by disonnecting the pipe after flushing\nthe stdio and pipe buffers. This doesn\u0027t work for anonymous pipes (created\nvia CreatePipe), as DisconnectNamedPipe only works on the read end, which\ndiscards remaining data. Thus we have to setup the pipe manually, with the\nwrite end beeing the server (opened with CreateNamedPipe) and the read end\nthe client (opened with CreateFile).\n\nLimitations: doesn\u0027t track reopened or duped file descriptors, i.e.:\n- fdopen(1/2) returns fully buffered streams\n- dup(1/2), dup2(1/2) returns normal pipe descriptors (i.e. isatty() \u003d\n  false, winansi_get_osfhandle won\u0027t return the original console handle)\n\nCurrently, only the git-format-patch command uses xfdopen(xdup(1)) (see\n\"realstdout\" in builtin/log.c), but works well with these limitations.\n\nMany thanks to Atsushi Nakagawa \u003catnak@chejz.com\u003e for suggesting and\nreviewing the thread-exit-mechanism.\n\nSigned-off-by: Karsten Blees \u003cblees@dcon.de\u003e\nSigned-off-by: Stepan Kasal \u003ckasal@ucw.cz\u003e\nSigned-off-by: Junio C Hamano \u003cgitster@pobox.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "6f1fb108e9968ecc984c838cdeafc30bfb512842",
      "old_mode": 33188,
      "old_path": "compat/mingw.c",
      "new_id": "d242557eb5781b21123f0cdd8f41c5205fa2e836",
      "new_mode": 33188,
      "new_path": "compat/mingw.c"
    },
    {
      "type": "modify",
      "old_id": "921ba08b1de05808250b9cde24abecc1a9d47576",
      "old_mode": 33188,
      "old_path": "compat/mingw.h",
      "new_id": "4b638d83361abe2abd8c1a13139ed5ffd71e9cc6",
      "new_mode": 33188,
      "new_path": "compat/mingw.h"
    },
    {
      "type": "modify",
      "old_id": "bec6713b746e2006c34ca21c91ea6e7d633a54f2",
      "old_mode": 33188,
      "old_path": "compat/winansi.c",
      "new_id": "fcdd6dc1b394bc71fa71435534f260d3338548a1",
      "new_mode": 33188,
      "new_path": "compat/winansi.c"
    }
  ]
}
