We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Not stashing changes before installing
Hi,

I'm regularly running into this situation: I have pending changes, I run `git commit -a`, and pre-commit tries to install its hooks:

```
[INFO] Initializing environment for git://github.com/pre-commit/pre-commit-hooks.
An unexpected error has occurred: CalledProcessError: Command: ['git', 'checkout', 'd3db0385825d4c082bc7117c090ac16cb4840f3e']
Return code: 1
Expected return code: 0
Output: (none)
Errors: 
    error: Your local changes to the following files would be overwritten by checkout:
        .pre-commit-config.yaml
        .travis.yml
        CHANGELOG
        README.md
        hooks.yaml
        pre_commit_hooks/autopep8_wrapper.py
        pre_commit_hooks/check_json.py
        pre_commit_hooks/check_yaml.py
        pre_commit_hooks/debug_statement_hook.py
        pre_commit_hooks/end_of_file_fixer.py
        pre_commit_hooks/tests_should_end_in_test.py
        pre_commit_hooks/trailing_whitespace_fixer.py
        pre_commit_hooks/util.py
        pylintrc
        requirements-dev.txt
        setup.py
        testing/util.py
        tests/autopep8_wrapper_test.py
        tests/debug_statement_hook_test.py
        tests/end_of_file_fixer_test.py
        tests/tests_should_end_in_test_test.py
        tests/trailing_whitespace_fixer_test.py
        tests/util_test.py
        tox.ini
    Please, commit your changes or stash them before you can switch branches.
    Aborting


Check the log at ~/.pre-commit/pre-commit.log
```

The log contents are 

```
An unexpected error has occurred: CalledProcessError: Command: ['git', 'checkout', 'd3db0385825d4c082bc7117c090ac16cb4840f3e']
Return code: 1
Expected return code: 0
Output: (none)
Errors: 
    error: Your local changes to the following files would be overwritten by checkout:
        .pre-commit-config.yaml
        .travis.yml
        CHANGELOG
        README.md
        hooks.yaml
        pre_commit_hooks/autopep8_wrapper.py
        pre_commit_hooks/check_json.py
        pre_commit_hooks/check_yaml.py
        pre_commit_hooks/debug_statement_hook.py
        pre_commit_hooks/end_of_file_fixer.py
        pre_commit_hooks/tests_should_end_in_test.py
        pre_commit_hooks/trailing_whitespace_fixer.py
        pre_commit_hooks/util.py
        pylintrc
        requirements-dev.txt
        setup.py
        testing/util.py
        tests/autopep8_wrapper_test.py
        tests/debug_statement_hook_test.py
        tests/end_of_file_fixer_test.py
        tests/tests_should_end_in_test_test.py
        tests/trailing_whitespace_fixer_test.py
        tests/util_test.py
        tox.ini
    Please, commit your changes or stash them before you can switch branches.
    Aborting


Traceback (most recent call last):
  File "/home/qdm/workspace/web/pre-commit/pre_commit/error_handler.py", line 34, in error_handler
    yield
  File "/home/qdm/workspace/web/pre-commit/pre_commit/main.py", line 129, in main
    return run(runner, args)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/commands/run.py", line 165, in run
    return _run_hooks(runner, args, write=write, environ=environ)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/commands/run.py", line 115, in _run_hooks
    for repo in runner.repositories:
  File "/usr/lib/python3.4/site-packages/cached_property.py", line 26, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/runner.py", line 43, in repositories
    repository.require_installed()
  File "/home/qdm/workspace/web/pre-commit/pre_commit/repository.py", line 64, in require_installed
    self.install()
  File "/home/qdm/workspace/web/pre-commit/pre_commit/repository.py", line 78, in install
    for language_name, _ in self.languages
  File "/usr/lib/python3.4/site-packages/cached_property.py", line 26, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/repository.py", line 41, in languages
    for _, hook in self.hooks
  File "/usr/lib/python3.4/site-packages/cached_property.py", line 26, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/repository.py", line 49, in hooks
    for hook in self.repo_config['hooks']
  File "/home/qdm/workspace/web/pre-commit/pre_commit/repository.py", line 49, in <genexpr>
    for hook in self.repo_config['hooks']
  File "/usr/lib/python3.4/site-packages/cached_property.py", line 26, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/manifest.py", line 24, in hooks
    return dict((hook['id'], hook) for hook in self.manifest_contents)
  File "/usr/lib/python3.4/site-packages/cached_property.py", line 26, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/manifest.py", line 18, in manifest_contents
    self.repo_path_getter.repo_path, C.MANIFEST_FILE,
  File "/usr/lib/python3.4/site-packages/cached_property.py", line 26, in __get__
    value = obj.__dict__[self.func.__name__] = self.func(obj)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/store.py", line 46, in repo_path
    return self._store.clone(self._repo, self._sha)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/store.py", line 119, in clone
    cmd_output('git', 'checkout', sha)
  File "/home/qdm/workspace/web/pre-commit/pre_commit/util.py", line 160, in cmd_output
    returncode, cmd, retcode, output=(stdout, stderr),
pre_commit.util.CalledProcessError: Command: ['git', 'checkout', 'd3db0385825d4c082bc7117c090ac16cb4840f3e']
Return code: 1
Expected return code: 0
Output: (none)
Errors: 
    error: Your local changes to the following files would be overwritten by checkout:
        .pre-commit-config.yaml
        .travis.yml
        CHANGELOG
        README.md
        hooks.yaml
        pre_commit_hooks/autopep8_wrapper.py
        pre_commit_hooks/check_json.py
        pre_commit_hooks/check_yaml.py
        pre_commit_hooks/debug_statement_hook.py
        pre_commit_hooks/end_of_file_fixer.py
        pre_commit_hooks/tests_should_end_in_test.py
        pre_commit_hooks/trailing_whitespace_fixer.py
        pre_commit_hooks/util.py
        pylintrc
        requirements-dev.txt
        setup.py
        testing/util.py
        tests/autopep8_wrapper_test.py
        tests/debug_statement_hook_test.py
        tests/end_of_file_fixer_test.py
        tests/tests_should_end_in_test_test.py
        tests/trailing_whitespace_fixer_test.py
        tests/util_test.py
        tox.ini
    Please, commit your changes or stash them before you can switch branches.
    Aborting
```

I think this is a regression from a previous version, it was more seamless then.


--- 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/store.py`
Content:
```
1 from __future__ import unicode_literals
2 
3 import contextlib
4 import io
5 import logging
6 import os
7 import os.path
8 import sqlite3
9 import tempfile
10 
11 from cached_property import cached_property
12 
13 from pre_commit.prefixed_command_runner import PrefixedCommandRunner
14 from pre_commit.util import clean_path_on_failure
15 from pre_commit.util import cmd_output
16 from pre_commit.util import cwd
17 
18 
19 logger = logging.getLogger('pre_commit')
20 
21 
22 def _get_default_directory():
23     """Returns the default directory for the Store.  This is intentionally
24     underscored to indicate that `Store.get_default_directory` is the intended
25     way to get this information.  This is also done so
26     `Store.get_default_directory` can be mocked in tests and
27     `_get_default_directory` can be tested.
28     """
29     return os.environ.get(
30         'PRE_COMMIT_HOME',
31         os.path.join(os.path.expanduser('~'), '.pre-commit'),
32     )
33 
34 
35 class Store(object):
36     get_default_directory = staticmethod(_get_default_directory)
37 
38     class RepoPathGetter(object):
39         def __init__(self, repo, sha, store):
40             self._repo = repo
41             self._sha = sha
42             self._store = store
43 
44         @cached_property
45         def repo_path(self):
46             return self._store.clone(self._repo, self._sha)
47 
48     def __init__(self, directory=None):
49         if directory is None:
50             directory = self.get_default_directory()
51 
52         self.directory = directory
53         self.__created = False
54 
55     def _write_readme(self):
56         with io.open(os.path.join(self.directory, 'README'), 'w') as readme:
57             readme.write(
58                 'This directory is maintained by the pre-commit project.\n'
59                 'Learn more: https://github.com/pre-commit/pre-commit\n'
60             )
61 
62     def _write_sqlite_db(self):
63         # To avoid a race where someone ^Cs between db creation and execution
64         # of the CREATE TABLE statement
65         fd, tmpfile = tempfile.mkstemp(dir=self.directory)
66         # We'll be managing this file ourselves
67         os.close(fd)
68         # sqlite doesn't close its fd with its contextmanager >.<
69         # contextlib.closing fixes this.
70         # See: http://stackoverflow.com/a/28032829/812183
71         with contextlib.closing(sqlite3.connect(tmpfile)) as db:
72             db.executescript(
73                 'CREATE TABLE repos ('
74                 '    repo CHAR(255) NOT NULL,'
75                 '    ref CHAR(255) NOT NULL,'
76                 '    path CHAR(255) NOT NULL,'
77                 '    PRIMARY KEY (repo, ref)'
78                 ');'
79             )
80 
81         # Atomic file move
82         os.rename(tmpfile, self.db_path)
83 
84     def _create(self):
85         if os.path.exists(self.db_path):
86             return
87         if not os.path.exists(self.directory):
88             os.makedirs(self.directory)
89             self._write_readme()
90         self._write_sqlite_db()
91 
92     def require_created(self):
93         """Require the pre-commit file store to be created."""
94         if self.__created:
95             return
96 
97         self._create()
98         self.__created = True
99 
100     def clone(self, url, sha):
101         """Clone the given url and checkout the specific sha."""
102         self.require_created()
103 
104         # Check if we already exist
105         with sqlite3.connect(self.db_path) as db:
106             result = db.execute(
107                 'SELECT path FROM repos WHERE repo = ? AND ref = ?',
108                 [url, sha],
109             ).fetchone()
110             if result:
111                 return result[0]
112 
113         logger.info('Initializing environment for {0}.'.format(url))
114 
115         dir = tempfile.mkdtemp(prefix='repo', dir=self.directory)
116         with clean_path_on_failure(dir):
117             cmd_output('git', 'clone', '--no-checkout', url, dir)
118             with cwd(dir):
119                 cmd_output('git', 'checkout', sha)
120 
121         # Update our db with the created repo
122         with sqlite3.connect(self.db_path) as db:
123             db.execute(
124                 'INSERT INTO repos (repo, ref, path) VALUES (?, ?, ?)',
125                 [url, sha, dir],
126             )
127         return dir
128 
129     def get_repo_path_getter(self, repo, sha):
130         return self.RepoPathGetter(repo, sha, self)
131 
132     @cached_property
133     def cmd_runner(self):
134         return PrefixedCommandRunner(self.directory)
135 
136     @cached_property
137     def db_path(self):
138         return os.path.join(self.directory, 'db.db')
139
```
--- 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/store.py b/pre_commit/store.py
--- a/pre_commit/store.py
+++ b/pre_commit/store.py
@@ -116,7 +116,7 @@
         with clean_path_on_failure(dir):
             cmd_output('git', 'clone', '--no-checkout', url, dir)
             with cwd(dir):
-                cmd_output('git', 'checkout', sha)
+                cmd_output('git', 'reset', sha, '--hard')
 
         # Update our db with the created repo
         with sqlite3.connect(self.db_path) as db:

{"golden_diff": "diff --git a/pre_commit/store.py b/pre_commit/store.py\n--- a/pre_commit/store.py\n+++ b/pre_commit/store.py\n@@ -116,7 +116,7 @@\n         with clean_path_on_failure(dir):\n             cmd_output('git', 'clone', '--no-checkout', url, dir)\n             with cwd(dir):\n-                cmd_output('git', 'checkout', sha)\n+                cmd_output('git', 'reset', sha, '--hard')\n \n         # Update our db with the created repo\n         with sqlite3.connect(self.db_path) as db:\n", "issue": "Not stashing changes before installing\nHi,\n\nI'm regularly running into this situation: I have pending changes, I run `git commit -a`, and pre-commit tries to install its hooks:\n\n```\n[INFO] Initializing environment for git://github.com/pre-commit/pre-commit-hooks.\nAn unexpected error has occurred: CalledProcessError: Command: ['git', 'checkout', 'd3db0385825d4c082bc7117c090ac16cb4840f3e']\nReturn code: 1\nExpected return code: 0\nOutput: (none)\nErrors: \n    error: Your local changes to the following files would be overwritten by checkout:\n        .pre-commit-config.yaml\n        .travis.yml\n        CHANGELOG\n        README.md\n        hooks.yaml\n        pre_commit_hooks/autopep8_wrapper.py\n        pre_commit_hooks/check_json.py\n        pre_commit_hooks/check_yaml.py\n        pre_commit_hooks/debug_statement_hook.py\n        pre_commit_hooks/end_of_file_fixer.py\n        pre_commit_hooks/tests_should_end_in_test.py\n        pre_commit_hooks/trailing_whitespace_fixer.py\n        pre_commit_hooks/util.py\n        pylintrc\n        requirements-dev.txt\n        setup.py\n        testing/util.py\n        tests/autopep8_wrapper_test.py\n        tests/debug_statement_hook_test.py\n        tests/end_of_file_fixer_test.py\n        tests/tests_should_end_in_test_test.py\n        tests/trailing_whitespace_fixer_test.py\n        tests/util_test.py\n        tox.ini\n    Please, commit your changes or stash them before you can switch branches.\n    Aborting\n\n\nCheck the log at ~/.pre-commit/pre-commit.log\n```\n\nThe log contents are \n\n```\nAn unexpected error has occurred: CalledProcessError: Command: ['git', 'checkout', 'd3db0385825d4c082bc7117c090ac16cb4840f3e']\nReturn code: 1\nExpected return code: 0\nOutput: (none)\nErrors: \n    error: Your local changes to the following files would be overwritten by checkout:\n        .pre-commit-config.yaml\n        .travis.yml\n        CHANGELOG\n        README.md\n        hooks.yaml\n        pre_commit_hooks/autopep8_wrapper.py\n        pre_commit_hooks/check_json.py\n        pre_commit_hooks/check_yaml.py\n        pre_commit_hooks/debug_statement_hook.py\n        pre_commit_hooks/end_of_file_fixer.py\n        pre_commit_hooks/tests_should_end_in_test.py\n        pre_commit_hooks/trailing_whitespace_fixer.py\n        pre_commit_hooks/util.py\n        pylintrc\n        requirements-dev.txt\n        setup.py\n        testing/util.py\n        tests/autopep8_wrapper_test.py\n        tests/debug_statement_hook_test.py\n        tests/end_of_file_fixer_test.py\n        tests/tests_should_end_in_test_test.py\n        tests/trailing_whitespace_fixer_test.py\n        tests/util_test.py\n        tox.ini\n    Please, commit your changes or stash them before you can switch branches.\n    Aborting\n\n\nTraceback (most recent call last):\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/error_handler.py\", line 34, in error_handler\n    yield\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/main.py\", line 129, in main\n    return run(runner, args)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/commands/run.py\", line 165, in run\n    return _run_hooks(runner, args, write=write, environ=environ)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/commands/run.py\", line 115, in _run_hooks\n    for repo in runner.repositories:\n  File \"/usr/lib/python3.4/site-packages/cached_property.py\", line 26, in __get__\n    value = obj.__dict__[self.func.__name__] = self.func(obj)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/runner.py\", line 43, in repositories\n    repository.require_installed()\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/repository.py\", line 64, in require_installed\n    self.install()\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/repository.py\", line 78, in install\n    for language_name, _ in self.languages\n  File \"/usr/lib/python3.4/site-packages/cached_property.py\", line 26, in __get__\n    value = obj.__dict__[self.func.__name__] = self.func(obj)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/repository.py\", line 41, in languages\n    for _, hook in self.hooks\n  File \"/usr/lib/python3.4/site-packages/cached_property.py\", line 26, in __get__\n    value = obj.__dict__[self.func.__name__] = self.func(obj)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/repository.py\", line 49, in hooks\n    for hook in self.repo_config['hooks']\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/repository.py\", line 49, in <genexpr>\n    for hook in self.repo_config['hooks']\n  File \"/usr/lib/python3.4/site-packages/cached_property.py\", line 26, in __get__\n    value = obj.__dict__[self.func.__name__] = self.func(obj)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/manifest.py\", line 24, in hooks\n    return dict((hook['id'], hook) for hook in self.manifest_contents)\n  File \"/usr/lib/python3.4/site-packages/cached_property.py\", line 26, in __get__\n    value = obj.__dict__[self.func.__name__] = self.func(obj)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/manifest.py\", line 18, in manifest_contents\n    self.repo_path_getter.repo_path, C.MANIFEST_FILE,\n  File \"/usr/lib/python3.4/site-packages/cached_property.py\", line 26, in __get__\n    value = obj.__dict__[self.func.__name__] = self.func(obj)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/store.py\", line 46, in repo_path\n    return self._store.clone(self._repo, self._sha)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/store.py\", line 119, in clone\n    cmd_output('git', 'checkout', sha)\n  File \"/home/qdm/workspace/web/pre-commit/pre_commit/util.py\", line 160, in cmd_output\n    returncode, cmd, retcode, output=(stdout, stderr),\npre_commit.util.CalledProcessError: Command: ['git', 'checkout', 'd3db0385825d4c082bc7117c090ac16cb4840f3e']\nReturn code: 1\nExpected return code: 0\nOutput: (none)\nErrors: \n    error: Your local changes to the following files would be overwritten by checkout:\n        .pre-commit-config.yaml\n        .travis.yml\n        CHANGELOG\n        README.md\n        hooks.yaml\n        pre_commit_hooks/autopep8_wrapper.py\n        pre_commit_hooks/check_json.py\n        pre_commit_hooks/check_yaml.py\n        pre_commit_hooks/debug_statement_hook.py\n        pre_commit_hooks/end_of_file_fixer.py\n        pre_commit_hooks/tests_should_end_in_test.py\n        pre_commit_hooks/trailing_whitespace_fixer.py\n        pre_commit_hooks/util.py\n        pylintrc\n        requirements-dev.txt\n        setup.py\n        testing/util.py\n        tests/autopep8_wrapper_test.py\n        tests/debug_statement_hook_test.py\n        tests/end_of_file_fixer_test.py\n        tests/tests_should_end_in_test_test.py\n        tests/trailing_whitespace_fixer_test.py\n        tests/util_test.py\n        tox.ini\n    Please, commit your changes or stash them before you can switch branches.\n    Aborting\n```\n\nI think this is a regression from a previous version, it was more seamless then.\n\n", "before_files": [{"content": "from __future__ import unicode_literals\n\nimport contextlib\nimport io\nimport logging\nimport os\nimport os.path\nimport sqlite3\nimport tempfile\n\nfrom cached_property import cached_property\n\nfrom pre_commit.prefixed_command_runner import PrefixedCommandRunner\nfrom pre_commit.util import clean_path_on_failure\nfrom pre_commit.util import cmd_output\nfrom pre_commit.util import cwd\n\n\nlogger = logging.getLogger('pre_commit')\n\n\ndef _get_default_directory():\n    \"\"\"Returns the default directory for the Store.  This is intentionally\n    underscored to indicate that `Store.get_default_directory` is the intended\n    way to get this information.  This is also done so\n    `Store.get_default_directory` can be mocked in tests and\n    `_get_default_directory` can be tested.\n    \"\"\"\n    return os.environ.get(\n        'PRE_COMMIT_HOME',\n        os.path.join(os.path.expanduser('~'), '.pre-commit'),\n    )\n\n\nclass Store(object):\n    get_default_directory = staticmethod(_get_default_directory)\n\n    class RepoPathGetter(object):\n        def __init__(self, repo, sha, store):\n            self._repo = repo\n            self._sha = sha\n            self._store = store\n\n        @cached_property\n        def repo_path(self):\n            return self._store.clone(self._repo, self._sha)\n\n    def __init__(self, directory=None):\n        if directory is None:\n            directory = self.get_default_directory()\n\n        self.directory = directory\n        self.__created = False\n\n    def _write_readme(self):\n        with io.open(os.path.join(self.directory, 'README'), 'w') as readme:\n            readme.write(\n                'This directory is maintained by the pre-commit project.\\n'\n                'Learn more: https://github.com/pre-commit/pre-commit\\n'\n            )\n\n    def _write_sqlite_db(self):\n        # To avoid a race where someone ^Cs between db creation and execution\n        # of the CREATE TABLE statement\n        fd, tmpfile = tempfile.mkstemp(dir=self.directory)\n        # We'll be managing this file ourselves\n        os.close(fd)\n        # sqlite doesn't close its fd with its contextmanager >.<\n        # contextlib.closing fixes this.\n        # See: http://stackoverflow.com/a/28032829/812183\n        with contextlib.closing(sqlite3.connect(tmpfile)) as db:\n            db.executescript(\n                'CREATE TABLE repos ('\n                '    repo CHAR(255) NOT NULL,'\n                '    ref CHAR(255) NOT NULL,'\n                '    path CHAR(255) NOT NULL,'\n                '    PRIMARY KEY (repo, ref)'\n                ');'\n            )\n\n        # Atomic file move\n        os.rename(tmpfile, self.db_path)\n\n    def _create(self):\n        if os.path.exists(self.db_path):\n            return\n        if not os.path.exists(self.directory):\n            os.makedirs(self.directory)\n            self._write_readme()\n        self._write_sqlite_db()\n\n    def require_created(self):\n        \"\"\"Require the pre-commit file store to be created.\"\"\"\n        if self.__created:\n            return\n\n        self._create()\n        self.__created = True\n\n    def clone(self, url, sha):\n        \"\"\"Clone the given url and checkout the specific sha.\"\"\"\n        self.require_created()\n\n        # Check if we already exist\n        with sqlite3.connect(self.db_path) as db:\n            result = db.execute(\n                'SELECT path FROM repos WHERE repo = ? AND ref = ?',\n                [url, sha],\n            ).fetchone()\n            if result:\n                return result[0]\n\n        logger.info('Initializing environment for {0}.'.format(url))\n\n        dir = tempfile.mkdtemp(prefix='repo', dir=self.directory)\n        with clean_path_on_failure(dir):\n            cmd_output('git', 'clone', '--no-checkout', url, dir)\n            with cwd(dir):\n                cmd_output('git', 'checkout', sha)\n\n        # Update our db with the created repo\n        with sqlite3.connect(self.db_path) as db:\n            db.execute(\n                'INSERT INTO repos (repo, ref, path) VALUES (?, ?, ?)',\n                [url, sha, dir],\n            )\n        return dir\n\n    def get_repo_path_getter(self, repo, sha):\n        return self.RepoPathGetter(repo, sha, self)\n\n    @cached_property\n    def cmd_runner(self):\n        return PrefixedCommandRunner(self.directory)\n\n    @cached_property\n    def db_path(self):\n        return os.path.join(self.directory, 'db.db')\n", "path": "pre_commit/store.py"}], "after_files": [{"content": "from __future__ import unicode_literals\n\nimport contextlib\nimport io\nimport logging\nimport os\nimport os.path\nimport sqlite3\nimport tempfile\n\nfrom cached_property import cached_property\n\nfrom pre_commit.prefixed_command_runner import PrefixedCommandRunner\nfrom pre_commit.util import clean_path_on_failure\nfrom pre_commit.util import cmd_output\nfrom pre_commit.util import cwd\n\n\nlogger = logging.getLogger('pre_commit')\n\n\ndef _get_default_directory():\n    \"\"\"Returns the default directory for the Store.  This is intentionally\n    underscored to indicate that `Store.get_default_directory` is the intended\n    way to get this information.  This is also done so\n    `Store.get_default_directory` can be mocked in tests and\n    `_get_default_directory` can be tested.\n    \"\"\"\n    return os.environ.get(\n        'PRE_COMMIT_HOME',\n        os.path.join(os.path.expanduser('~'), '.pre-commit'),\n    )\n\n\nclass Store(object):\n    get_default_directory = staticmethod(_get_default_directory)\n\n    class RepoPathGetter(object):\n        def __init__(self, repo, sha, store):\n            self._repo = repo\n            self._sha = sha\n            self._store = store\n\n        @cached_property\n        def repo_path(self):\n            return self._store.clone(self._repo, self._sha)\n\n    def __init__(self, directory=None):\n        if directory is None:\n            directory = self.get_default_directory()\n\n        self.directory = directory\n        self.__created = False\n\n    def _write_readme(self):\n        with io.open(os.path.join(self.directory, 'README'), 'w') as readme:\n            readme.write(\n                'This directory is maintained by the pre-commit project.\\n'\n                'Learn more: https://github.com/pre-commit/pre-commit\\n'\n            )\n\n    def _write_sqlite_db(self):\n        # To avoid a race where someone ^Cs between db creation and execution\n        # of the CREATE TABLE statement\n        fd, tmpfile = tempfile.mkstemp(dir=self.directory)\n        # We'll be managing this file ourselves\n        os.close(fd)\n        # sqlite doesn't close its fd with its contextmanager >.<\n        # contextlib.closing fixes this.\n        # See: http://stackoverflow.com/a/28032829/812183\n        with contextlib.closing(sqlite3.connect(tmpfile)) as db:\n            db.executescript(\n                'CREATE TABLE repos ('\n                '    repo CHAR(255) NOT NULL,'\n                '    ref CHAR(255) NOT NULL,'\n                '    path CHAR(255) NOT NULL,'\n                '    PRIMARY KEY (repo, ref)'\n                ');'\n            )\n\n        # Atomic file move\n        os.rename(tmpfile, self.db_path)\n\n    def _create(self):\n        if os.path.exists(self.db_path):\n            return\n        if not os.path.exists(self.directory):\n            os.makedirs(self.directory)\n            self._write_readme()\n        self._write_sqlite_db()\n\n    def require_created(self):\n        \"\"\"Require the pre-commit file store to be created.\"\"\"\n        if self.__created:\n            return\n\n        self._create()\n        self.__created = True\n\n    def clone(self, url, sha):\n        \"\"\"Clone the given url and checkout the specific sha.\"\"\"\n        self.require_created()\n\n        # Check if we already exist\n        with sqlite3.connect(self.db_path) as db:\n            result = db.execute(\n                'SELECT path FROM repos WHERE repo = ? AND ref = ?',\n                [url, sha],\n            ).fetchone()\n            if result:\n                return result[0]\n\n        logger.info('Initializing environment for {0}.'.format(url))\n\n        dir = tempfile.mkdtemp(prefix='repo', dir=self.directory)\n        with clean_path_on_failure(dir):\n            cmd_output('git', 'clone', '--no-checkout', url, dir)\n            with cwd(dir):\n                cmd_output('git', 'reset', sha, '--hard')\n\n        # Update our db with the created repo\n        with sqlite3.connect(self.db_path) as db:\n            db.execute(\n                'INSERT INTO repos (repo, ref, path) VALUES (?, ?, ?)',\n                [url, sha, dir],\n            )\n        return dir\n\n    def get_repo_path_getter(self, repo, sha):\n        return self.RepoPathGetter(repo, sha, self)\n\n    @cached_property\n    def cmd_runner(self):\n        return PrefixedCommandRunner(self.directory)\n\n    @cached_property\n    def db_path(self):\n        return os.path.join(self.directory, 'db.db')\n", "path": "pre_commit/store.py"}]}