prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Stashed changes lost if hook fails with non-UTF-8 diff containing trailing whitespace
  Hi,
  
  A colleague almost lost all the changes she was working on after launching a `git commit` (with zero file added) and `pre-commit` crashing without restoring its [patch](https://github.com/pre-commit/pre-commit/blob/master/pre_commit/staged_files_only.py#L15).
  
  Here is the terminal message she got:
  
  ```
  [WARNING] Stashed changes conflicted with hook auto-fixes... Rolling back fixes...
  An unexpected error has occurred: CalledProcessError: Command: ['git', 'apply', 'C:\\Users\\toto\\.pre-commit\\patch1471341002']
  ```
  
  This seems very similar to a past solved issue:
  https://github.com/pre-commit/pre-commit/issues/176
  
  I think it had to do with CRLF conversion.
  I'm going to try to reproduce this.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pre_commit/staged_files_only.py`
  Content:
  ```
  1 from __future__ import unicode_literals
  2 
  3 import contextlib
  4 import io
  5 import logging
  6 import time
  7 
  8 from pre_commit.util import CalledProcessError
  9 
  10 
  11 logger = logging.getLogger('pre_commit')
  12 
  13 
  14 @contextlib.contextmanager
  15 def staged_files_only(cmd_runner):
  16     """Clear any unstaged changes from the git working directory inside this
  17     context.
  18 
  19     Args:
  20         cmd_runner - PrefixedCommandRunner
  21     """
  22     # Determine if there are unstaged files
  23     retcode, diff_stdout_binary, _ = cmd_runner.run(
  24         [
  25             'git', 'diff', '--ignore-submodules', '--binary', '--exit-code',
  26             '--no-color',
  27         ],
  28         retcode=None,
  29         encoding=None,
  30     )
  31     if retcode and diff_stdout_binary.strip():
  32         patch_filename = cmd_runner.path('patch{0}'.format(int(time.time())))
  33         logger.warning('Unstaged files detected.')
  34         logger.info(
  35             'Stashing unstaged files to {0}.'.format(patch_filename),
  36         )
  37         # Save the current unstaged changes as a patch
  38         with io.open(patch_filename, 'wb') as patch_file:
  39             patch_file.write(diff_stdout_binary)
  40 
  41         # Clear the working directory of unstaged changes
  42         cmd_runner.run(['git', 'checkout', '--', '.'])
  43         try:
  44             yield
  45         finally:
  46             # Try to apply the patch we saved
  47             try:
  48                 cmd_runner.run(['git', 'apply', patch_filename])
  49             except CalledProcessError:
  50                 logger.warning(
  51                     'Stashed changes conflicted with hook auto-fixes... '
  52                     'Rolling back fixes...'
  53                 )
  54                 # We failed to apply the patch, presumably due to fixes made
  55                 # by hooks.
  56                 # Roll back the changes made by hooks.
  57                 cmd_runner.run(['git', 'checkout', '--', '.'])
  58                 cmd_runner.run(['git', 'apply', patch_filename])
  59             logger.info('Restored changes from {0}.'.format(patch_filename))
  60     else:
  61         # There weren't any staged files so we don't need to do anything
  62         # special
  63         yield
  64
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pre_commit/staged_files_only.py b/pre_commit/staged_files_only.py
  --- a/pre_commit/staged_files_only.py
  +++ b/pre_commit/staged_files_only.py
  @@ -45,7 +45,7 @@
           finally:
               # Try to apply the patch we saved
               try:
  -                cmd_runner.run(['git', 'apply', patch_filename])
  +                cmd_runner.run(('git', 'apply', patch_filename), encoding=None)
               except CalledProcessError:
                   logger.warning(
                       'Stashed changes conflicted with hook auto-fixes... '
  @@ -55,7 +55,7 @@
                   # by hooks.
                   # Roll back the changes made by hooks.
                   cmd_runner.run(['git', 'checkout', '--', '.'])
  -                cmd_runner.run(['git', 'apply', patch_filename])
  +                cmd_runner.run(('git', 'apply', patch_filename), encoding=None)
               logger.info('Restored changes from {0}.'.format(patch_filename))
       else:
           # There weren't any staged files so we don't need to do anything
  
verification_info: {"golden_diff": "diff --git a/pre_commit/staged_files_only.py b/pre_commit/staged_files_only.py\n--- a/pre_commit/staged_files_only.py\n+++ b/pre_commit/staged_files_only.py\n@@ -45,7 +45,7 @@\n         finally:\n             # Try to apply the patch we saved\n             try:\n-                cmd_runner.run(['git', 'apply', patch_filename])\n+                cmd_runner.run(('git', 'apply', patch_filename), encoding=None)\n             except CalledProcessError:\n                 logger.warning(\n                     'Stashed changes conflicted with hook auto-fixes... '\n@@ -55,7 +55,7 @@\n                 # by hooks.\n                 # Roll back the changes made by hooks.\n                 cmd_runner.run(['git', 'checkout', '--', '.'])\n-                cmd_runner.run(['git', 'apply', patch_filename])\n+                cmd_runner.run(('git', 'apply', patch_filename), encoding=None)\n             logger.info('Restored changes from {0}.'.format(patch_filename))\n     else:\n         # There weren't any staged files so we don't need to do anything\n", "issue": "Stashed changes lost if hook fails with non-UTF-8 diff containing trailing whitespace\nHi,\n\nA colleague almost lost all the changes she was working on after launching a `git commit` (with zero file added) and `pre-commit` crashing without restoring its [patch](https://github.com/pre-commit/pre-commit/blob/master/pre_commit/staged_files_only.py#L15).\n\nHere is the terminal message she got:\n\n```\n[WARNING] Stashed changes conflicted with hook auto-fixes... Rolling back fixes...\nAn unexpected error has occurred: CalledProcessError: Command: ['git', 'apply', 'C:\\\\Users\\\\toto\\\\.pre-commit\\\\patch1471341002']\n```\n\nThis seems very similar to a past solved issue:\nhttps://github.com/pre-commit/pre-commit/issues/176\n\nI think it had to do with CRLF conversion.\nI'm going to try to reproduce this.\n\n", "before_files": [{"content": "from __future__ import unicode_literals\n\nimport contextlib\nimport io\nimport logging\nimport time\n\nfrom pre_commit.util import CalledProcessError\n\n\nlogger = logging.getLogger('pre_commit')\n\n\n@contextlib.contextmanager\ndef staged_files_only(cmd_runner):\n    \"\"\"Clear any unstaged changes from the git working directory inside this\n    context.\n\n    Args:\n        cmd_runner - PrefixedCommandRunner\n    \"\"\"\n    # Determine if there are unstaged files\n    retcode, diff_stdout_binary, _ = cmd_runner.run(\n        [\n            'git', 'diff', '--ignore-submodules', '--binary', '--exit-code',\n            '--no-color',\n        ],\n        retcode=None,\n        encoding=None,\n    )\n    if retcode and diff_stdout_binary.strip():\n        patch_filename = cmd_runner.path('patch{0}'.format(int(time.time())))\n        logger.warning('Unstaged files detected.')\n        logger.info(\n            'Stashing unstaged files to {0}.'.format(patch_filename),\n        )\n        # Save the current unstaged changes as a patch\n        with io.open(patch_filename, 'wb') as patch_file:\n            patch_file.write(diff_stdout_binary)\n\n        # Clear the working directory of unstaged changes\n        cmd_runner.run(['git', 'checkout', '--', '.'])\n        try:\n            yield\n        finally:\n            # Try to apply the patch we saved\n            try:\n                cmd_runner.run(['git', 'apply', patch_filename])\n            except CalledProcessError:\n                logger.warning(\n                    'Stashed changes conflicted with hook auto-fixes... '\n                    'Rolling back fixes...'\n                )\n                # We failed to apply the patch, presumably due to fixes made\n                # by hooks.\n                # Roll back the changes made by hooks.\n                cmd_runner.run(['git', 'checkout', '--', '.'])\n                cmd_runner.run(['git', 'apply', patch_filename])\n            logger.info('Restored changes from {0}.'.format(patch_filename))\n    else:\n        # There weren't any staged files so we don't need to do anything\n        # special\n        yield\n", "path": "pre_commit/staged_files_only.py"}], "after_files": [{"content": "from __future__ import unicode_literals\n\nimport contextlib\nimport io\nimport logging\nimport time\n\nfrom pre_commit.util import CalledProcessError\n\n\nlogger = logging.getLogger('pre_commit')\n\n\n@contextlib.contextmanager\ndef staged_files_only(cmd_runner):\n    \"\"\"Clear any unstaged changes from the git working directory inside this\n    context.\n\n    Args:\n        cmd_runner - PrefixedCommandRunner\n    \"\"\"\n    # Determine if there are unstaged files\n    retcode, diff_stdout_binary, _ = cmd_runner.run(\n        [\n            'git', 'diff', '--ignore-submodules', '--binary', '--exit-code',\n            '--no-color',\n        ],\n        retcode=None,\n        encoding=None,\n    )\n    if retcode and diff_stdout_binary.strip():\n        patch_filename = cmd_runner.path('patch{0}'.format(int(time.time())))\n        logger.warning('Unstaged files detected.')\n        logger.info(\n            'Stashing unstaged files to {0}.'.format(patch_filename),\n        )\n        # Save the current unstaged changes as a patch\n        with io.open(patch_filename, 'wb') as patch_file:\n            patch_file.write(diff_stdout_binary)\n\n        # Clear the working directory of unstaged changes\n        cmd_runner.run(['git', 'checkout', '--', '.'])\n        try:\n            yield\n        finally:\n            # Try to apply the patch we saved\n            try:\n                cmd_runner.run(('git', 'apply', patch_filename), encoding=None)\n            except CalledProcessError:\n                logger.warning(\n                    'Stashed changes conflicted with hook auto-fixes... '\n                    'Rolling back fixes...'\n                )\n                # We failed to apply the patch, presumably due to fixes made\n                # by hooks.\n                # Roll back the changes made by hooks.\n                cmd_runner.run(['git', 'checkout', '--', '.'])\n                cmd_runner.run(('git', 'apply', patch_filename), encoding=None)\n            logger.info('Restored changes from {0}.'.format(patch_filename))\n    else:\n        # There weren't any staged files so we don't need to do anything\n        # special\n        yield\n", "path": "pre_commit/staged_files_only.py"}]}