We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[FR][bug?] pre-commit hook repo self-test
Given a repo with `.pre-commit-hooks.yaml` defined (like https://github.com/ansible/ansible-lint), I want to integrate testing of the hooks declared in it.

I can do `pre-commit try-repo https://github.com/ansible/ansible-lint.git` but this hits the remote which I want to avoid. I know that Git itself can work with local fs paths (like `/path/to/.git`) perfectly fine.

So I tried:
<details>
<summary>
  <code>$ <kbd>pre-commit try-repo .git -vvv</kbd></code>
</summary>

```console
➜ pre-commit try-repo .git -vvv
[WARNING] Creating temporary repo with uncommitted changes...
An unexpected error has occurred: CalledProcessError: Command: ('/usr/bin/git', 'add', '-u')
Return code: 128
Expected return code: 0
Output: (none)
Errors: 
    fatal: this operation must be run in a work tree
    

Check the log at ~/.cache/pre-commit/pre-commit.log
```
</details>

The log doesn't reveal anything more than the fact that the Git command failed.
<details>
<summary>
  <code>$ <kbd>cat ~/.cache/pre-commit/pre-commit.log</kbd></code>
</summary>

```console
An unexpected error has occurred: CalledProcessError: Command: ('/usr/bin/git', 'add', '-u')
Return code: 128
Expected return code: 0
Output: (none)
Errors: 
    fatal: this operation must be run in a work tree
    

Traceback (most recent call last):
  File "~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/error_handler.py", line 46, in error_handler
    yield
  File "~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/main.py", line 296, in main
    return try_repo(args)
  File "~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/commands/try_repo.py", line 55, in try_repo
    repo, ref = _repo_ref(tempdir, args.repo, args.ref)
  File "~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/commands/try_repo.py", line 45, in _repo_ref
    cmd_output('git', 'add', '-u', cwd=repo, env=env)
  File "~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/util.py", line 153, in cmd_output
    returncode, cmd, retcode, output=(stdout, stderr),
pre_commit.util.CalledProcessError: Command: ('/usr/bin/git', 'add', '-u')
Return code: 128
Expected return code: 0
Output: (none)
Errors: 
    fatal: this operation must be run in a work tree
```
</details>

It must be pretty easy to fix.

--- 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/git.py`
Content:
```
1 from __future__ import unicode_literals
2 
3 import logging
4 import os.path
5 import sys
6 
7 from pre_commit.util import cmd_output
8 from pre_commit.util import cmd_output_b
9 
10 
11 logger = logging.getLogger(__name__)
12 
13 
14 def zsplit(s):
15     s = s.strip('\0')
16     if s:
17         return s.split('\0')
18     else:
19         return []
20 
21 
22 def no_git_env(_env=None):
23     # Too many bugs dealing with environment variables and GIT:
24     # https://github.com/pre-commit/pre-commit/issues/300
25     # In git 2.6.3 (maybe others), git exports GIT_WORK_TREE while running
26     # pre-commit hooks
27     # In git 1.9.1 (maybe others), git exports GIT_DIR and GIT_INDEX_FILE
28     # while running pre-commit hooks in submodules.
29     # GIT_DIR: Causes git clone to clone wrong thing
30     # GIT_INDEX_FILE: Causes 'error invalid object ...' during commit
31     _env = _env if _env is not None else os.environ
32     return {
33         k: v for k, v in _env.items()
34         if not k.startswith('GIT_') or
35         k in {'GIT_EXEC_PATH', 'GIT_SSH', 'GIT_SSH_COMMAND', 'GIT_SSL_CAINFO'}
36     }
37 
38 
39 def get_root():
40     return cmd_output('git', 'rev-parse', '--show-toplevel')[1].strip()
41 
42 
43 def get_git_dir(git_root='.'):
44     opts = ('--git-common-dir', '--git-dir')
45     _, out, _ = cmd_output('git', 'rev-parse', *opts, cwd=git_root)
46     for line, opt in zip(out.splitlines(), opts):
47         if line != opt:  # pragma: no branch (git < 2.5)
48             return os.path.normpath(os.path.join(git_root, line))
49     else:
50         raise AssertionError('unreachable: no git dir')
51 
52 
53 def get_remote_url(git_root):
54     _, out, _ = cmd_output('git', 'config', 'remote.origin.url', cwd=git_root)
55     return out.strip()
56 
57 
58 def is_in_merge_conflict():
59     git_dir = get_git_dir('.')
60     return (
61         os.path.exists(os.path.join(git_dir, 'MERGE_MSG')) and
62         os.path.exists(os.path.join(git_dir, 'MERGE_HEAD'))
63     )
64 
65 
66 def parse_merge_msg_for_conflicts(merge_msg):
67     # Conflicted files start with tabs
68     return [
69         line.lstrip(b'#').strip().decode('UTF-8')
70         for line in merge_msg.splitlines()
71         # '#\t' for git 2.4.1
72         if line.startswith((b'\t', b'#\t'))
73     ]
74 
75 
76 def get_conflicted_files():
77     logger.info('Checking merge-conflict files only.')
78     # Need to get the conflicted files from the MERGE_MSG because they could
79     # have resolved the conflict by choosing one side or the other
80     with open(os.path.join(get_git_dir('.'), 'MERGE_MSG'), 'rb') as f:
81         merge_msg = f.read()
82     merge_conflict_filenames = parse_merge_msg_for_conflicts(merge_msg)
83 
84     # This will get the rest of the changes made after the merge.
85     # If they resolved the merge conflict by choosing a mesh of both sides
86     # this will also include the conflicted files
87     tree_hash = cmd_output('git', 'write-tree')[1].strip()
88     merge_diff_filenames = zsplit(
89         cmd_output(
90             'git', 'diff', '--name-only', '--no-ext-diff', '-z',
91             '-m', tree_hash, 'HEAD', 'MERGE_HEAD',
92         )[1],
93     )
94     return set(merge_conflict_filenames) | set(merge_diff_filenames)
95 
96 
97 def get_staged_files(cwd=None):
98     return zsplit(
99         cmd_output(
100             'git', 'diff', '--staged', '--name-only', '--no-ext-diff', '-z',
101             # Everything except for D
102             '--diff-filter=ACMRTUXB',
103             cwd=cwd,
104         )[1],
105     )
106 
107 
108 def intent_to_add_files():
109     _, stdout, _ = cmd_output('git', 'status', '--porcelain', '-z')
110     parts = list(reversed(zsplit(stdout)))
111     intent_to_add = []
112     while parts:
113         line = parts.pop()
114         status, filename = line[:3], line[3:]
115         if status[0] in {'C', 'R'}:  # renames / moves have an additional arg
116             parts.pop()
117         if status[1] == 'A':
118             intent_to_add.append(filename)
119     return intent_to_add
120 
121 
122 def get_all_files():
123     return zsplit(cmd_output('git', 'ls-files', '-z')[1])
124 
125 
126 def get_changed_files(new, old):
127     return zsplit(
128         cmd_output(
129             'git', 'diff', '--name-only', '--no-ext-diff', '-z',
130             '{}...{}'.format(old, new),
131         )[1],
132     )
133 
134 
135 def head_rev(remote):
136     _, out, _ = cmd_output('git', 'ls-remote', '--exit-code', remote, 'HEAD')
137     return out.split()[0]
138 
139 
140 def has_diff(*args, **kwargs):
141     repo = kwargs.pop('repo', '.')
142     assert not kwargs, kwargs
143     cmd = ('git', 'diff', '--quiet', '--no-ext-diff') + args
144     return cmd_output_b(*cmd, cwd=repo, retcode=None)[0]
145 
146 
147 def has_core_hookpaths_set():
148     _, out, _ = cmd_output_b('git', 'config', 'core.hooksPath', retcode=None)
149     return bool(out.strip())
150 
151 
152 def init_repo(path, remote):
153     if os.path.isdir(remote):
154         remote = os.path.abspath(remote)
155 
156     env = no_git_env()
157     cmd_output_b('git', 'init', path, env=env)
158     cmd_output_b('git', 'remote', 'add', 'origin', remote, cwd=path, env=env)
159 
160 
161 def commit(repo='.'):
162     env = no_git_env()
163     name, email = 'pre-commit', 'asottile+pre-commit@umich.edu'
164     env['GIT_AUTHOR_NAME'] = env['GIT_COMMITTER_NAME'] = name
165     env['GIT_AUTHOR_EMAIL'] = env['GIT_COMMITTER_EMAIL'] = email
166     cmd = ('git', 'commit', '--no-edit', '--no-gpg-sign', '-n', '-minit')
167     cmd_output_b(*cmd, cwd=repo, env=env)
168 
169 
170 def git_path(name, repo='.'):
171     _, out, _ = cmd_output('git', 'rev-parse', '--git-path', name, cwd=repo)
172     return os.path.join(repo, out.strip())
173 
174 
175 def check_for_cygwin_mismatch():
176     """See https://github.com/pre-commit/pre-commit/issues/354"""
177     if sys.platform in ('cygwin', 'win32'):  # pragma: no cover (windows)
178         is_cygwin_python = sys.platform == 'cygwin'
179         toplevel = cmd_output('git', 'rev-parse', '--show-toplevel')[1]
180         is_cygwin_git = toplevel.startswith('/')
181 
182         if is_cygwin_python ^ is_cygwin_git:
183             exe_type = {True: '(cygwin)', False: '(windows)'}
184             logger.warn(
185                 'pre-commit has detected a mix of cygwin python / git\n'
186                 'This combination is not supported, it is likely you will '
187                 'receive an error later in the program.\n'
188                 'Make sure to use cygwin git+python while using cygwin\n'
189                 'These can be installed through the cygwin installer.\n'
190                 ' - python {}\n'
191                 ' - git {}\n'.format(
192                     exe_type[is_cygwin_python], exe_type[is_cygwin_git],
193                 ),
194             )
195
```
--- 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()

```

diff --git a/pre_commit/git.py b/pre_commit/git.py
--- a/pre_commit/git.py
+++ b/pre_commit/git.py
@@ -141,7 +141,7 @@
     repo = kwargs.pop('repo', '.')
     assert not kwargs, kwargs
     cmd = ('git', 'diff', '--quiet', '--no-ext-diff') + args
-    return cmd_output_b(*cmd, cwd=repo, retcode=None)[0]
+    return cmd_output_b(*cmd, cwd=repo, retcode=None)[0] == 1
 
 
 def has_core_hookpaths_set():

{"golden_diff": "diff --git a/pre_commit/git.py b/pre_commit/git.py\n--- a/pre_commit/git.py\n+++ b/pre_commit/git.py\n@@ -141,7 +141,7 @@\n     repo = kwargs.pop('repo', '.')\n     assert not kwargs, kwargs\n     cmd = ('git', 'diff', '--quiet', '--no-ext-diff') + args\n-    return cmd_output_b(*cmd, cwd=repo, retcode=None)[0]\n+    return cmd_output_b(*cmd, cwd=repo, retcode=None)[0] == 1\n \n \n def has_core_hookpaths_set():\n", "issue": "[FR][bug?] pre-commit hook repo self-test\nGiven a repo with `.pre-commit-hooks.yaml` defined (like https://github.com/ansible/ansible-lint), I want to integrate testing of the hooks declared in it.\r\n\r\nI can do `pre-commit try-repo https://github.com/ansible/ansible-lint.git` but this hits the remote which I want to avoid. I know that Git itself can work with local fs paths (like `/path/to/.git`) perfectly fine.\r\n\r\nSo I tried:\r\n<details>\r\n<summary>\r\n  <code>$ <kbd>pre-commit try-repo .git -vvv</kbd></code>\r\n</summary>\r\n\r\n```console\r\n\u279c pre-commit try-repo .git -vvv\r\n[WARNING] Creating temporary repo with uncommitted changes...\r\nAn unexpected error has occurred: CalledProcessError: Command: ('/usr/bin/git', 'add', '-u')\r\nReturn code: 128\r\nExpected return code: 0\r\nOutput: (none)\r\nErrors: \r\n    fatal: this operation must be run in a work tree\r\n    \r\n\r\nCheck the log at ~/.cache/pre-commit/pre-commit.log\r\n```\r\n</details>\r\n\r\nThe log doesn't reveal anything more than the fact that the Git command failed.\r\n<details>\r\n<summary>\r\n  <code>$ <kbd>cat ~/.cache/pre-commit/pre-commit.log</kbd></code>\r\n</summary>\r\n\r\n```console\r\nAn unexpected error has occurred: CalledProcessError: Command: ('/usr/bin/git', 'add', '-u')\r\nReturn code: 128\r\nExpected return code: 0\r\nOutput: (none)\r\nErrors: \r\n    fatal: this operation must be run in a work tree\r\n    \r\n\r\nTraceback (most recent call last):\r\n  File \"~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/error_handler.py\", line 46, in error_handler\r\n    yield\r\n  File \"~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/main.py\", line 296, in main\r\n    return try_repo(args)\r\n  File \"~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/commands/try_repo.py\", line 55, in try_repo\r\n    repo, ref = _repo_ref(tempdir, args.repo, args.ref)\r\n  File \"~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/commands/try_repo.py\", line 45, in _repo_ref\r\n    cmd_output('git', 'add', '-u', cwd=repo, env=env)\r\n  File \"~/.pyenv/versions/3.7.1/lib/python3.7/site-packages/pre_commit/util.py\", line 153, in cmd_output\r\n    returncode, cmd, retcode, output=(stdout, stderr),\r\npre_commit.util.CalledProcessError: Command: ('/usr/bin/git', 'add', '-u')\r\nReturn code: 128\r\nExpected return code: 0\r\nOutput: (none)\r\nErrors: \r\n    fatal: this operation must be run in a work tree\r\n```\r\n</details>\r\n\r\nIt must be pretty easy to fix.\n", "before_files": [{"content": "from __future__ import unicode_literals\n\nimport logging\nimport os.path\nimport sys\n\nfrom pre_commit.util import cmd_output\nfrom pre_commit.util import cmd_output_b\n\n\nlogger = logging.getLogger(__name__)\n\n\ndef zsplit(s):\n    s = s.strip('\\0')\n    if s:\n        return s.split('\\0')\n    else:\n        return []\n\n\ndef no_git_env(_env=None):\n    # Too many bugs dealing with environment variables and GIT:\n    # https://github.com/pre-commit/pre-commit/issues/300\n    # In git 2.6.3 (maybe others), git exports GIT_WORK_TREE while running\n    # pre-commit hooks\n    # In git 1.9.1 (maybe others), git exports GIT_DIR and GIT_INDEX_FILE\n    # while running pre-commit hooks in submodules.\n    # GIT_DIR: Causes git clone to clone wrong thing\n    # GIT_INDEX_FILE: Causes 'error invalid object ...' during commit\n    _env = _env if _env is not None else os.environ\n    return {\n        k: v for k, v in _env.items()\n        if not k.startswith('GIT_') or\n        k in {'GIT_EXEC_PATH', 'GIT_SSH', 'GIT_SSH_COMMAND', 'GIT_SSL_CAINFO'}\n    }\n\n\ndef get_root():\n    return cmd_output('git', 'rev-parse', '--show-toplevel')[1].strip()\n\n\ndef get_git_dir(git_root='.'):\n    opts = ('--git-common-dir', '--git-dir')\n    _, out, _ = cmd_output('git', 'rev-parse', *opts, cwd=git_root)\n    for line, opt in zip(out.splitlines(), opts):\n        if line != opt:  # pragma: no branch (git < 2.5)\n            return os.path.normpath(os.path.join(git_root, line))\n    else:\n        raise AssertionError('unreachable: no git dir')\n\n\ndef get_remote_url(git_root):\n    _, out, _ = cmd_output('git', 'config', 'remote.origin.url', cwd=git_root)\n    return out.strip()\n\n\ndef is_in_merge_conflict():\n    git_dir = get_git_dir('.')\n    return (\n        os.path.exists(os.path.join(git_dir, 'MERGE_MSG')) and\n        os.path.exists(os.path.join(git_dir, 'MERGE_HEAD'))\n    )\n\n\ndef parse_merge_msg_for_conflicts(merge_msg):\n    # Conflicted files start with tabs\n    return [\n        line.lstrip(b'#').strip().decode('UTF-8')\n        for line in merge_msg.splitlines()\n        # '#\\t' for git 2.4.1\n        if line.startswith((b'\\t', b'#\\t'))\n    ]\n\n\ndef get_conflicted_files():\n    logger.info('Checking merge-conflict files only.')\n    # Need to get the conflicted files from the MERGE_MSG because they could\n    # have resolved the conflict by choosing one side or the other\n    with open(os.path.join(get_git_dir('.'), 'MERGE_MSG'), 'rb') as f:\n        merge_msg = f.read()\n    merge_conflict_filenames = parse_merge_msg_for_conflicts(merge_msg)\n\n    # This will get the rest of the changes made after the merge.\n    # If they resolved the merge conflict by choosing a mesh of both sides\n    # this will also include the conflicted files\n    tree_hash = cmd_output('git', 'write-tree')[1].strip()\n    merge_diff_filenames = zsplit(\n        cmd_output(\n            'git', 'diff', '--name-only', '--no-ext-diff', '-z',\n            '-m', tree_hash, 'HEAD', 'MERGE_HEAD',\n        )[1],\n    )\n    return set(merge_conflict_filenames) | set(merge_diff_filenames)\n\n\ndef get_staged_files(cwd=None):\n    return zsplit(\n        cmd_output(\n            'git', 'diff', '--staged', '--name-only', '--no-ext-diff', '-z',\n            # Everything except for D\n            '--diff-filter=ACMRTUXB',\n            cwd=cwd,\n        )[1],\n    )\n\n\ndef intent_to_add_files():\n    _, stdout, _ = cmd_output('git', 'status', '--porcelain', '-z')\n    parts = list(reversed(zsplit(stdout)))\n    intent_to_add = []\n    while parts:\n        line = parts.pop()\n        status, filename = line[:3], line[3:]\n        if status[0] in {'C', 'R'}:  # renames / moves have an additional arg\n            parts.pop()\n        if status[1] == 'A':\n            intent_to_add.append(filename)\n    return intent_to_add\n\n\ndef get_all_files():\n    return zsplit(cmd_output('git', 'ls-files', '-z')[1])\n\n\ndef get_changed_files(new, old):\n    return zsplit(\n        cmd_output(\n            'git', 'diff', '--name-only', '--no-ext-diff', '-z',\n            '{}...{}'.format(old, new),\n        )[1],\n    )\n\n\ndef head_rev(remote):\n    _, out, _ = cmd_output('git', 'ls-remote', '--exit-code', remote, 'HEAD')\n    return out.split()[0]\n\n\ndef has_diff(*args, **kwargs):\n    repo = kwargs.pop('repo', '.')\n    assert not kwargs, kwargs\n    cmd = ('git', 'diff', '--quiet', '--no-ext-diff') + args\n    return cmd_output_b(*cmd, cwd=repo, retcode=None)[0]\n\n\ndef has_core_hookpaths_set():\n    _, out, _ = cmd_output_b('git', 'config', 'core.hooksPath', retcode=None)\n    return bool(out.strip())\n\n\ndef init_repo(path, remote):\n    if os.path.isdir(remote):\n        remote = os.path.abspath(remote)\n\n    env = no_git_env()\n    cmd_output_b('git', 'init', path, env=env)\n    cmd_output_b('git', 'remote', 'add', 'origin', remote, cwd=path, env=env)\n\n\ndef commit(repo='.'):\n    env = no_git_env()\n    name, email = 'pre-commit', 'asottile+pre-commit@umich.edu'\n    env['GIT_AUTHOR_NAME'] = env['GIT_COMMITTER_NAME'] = name\n    env['GIT_AUTHOR_EMAIL'] = env['GIT_COMMITTER_EMAIL'] = email\n    cmd = ('git', 'commit', '--no-edit', '--no-gpg-sign', '-n', '-minit')\n    cmd_output_b(*cmd, cwd=repo, env=env)\n\n\ndef git_path(name, repo='.'):\n    _, out, _ = cmd_output('git', 'rev-parse', '--git-path', name, cwd=repo)\n    return os.path.join(repo, out.strip())\n\n\ndef check_for_cygwin_mismatch():\n    \"\"\"See https://github.com/pre-commit/pre-commit/issues/354\"\"\"\n    if sys.platform in ('cygwin', 'win32'):  # pragma: no cover (windows)\n        is_cygwin_python = sys.platform == 'cygwin'\n        toplevel = cmd_output('git', 'rev-parse', '--show-toplevel')[1]\n        is_cygwin_git = toplevel.startswith('/')\n\n        if is_cygwin_python ^ is_cygwin_git:\n            exe_type = {True: '(cygwin)', False: '(windows)'}\n            logger.warn(\n                'pre-commit has detected a mix of cygwin python / git\\n'\n                'This combination is not supported, it is likely you will '\n                'receive an error later in the program.\\n'\n                'Make sure to use cygwin git+python while using cygwin\\n'\n                'These can be installed through the cygwin installer.\\n'\n                ' - python {}\\n'\n                ' - git {}\\n'.format(\n                    exe_type[is_cygwin_python], exe_type[is_cygwin_git],\n                ),\n            )\n", "path": "pre_commit/git.py"}], "after_files": [{"content": "from __future__ import unicode_literals\n\nimport logging\nimport os.path\nimport sys\n\nfrom pre_commit.util import cmd_output\nfrom pre_commit.util import cmd_output_b\n\n\nlogger = logging.getLogger(__name__)\n\n\ndef zsplit(s):\n    s = s.strip('\\0')\n    if s:\n        return s.split('\\0')\n    else:\n        return []\n\n\ndef no_git_env(_env=None):\n    # Too many bugs dealing with environment variables and GIT:\n    # https://github.com/pre-commit/pre-commit/issues/300\n    # In git 2.6.3 (maybe others), git exports GIT_WORK_TREE while running\n    # pre-commit hooks\n    # In git 1.9.1 (maybe others), git exports GIT_DIR and GIT_INDEX_FILE\n    # while running pre-commit hooks in submodules.\n    # GIT_DIR: Causes git clone to clone wrong thing\n    # GIT_INDEX_FILE: Causes 'error invalid object ...' during commit\n    _env = _env if _env is not None else os.environ\n    return {\n        k: v for k, v in _env.items()\n        if not k.startswith('GIT_') or\n        k in {'GIT_EXEC_PATH', 'GIT_SSH', 'GIT_SSH_COMMAND', 'GIT_SSL_CAINFO'}\n    }\n\n\ndef get_root():\n    return cmd_output('git', 'rev-parse', '--show-toplevel')[1].strip()\n\n\ndef get_git_dir(git_root='.'):\n    opts = ('--git-common-dir', '--git-dir')\n    _, out, _ = cmd_output('git', 'rev-parse', *opts, cwd=git_root)\n    for line, opt in zip(out.splitlines(), opts):\n        if line != opt:  # pragma: no branch (git < 2.5)\n            return os.path.normpath(os.path.join(git_root, line))\n    else:\n        raise AssertionError('unreachable: no git dir')\n\n\ndef get_remote_url(git_root):\n    _, out, _ = cmd_output('git', 'config', 'remote.origin.url', cwd=git_root)\n    return out.strip()\n\n\ndef is_in_merge_conflict():\n    git_dir = get_git_dir('.')\n    return (\n        os.path.exists(os.path.join(git_dir, 'MERGE_MSG')) and\n        os.path.exists(os.path.join(git_dir, 'MERGE_HEAD'))\n    )\n\n\ndef parse_merge_msg_for_conflicts(merge_msg):\n    # Conflicted files start with tabs\n    return [\n        line.lstrip(b'#').strip().decode('UTF-8')\n        for line in merge_msg.splitlines()\n        # '#\\t' for git 2.4.1\n        if line.startswith((b'\\t', b'#\\t'))\n    ]\n\n\ndef get_conflicted_files():\n    logger.info('Checking merge-conflict files only.')\n    # Need to get the conflicted files from the MERGE_MSG because they could\n    # have resolved the conflict by choosing one side or the other\n    with open(os.path.join(get_git_dir('.'), 'MERGE_MSG'), 'rb') as f:\n        merge_msg = f.read()\n    merge_conflict_filenames = parse_merge_msg_for_conflicts(merge_msg)\n\n    # This will get the rest of the changes made after the merge.\n    # If they resolved the merge conflict by choosing a mesh of both sides\n    # this will also include the conflicted files\n    tree_hash = cmd_output('git', 'write-tree')[1].strip()\n    merge_diff_filenames = zsplit(\n        cmd_output(\n            'git', 'diff', '--name-only', '--no-ext-diff', '-z',\n            '-m', tree_hash, 'HEAD', 'MERGE_HEAD',\n        )[1],\n    )\n    return set(merge_conflict_filenames) | set(merge_diff_filenames)\n\n\ndef get_staged_files(cwd=None):\n    return zsplit(\n        cmd_output(\n            'git', 'diff', '--staged', '--name-only', '--no-ext-diff', '-z',\n            # Everything except for D\n            '--diff-filter=ACMRTUXB',\n            cwd=cwd,\n        )[1],\n    )\n\n\ndef intent_to_add_files():\n    _, stdout, _ = cmd_output('git', 'status', '--porcelain', '-z')\n    parts = list(reversed(zsplit(stdout)))\n    intent_to_add = []\n    while parts:\n        line = parts.pop()\n        status, filename = line[:3], line[3:]\n        if status[0] in {'C', 'R'}:  # renames / moves have an additional arg\n            parts.pop()\n        if status[1] == 'A':\n            intent_to_add.append(filename)\n    return intent_to_add\n\n\ndef get_all_files():\n    return zsplit(cmd_output('git', 'ls-files', '-z')[1])\n\n\ndef get_changed_files(new, old):\n    return zsplit(\n        cmd_output(\n            'git', 'diff', '--name-only', '--no-ext-diff', '-z',\n            '{}...{}'.format(old, new),\n        )[1],\n    )\n\n\ndef head_rev(remote):\n    _, out, _ = cmd_output('git', 'ls-remote', '--exit-code', remote, 'HEAD')\n    return out.split()[0]\n\n\ndef has_diff(*args, **kwargs):\n    repo = kwargs.pop('repo', '.')\n    assert not kwargs, kwargs\n    cmd = ('git', 'diff', '--quiet', '--no-ext-diff') + args\n    return cmd_output_b(*cmd, cwd=repo, retcode=None)[0] == 1\n\n\ndef has_core_hookpaths_set():\n    _, out, _ = cmd_output_b('git', 'config', 'core.hooksPath', retcode=None)\n    return bool(out.strip())\n\n\ndef init_repo(path, remote):\n    if os.path.isdir(remote):\n        remote = os.path.abspath(remote)\n\n    env = no_git_env()\n    cmd_output_b('git', 'init', path, env=env)\n    cmd_output_b('git', 'remote', 'add', 'origin', remote, cwd=path, env=env)\n\n\ndef commit(repo='.'):\n    env = no_git_env()\n    name, email = 'pre-commit', 'asottile+pre-commit@umich.edu'\n    env['GIT_AUTHOR_NAME'] = env['GIT_COMMITTER_NAME'] = name\n    env['GIT_AUTHOR_EMAIL'] = env['GIT_COMMITTER_EMAIL'] = email\n    cmd = ('git', 'commit', '--no-edit', '--no-gpg-sign', '-n', '-minit')\n    cmd_output_b(*cmd, cwd=repo, env=env)\n\n\ndef git_path(name, repo='.'):\n    _, out, _ = cmd_output('git', 'rev-parse', '--git-path', name, cwd=repo)\n    return os.path.join(repo, out.strip())\n\n\ndef check_for_cygwin_mismatch():\n    \"\"\"See https://github.com/pre-commit/pre-commit/issues/354\"\"\"\n    if sys.platform in ('cygwin', 'win32'):  # pragma: no cover (windows)\n        is_cygwin_python = sys.platform == 'cygwin'\n        toplevel = cmd_output('git', 'rev-parse', '--show-toplevel')[1]\n        is_cygwin_git = toplevel.startswith('/')\n\n        if is_cygwin_python ^ is_cygwin_git:\n            exe_type = {True: '(cygwin)', False: '(windows)'}\n            logger.warn(\n                'pre-commit has detected a mix of cygwin python / git\\n'\n                'This combination is not supported, it is likely you will '\n                'receive an error later in the program.\\n'\n                'Make sure to use cygwin git+python while using cygwin\\n'\n                'These can be installed through the cygwin installer.\\n'\n                ' - python {}\\n'\n                ' - git {}\\n'.format(\n                    exe_type[is_cygwin_python], exe_type[is_cygwin_git],\n                ),\n            )\n", "path": "pre_commit/git.py"}]}