We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
git.get_git_dir() appears to break with older versions of git
When you install the current pre-commit (v1.11.0) on a system using an older git, eg 2.1.4, the `git rev-parse --git-common-dir` ultimately issued by `git.get_git_dir()` yields the result `--git-common-dir` instead of `.git` like you'd expect. This causes pre-commit to get installed in a directory literally named "--git-common-dir", and thus not work.

Happened to encounter using a docker image for an older version of python, which used an older git. Examples to demo the issue:

```
$ docker run python:2.7.9 sh -c "git init foo && cd foo && git rev-parse --git-common-dir && git --version"
Initialized empty Git repository in /foo/.git/
--git-common-dir
git version 2.1.4
$ docker run python:2.7.15 sh -c "git init foo && cd foo && git rev-parse --git-common-dir && git --version"
Initialized empty Git repository in /foo/.git/
.git
git version 2.11.0
```

In git.get_git_dir() as it stands, it appears that the older-git behavior is anticipated. It looks like older gits are expected to throw a `CalledProcessError` when `git rev-parse --git-common-dir` is called, and fall back to `git rev-parse --git-dir`. But evidently that's not working as intended?

--- 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.error_handler import FatalError
8 from pre_commit.util import CalledProcessError
9 from pre_commit.util import cmd_output
10 
11 
12 logger = logging.getLogger('pre_commit')
13 
14 
15 def zsplit(s):
16     s = s.strip('\0')
17     if s:
18         return s.split('\0')
19     else:
20         return []
21 
22 
23 def get_root():
24     try:
25         return cmd_output('git', 'rev-parse', '--show-toplevel')[1].strip()
26     except CalledProcessError:
27         raise FatalError(
28             'git failed. Is it installed, and are you in a Git repository '
29             'directory?',
30         )
31 
32 
33 def get_git_dir(git_root):
34     def _git_dir(opt):
35         return os.path.normpath(os.path.join(
36             git_root,
37             cmd_output('git', 'rev-parse', opt, cwd=git_root)[1].strip(),
38         ))
39 
40     try:
41         return _git_dir('--git-common-dir')
42     except CalledProcessError:  # pragma: no cover (git < 2.5)
43         return _git_dir('--git-dir')
44 
45 
46 def get_remote_url(git_root):
47     ret = cmd_output('git', 'config', 'remote.origin.url', cwd=git_root)[1]
48     return ret.strip()
49 
50 
51 def is_in_merge_conflict():
52     git_dir = get_git_dir('.')
53     return (
54         os.path.exists(os.path.join(git_dir, 'MERGE_MSG')) and
55         os.path.exists(os.path.join(git_dir, 'MERGE_HEAD'))
56     )
57 
58 
59 def parse_merge_msg_for_conflicts(merge_msg):
60     # Conflicted files start with tabs
61     return [
62         line.lstrip(b'#').strip().decode('UTF-8')
63         for line in merge_msg.splitlines()
64         # '#\t' for git 2.4.1
65         if line.startswith((b'\t', b'#\t'))
66     ]
67 
68 
69 def get_conflicted_files():
70     logger.info('Checking merge-conflict files only.')
71     # Need to get the conflicted files from the MERGE_MSG because they could
72     # have resolved the conflict by choosing one side or the other
73     with open(os.path.join(get_git_dir('.'), 'MERGE_MSG'), 'rb') as f:
74         merge_msg = f.read()
75     merge_conflict_filenames = parse_merge_msg_for_conflicts(merge_msg)
76 
77     # This will get the rest of the changes made after the merge.
78     # If they resolved the merge conflict by choosing a mesh of both sides
79     # this will also include the conflicted files
80     tree_hash = cmd_output('git', 'write-tree')[1].strip()
81     merge_diff_filenames = zsplit(cmd_output(
82         'git', 'diff', '--name-only', '--no-ext-diff', '-z',
83         '-m', tree_hash, 'HEAD', 'MERGE_HEAD',
84     )[1])
85     return set(merge_conflict_filenames) | set(merge_diff_filenames)
86 
87 
88 def get_staged_files():
89     return zsplit(cmd_output(
90         'git', 'diff', '--staged', '--name-only', '--no-ext-diff', '-z',
91         # Everything except for D
92         '--diff-filter=ACMRTUXB',
93     )[1])
94 
95 
96 def get_all_files():
97     return zsplit(cmd_output('git', 'ls-files', '-z')[1])
98 
99 
100 def get_changed_files(new, old):
101     return zsplit(cmd_output(
102         'git', 'diff', '--name-only', '--no-ext-diff', '-z',
103         '{}...{}'.format(old, new),
104     )[1])
105 
106 
107 def head_rev(remote):
108     _, out, _ = cmd_output('git', 'ls-remote', '--exit-code', remote, 'HEAD')
109     return out.split()[0]
110 
111 
112 def check_for_cygwin_mismatch():
113     """See https://github.com/pre-commit/pre-commit/issues/354"""
114     if sys.platform in ('cygwin', 'win32'):  # pragma: no cover (windows)
115         is_cygwin_python = sys.platform == 'cygwin'
116         toplevel = cmd_output('git', 'rev-parse', '--show-toplevel')[1]
117         is_cygwin_git = toplevel.startswith('/')
118 
119         if is_cygwin_python ^ is_cygwin_git:
120             exe_type = {True: '(cygwin)', False: '(windows)'}
121             logger.warn(
122                 'pre-commit has detected a mix of cygwin python / git\n'
123                 'This combination is not supported, it is likely you will '
124                 'receive an error later in the program.\n'
125                 'Make sure to use cygwin git+python while using cygwin\n'
126                 'These can be installed through the cygwin installer.\n'
127                 ' - python {}\n'
128                 ' - git {}\n'.format(
129                     exe_type[is_cygwin_python], exe_type[is_cygwin_git],
130                 ),
131             )
132
```
--- 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
@@ -31,16 +31,13 @@
 
 
 def get_git_dir(git_root):
-    def _git_dir(opt):
-        return os.path.normpath(os.path.join(
-            git_root,
-            cmd_output('git', 'rev-parse', opt, cwd=git_root)[1].strip(),
-        ))
-
-    try:
-        return _git_dir('--git-common-dir')
-    except CalledProcessError:  # pragma: no cover (git < 2.5)
-        return _git_dir('--git-dir')
+    opts = ('--git-common-dir', '--git-dir')
+    _, out, _ = cmd_output('git', 'rev-parse', *opts, cwd=git_root)
+    for line, opt in zip(out.splitlines(), opts):
+        if line != opt:  # pragma: no branch (git < 2.5)
+            return os.path.normpath(os.path.join(git_root, line))
+    else:
+        raise AssertionError('unreachable: no git dir')
 
 
 def get_remote_url(git_root):

{"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@@ -31,16 +31,13 @@\n \n \n def get_git_dir(git_root):\n-    def _git_dir(opt):\n-        return os.path.normpath(os.path.join(\n-            git_root,\n-            cmd_output('git', 'rev-parse', opt, cwd=git_root)[1].strip(),\n-        ))\n-\n-    try:\n-        return _git_dir('--git-common-dir')\n-    except CalledProcessError:  # pragma: no cover (git < 2.5)\n-        return _git_dir('--git-dir')\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 \n def get_remote_url(git_root):\n", "issue": "git.get_git_dir() appears to break with older versions of git\nWhen you install the current pre-commit (v1.11.0) on a system using an older git, eg 2.1.4, the `git rev-parse --git-common-dir` ultimately issued by `git.get_git_dir()` yields the result `--git-common-dir` instead of `.git` like you'd expect. This causes pre-commit to get installed in a directory literally named \"--git-common-dir\", and thus not work.\r\n\r\nHappened to encounter using a docker image for an older version of python, which used an older git. Examples to demo the issue:\r\n\r\n```\r\n$ docker run python:2.7.9 sh -c \"git init foo && cd foo && git rev-parse --git-common-dir && git --version\"\r\nInitialized empty Git repository in /foo/.git/\r\n--git-common-dir\r\ngit version 2.1.4\r\n$ docker run python:2.7.15 sh -c \"git init foo && cd foo && git rev-parse --git-common-dir && git --version\"\r\nInitialized empty Git repository in /foo/.git/\r\n.git\r\ngit version 2.11.0\r\n```\r\n\r\nIn git.get_git_dir() as it stands, it appears that the older-git behavior is anticipated. It looks like older gits are expected to throw a `CalledProcessError` when `git rev-parse --git-common-dir` is called, and fall back to `git rev-parse --git-dir`. But evidently that's not working as intended?\n", "before_files": [{"content": "from __future__ import unicode_literals\n\nimport logging\nimport os.path\nimport sys\n\nfrom pre_commit.error_handler import FatalError\nfrom pre_commit.util import CalledProcessError\nfrom pre_commit.util import cmd_output\n\n\nlogger = logging.getLogger('pre_commit')\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 get_root():\n    try:\n        return cmd_output('git', 'rev-parse', '--show-toplevel')[1].strip()\n    except CalledProcessError:\n        raise FatalError(\n            'git failed. Is it installed, and are you in a Git repository '\n            'directory?',\n        )\n\n\ndef get_git_dir(git_root):\n    def _git_dir(opt):\n        return os.path.normpath(os.path.join(\n            git_root,\n            cmd_output('git', 'rev-parse', opt, cwd=git_root)[1].strip(),\n        ))\n\n    try:\n        return _git_dir('--git-common-dir')\n    except CalledProcessError:  # pragma: no cover (git < 2.5)\n        return _git_dir('--git-dir')\n\n\ndef get_remote_url(git_root):\n    ret = cmd_output('git', 'config', 'remote.origin.url', cwd=git_root)[1]\n    return ret.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(cmd_output(\n        'git', 'diff', '--name-only', '--no-ext-diff', '-z',\n        '-m', tree_hash, 'HEAD', 'MERGE_HEAD',\n    )[1])\n    return set(merge_conflict_filenames) | set(merge_diff_filenames)\n\n\ndef get_staged_files():\n    return zsplit(cmd_output(\n        'git', 'diff', '--staged', '--name-only', '--no-ext-diff', '-z',\n        # Everything except for D\n        '--diff-filter=ACMRTUXB',\n    )[1])\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(cmd_output(\n        'git', 'diff', '--name-only', '--no-ext-diff', '-z',\n        '{}...{}'.format(old, new),\n    )[1])\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 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.error_handler import FatalError\nfrom pre_commit.util import CalledProcessError\nfrom pre_commit.util import cmd_output\n\n\nlogger = logging.getLogger('pre_commit')\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 get_root():\n    try:\n        return cmd_output('git', 'rev-parse', '--show-toplevel')[1].strip()\n    except CalledProcessError:\n        raise FatalError(\n            'git failed. Is it installed, and are you in a Git repository '\n            'directory?',\n        )\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    ret = cmd_output('git', 'config', 'remote.origin.url', cwd=git_root)[1]\n    return ret.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(cmd_output(\n        'git', 'diff', '--name-only', '--no-ext-diff', '-z',\n        '-m', tree_hash, 'HEAD', 'MERGE_HEAD',\n    )[1])\n    return set(merge_conflict_filenames) | set(merge_diff_filenames)\n\n\ndef get_staged_files():\n    return zsplit(cmd_output(\n        'git', 'diff', '--staged', '--name-only', '--no-ext-diff', '-z',\n        # Everything except for D\n        '--diff-filter=ACMRTUXB',\n    )[1])\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(cmd_output(\n        'git', 'diff', '--name-only', '--no-ext-diff', '-z',\n        '{}...{}'.format(old, new),\n    )[1])\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 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"}]}