internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: pre-commit/pre-commit

Issue:
Newly gitignored (but file still exists) files are linted
(they should not be)



Discussion:

Resolving patch:
diff --git a/pre_commit/git.py b/pre_commit/git.py
--- a/pre_commit/git.py
+++ b/pre_commit/git.py
@@ -69,7 +69,11 @@ def get_conflicted_files():
 
 @memoize_by_cwd
 def get_staged_files():
-    return cmd_output('git', 'diff', '--staged', '--name-only')[1].splitlines()
+    return cmd_output(
+        'git', 'diff', '--staged', '--name-only',
+        # Everything except for D
+        '--diff-filter=ACMRTUXB'
+    )[1].splitlines()
 
 
 @memoize_by_cwd


Test patch:
diff --git a/tests/git_test.py b/tests/git_test.py
--- a/tests/git_test.py
+++ b/tests/git_test.py
@@ -33,6 +33,16 @@ def test_get_root_not_git_dir(tempdir_factory):
             git.get_root()
 
 
+def test_get_staged_files_deleted(tempdir_factory):
+    path = git_dir(tempdir_factory)
+    with cwd(path):
+        open('test', 'a').close()
+        cmd_output('git', 'add', 'test')
+        cmd_output('git', 'commit', '-m', 'foo', '--allow-empty')
+        cmd_output('git', 'rm', '--cached', 'test')
+        assert git.get_staged_files() == []
+
+
 def test_is_not_in_merge_conflict(tempdir_factory):
     path = git_dir(tempdir_factory)
     with cwd(path):
Repository: pre-commit/pre-commit

Issue:
do not recommend `pre-commit autoupdate` on failure of `pre-commit autoupdate` 
It would be preferable to recommend something that has chance of fixing the problem

instruction to reproduce in #385



Discussion:
So `autoupdate` is  useful to get you into a working state, however the directions should be:
- Remove the hook, run autoupdate, and add the hook back.

See also: https://github.com/pre-commit/pre-commit/pull/368#issue-153987791


Resolving patch:
diff --git a/pre_commit/repository.py b/pre_commit/repository.py
--- a/pre_commit/repository.py
+++ b/pre_commit/repository.py
@@ -78,7 +78,9 @@ def hooks(self):
                 logger.error(
                     '`{0}` is not present in repository {1}.  '
                     'Typo? Perhaps it is introduced in a newer version?  '
-                    'Often `pre-commit autoupdate` fixes this.'.format(
+                    'Often you can fix this by removing the hook, running '
+                    '`pre-commit autoupdate`, '
+                    'and then adding the hook.'.format(
                         hook['id'], self.repo_config['repo'],
                     )
                 )


Test patch:
diff --git a/tests/repository_test.py b/tests/repository_test.py
--- a/tests/repository_test.py
+++ b/tests/repository_test.py
@@ -556,7 +556,9 @@ def test_hook_id_not_present(tempdir_factory, store, fake_log_handler):
     assert fake_log_handler.handle.call_args[0][0].msg == (
         '`i-dont-exist` is not present in repository {0}.  '
         'Typo? Perhaps it is introduced in a newer version?  '
-        'Often `pre-commit autoupdate` fixes this.'.format(path)
+        'Often you can fix this by removing the hook, '
+        'running `pre-commit autoupdate`, '
+        'and then adding the hook.'.format(path)
     )
Repository: pre-commit/pre-commit

Issue:
Warn when mismatching cygwin git/python
See #352 and #353 for how this can manifest itself



Discussion:
- cygwin python can be detected using `sys.platform == 'cygwin'`
- cygwin git can be detected using `check_output(('git', 'rev-parse', '--show-toplevel')).decode('UTF-8').startswith('/')` (maybe there's a better way?)

I think the code that would need to be added to verify this is:

```python
if sys.platform in ('win32', 'cygwin'):  # pragma no cover (windows only)
    is_cygwin_python = sys.platform == 'cygwin'
    is_cygwin_git = cmd_output('git', 'rev-parse', '--show-toplevel')[1].startswith('/')

    if is_cygwin_python ^ is_cygwin_git:
        logger.warn(...)
```


Resolving patch:
diff --git a/pre_commit/git.py b/pre_commit/git.py
--- a/pre_commit/git.py
+++ b/pre_commit/git.py
@@ -4,6 +4,7 @@
 import logging
 import os.path
 import re
+import sys
 
 from pre_commit.errors import FatalError
 from pre_commit.util import CalledProcessError
@@ -102,3 +103,26 @@ def wrapper(include_expr, exclude_expr):
 get_staged_files_matching = get_files_matching(get_staged_files)
 get_all_files_matching = get_files_matching(get_all_files)
 get_conflicted_files_matching = get_files_matching(get_conflicted_files)
+
+
+def check_for_cygwin_mismatch():
+    """See https://github.com/pre-commit/pre-commit/issues/354"""
+    if sys.platform in ('cygwin', 'win32'):  # pragma: no cover (windows)
+        is_cygwin_python = sys.platform == 'cygwin'
+        toplevel = cmd_output('git', 'rev-parse', '--show-toplevel')[1]
+        is_cygwin_git = toplevel.startswith('/')
+
+        if is_cygwin_python ^ is_cygwin_git:
+            exe_type = {True: '(cygwin)', False: '(windows)'}
+            logger.warn(
+                'pre-commit has detected a mix of cygwin python / git\n'
+                'This combination is not supported, it is likely you will '
+                'receive an error later in the program.\n'
+                'Make sure to use cygwin git+python while using cygwin\n'
+                'These can be installed through the cygwin installer.\n'
+                ' - python {}\n'
+                ' - git {}\n'.format(
+                    exe_type[is_cygwin_python],
+                    exe_type[is_cygwin_git],
+                )
+            )
diff --git a/pre_commit/main.py b/pre_commit/main.py
--- a/pre_commit/main.py
+++ b/pre_commit/main.py
@@ -152,6 +152,7 @@ def main(argv=None):
 
     with error_handler():
         add_logging_handler(args.color)
+        git.check_for_cygwin_mismatch()
         runner = Runner.create()
 
         if args.command == 'install':


Test patch:
Repository: pre-commit/pre-commit

Issue:
cygwin python checking should happen after setup code
Regressed as part of #436

Before:

```
$ ./pre-commit/venv_cygwin_python/bin/pre-commit clean
An error has occurred: FatalError: git failed. Is it installed, and are you in a Git repository directory?
Check the log at ~/.pre-commit/pre-commit.log
```

Current master:

```
$ ./pre-commit/venv_cygwin_python/bin/pre-commit clean
An unexpected error has occurred: CalledProcessError: Command: ('/usr/bin/git', 'rev-parse', '--show-toplevel')
Return code: 128
Expected return code: 0
Output: (none)
Errors:
    fatal: Not a git repository (or any of the parent directories): .git


Check the log at ~/.pre-commit/pre-commit.log
```


Discussion:

Resolving patch:
diff --git a/pre_commit/main.py b/pre_commit/main.py
--- a/pre_commit/main.py
+++ b/pre_commit/main.py
@@ -152,8 +152,8 @@ def main(argv=None):
 
     with error_handler():
         add_logging_handler(args.color)
-        git.check_for_cygwin_mismatch()
         runner = Runner.create()
+        git.check_for_cygwin_mismatch()
 
         if args.command == 'install':
             return install(


Test patch:
diff --git a/tests/main_test.py b/tests/main_test.py
--- a/tests/main_test.py
+++ b/tests/main_test.py
@@ -7,6 +7,7 @@
 import pytest
 
 from pre_commit import main
+from pre_commit.error_handler import PreCommitSystemExit
 from pre_commit.util import cwd
 from testing.auto_namedtuple import auto_namedtuple
 
@@ -142,3 +143,16 @@ def test_help_cmd_in_empty_directory(
         mock.call(['help', 'run']),
         mock.call(['run', '--help']),
     ])
+
+
+def test_expected_fatal_error_no_git_repo(
+        tempdir_factory, cap_out, mock_out_store_directory,
+):
+    with cwd(tempdir_factory.get()):
+        with pytest.raises(PreCommitSystemExit):
+            main.main([])
+    assert cap_out.get() == (
+        'An error has occurred: FatalError: git failed. '
+        'Is it installed, and are you in a Git repository directory?\n'
+        'Check the log at ~/.pre-commit/pre-commit.log\n'
+    )
Repository: pre-commit/pre-commit

Issue:
`docker build` argument order is invalid on old versions of Docker
We do: `docker build . --tag thing --label thing`

But this produces an error on Docker 1.11.2:
```
ckuehl@dev4-uswest1cdevc:~/proj/pre-commit$ docker build . --tag thing --label thing
docker: "build" requires 1 argument.
See 'docker build --help'.

Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile
```

The path needs to go at the end on 1.11.2, but it works on 1.13.0 as-is. We should probably just change the order of the arguments to make every version happy.


Discussion:

Resolving patch:
diff --git a/pre_commit/languages/docker.py b/pre_commit/languages/docker.py
--- a/pre_commit/languages/docker.py
+++ b/pre_commit/languages/docker.py
@@ -43,12 +43,14 @@ def build_docker_image(repo_cmd_runner, **kwargs):  # pragma: windows no cover
     pull = kwargs.pop('pull')
     assert not kwargs, kwargs
     cmd = (
-        'docker', 'build', '.',
+        'docker', 'build',
         '--tag', docker_tag(repo_cmd_runner),
         '--label', PRE_COMMIT_LABEL,
     )
     if pull:
         cmd += ('--pull',)
+    # This must come last for old versions of docker.  See #477
+    cmd += ('.',)
     helpers.run_setup_cmd(repo_cmd_runner, cmd)
 
 


Test patch:
Repository: pre-commit/pre-commit

Issue:
Encode some sort of "version" for language-local repositories
Without this, they'll never get upgraded if fixes are made in the pre-commit empty template


Discussion:

Resolving patch:
diff --git a/pre_commit/constants.py b/pre_commit/constants.py
--- a/pre_commit/constants.py
+++ b/pre_commit/constants.py
@@ -17,6 +17,8 @@
 
 # Bump when installation changes in a backwards / forwards incompatible way
 INSTALLED_STATE_VERSION = '1'
+# Bump when modifying `empty_template`
+LOCAL_REPO_VERSION = '1'
 
 VERSION = pkg_resources.get_distribution('pre-commit').version
 VERSION_PARSED = pkg_resources.parse_version(VERSION)
diff --git a/pre_commit/store.py b/pre_commit/store.py
--- a/pre_commit/store.py
+++ b/pre_commit/store.py
@@ -9,6 +9,7 @@
 
 from cached_property import cached_property
 
+import pre_commit.constants as C
 from pre_commit.prefixed_command_runner import PrefixedCommandRunner
 from pre_commit.util import clean_path_on_failure
 from pre_commit.util import cmd_output
@@ -129,7 +130,7 @@ def make_local(self, deps):
         def make_local_strategy(directory):
             copy_tree_to_path(resource_filename('empty_template'), directory)
         return self._new_repo(
-            'local:{}'.format(','.join(sorted(deps))), 'N/A',
+            'local:{}'.format(','.join(sorted(deps))), C.LOCAL_REPO_VERSION,
             make_local_strategy,
         )
 


Test patch:
Repository: pre-commit/pre-commit

Issue:
Windows: Color support
On unixlike platforms we support coloring via ANSI escapes.  Windows supports coloring somehow, figure out how that works and implement it.



Discussion:

Resolving patch:
diff --git a/pre_commit/color.py b/pre_commit/color.py
--- a/pre_commit/color.py
+++ b/pre_commit/color.py
@@ -1,7 +1,15 @@
 from __future__ import unicode_literals
 
+import os
 import sys
 
+if os.name == 'nt':  # pragma: no cover (windows)
+    from pre_commit.color_windows import enable_virtual_terminal_processing
+    try:
+        enable_virtual_terminal_processing()
+    except WindowsError:
+        pass
+
 RED = '\033[41m'
 GREEN = '\033[42m'
 YELLOW = '\033[43;30m'
diff --git a/pre_commit/color_windows.py b/pre_commit/color_windows.py
new file mode 100644
--- /dev/null
+++ b/pre_commit/color_windows.py
@@ -0,0 +1,49 @@
+from __future__ import unicode_literals
+
+from ctypes import POINTER
+from ctypes import windll
+from ctypes import WinError
+from ctypes import WINFUNCTYPE
+from ctypes.wintypes import BOOL
+from ctypes.wintypes import DWORD
+from ctypes.wintypes import HANDLE
+
+STD_OUTPUT_HANDLE = -11
+ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4
+
+
+def bool_errcheck(result, func, args):
+    if not result:
+        raise WinError()
+    return args
+
+
+GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)(
+    ("GetStdHandle", windll.kernel32),
+    ((1, "nStdHandle"), )
+)
+
+GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))(
+    ("GetConsoleMode", windll.kernel32),
+    ((1, "hConsoleHandle"), (2, "lpMode"))
+)
+GetConsoleMode.errcheck = bool_errcheck
+
+SetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, DWORD)(
+    ("SetConsoleMode", windll.kernel32),
+    ((1, "hConsoleHandle"), (1, "dwMode"))
+)
+SetConsoleMode.errcheck = bool_errcheck
+
+
+def enable_virtual_terminal_processing():
+    """As of Windows 10, the Windows console supports (some) ANSI escape
+    sequences, but it needs to be enabled using `SetConsoleMode` first.
+
+    More info on the escape sequences supported:
+    https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx
+
+    """
+    stdout = GetStdHandle(STD_OUTPUT_HANDLE)
+    flags = GetConsoleMode(stdout)
+    SetConsoleMode(stdout, flags | ENABLE_VIRTUAL_TERMINAL_PROCESSING)


Test patch:
Repository: pre-commit/pre-commit

Issue:
always_run + no `files` still crashes on `KeyError: files`
I was under the impression `files` was completely ignored for `always_run`, I guess not!

Here's a small reproduction:

```yaml
-   repo: local
    hooks:
    -   id: foo
        name: foo
        always_run: true
        entry: bash -c 'echo hello && exit 1'
        language: system
```

```
$ ./venv-pre_commit/bin/pre-commit run foo
An unexpected error has occurred: KeyError: u'files'
Check the log at ~/.pre-commit/pre-commit.log
```

```
$ cat ~/.pre-commit/pre-commit.log 
An unexpected error has occurred: KeyError: u'files'
Traceback (most recent call last):
  File "/tmp/foo/pre-commit/pre_commit/error_handler.py", line 48, in error_handler
    yield
  File "/tmp/foo/pre-commit/pre_commit/main.py", line 226, in main
    return run(runner, args)
  File "/tmp/foo/pre-commit/pre_commit/commands/run.py", line 235, in run
    return _run_hooks(repo_hooks, args, environ)
  File "/tmp/foo/pre-commit/pre_commit/commands/run.py", line 155, in _run_hooks
    retval |= _run_single_hook(hook, repo, args, skips, cols)
  File "/tmp/foo/pre-commit/pre_commit/commands/run.py", line 60, in _run_single_hook
    filenames = get_filenames(args, hook['files'], hook['exclude'])
KeyError: u'files'
```



Discussion:

Resolving patch:
diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py
--- a/pre_commit/commands/run.py
+++ b/pre_commit/commands/run.py
@@ -57,7 +57,7 @@ def get_filenames(args, include_expr, exclude_expr):
 
 
 def _run_single_hook(hook, repo, args, skips, cols):
-    filenames = get_filenames(args, hook['files'], hook['exclude'])
+    filenames = get_filenames(args, hook.get('files', ''), hook['exclude'])
     if hook['id'] in skips:
         output.write(get_hook_message(
             _hook_msg_start(hook, args.verbose),


Test patch:
Repository: pre-commit/pre-commit

Issue:
Unstaged files + never ran pre-commit => "No such file or directory: .../.cache/pre-commit/patch..."
```
$ pre-commit run
[WARNING] Unstaged files detected.
[INFO] Stashing unstaged files to /home/asottile/.cache/pre-commit/patch1505686307.
An unexpected error has occurred: IOError: [Errno 2] No such file or directory: '/home/asottile/.cache/pre-commit/patch1505686307'
Check the log at /home/asottile/.cache/pre-commit/pre-commit.log
```

Stacktrace:

```python
Traceback (most recent call last):
  File "/home/asottile/workspace/pre-commit/pre_commit/error_handler.py", line 44, in error_handler
    yield
  File "/home/asottile/workspace/pre-commit/pre_commit/main.py", line 231, in main
    return run(runner, args)
  File "/home/asottile/workspace/pre-commit/pre_commit/commands/run.py", line 249, in run
    with ctx:
  File "/usr/lib/python2.7/contextlib.py", line 17, in __enter__
    return self.gen.next()
  File "/home/asottile/workspace/pre-commit/pre_commit/staged_files_only.py", line 46, in staged_files_only
    with io.open(patch_filename, 'wb') as patch_file:
IOError: [Errno 2] No such file or directory: '/home/asottile/.cache/pre-commit/patch1505686307'
```


Discussion:
Originally from #620

Resolving patch:
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
@@ -8,6 +8,7 @@
 
 from pre_commit.util import CalledProcessError
 from pre_commit.util import cmd_output
+from pre_commit.util import mkdirp
 
 
 logger = logging.getLogger('pre_commit')
@@ -43,6 +44,7 @@ def staged_files_only(patch_dir):
             'Stashing unstaged files to {}.'.format(patch_filename),
         )
         # Save the current unstaged changes as a patch
+        mkdirp(patch_dir)
         with io.open(patch_filename, 'wb') as patch_file:
             patch_file.write(diff_stdout_binary)
 


Test patch:
diff --git a/tests/staged_files_only_test.py b/tests/staged_files_only_test.py
--- a/tests/staged_files_only_test.py
+++ b/tests/staged_files_only_test.py
@@ -75,6 +75,15 @@ def test_foo_something_unstaged(foo_staged, patch_dir):
     _test_foo_state(foo_staged, 'herp\nderp\n', 'AM')
 
 
+def test_does_not_crash_patch_dir_does_not_exist(foo_staged, patch_dir):
+    with io.open(foo_staged.foo_filename, 'w') as foo_file:
+        foo_file.write('hello\nworld\n')
+
+    shutil.rmtree(patch_dir)
+    with staged_files_only(patch_dir):
+        pass
+
+
 def test_something_unstaged_ext_diff_tool(foo_staged, patch_dir, tmpdir):
     diff_tool = tmpdir.join('diff-tool.sh')
     diff_tool.write('#!/usr/bin/env bash\necho "$@"\n')
Repository: pre-commit/pre-commit

Issue:
commit-msg stage does not work
Everything works as expected when running just `pre-commit install`, then hooks work.
But when running `pre-commit install -t commit-msg` `IOError` happens, since template could not be found.

Here's the detailed information.

## Env

- `python2.7`
- `pipenv 7.3.7`
- `pre-commit 1.1.1`

Actually tested with both `python2` and `python3`.

## Configuration

```yaml
- repo: local
  hooks:
    - id: gitlint
      name: gitlint
      entry: "bash -c 'gitlint lint'"
      language: system
      stages: [commit-msg]

    - id: pytest
      name: pytest
      entry: "bash -c 'python manage.py test'"
      language: system

    - id: safety
      name: safety
      entry: "bash -c 'safety check'"
      language: system
```

## Output

```
» pre-commit install -t commit-msg
Running in migration mode with existing hooks at /Users/sobolev/Desktop/test/.git/hooks/commit-msg.legacy
Use -f to use only pre-commit.
An unexpected error has occurred: IOError: [Errno 2] No such file or directory: '/Users/sobolev/.virtualenvs/test-p4WySO70/lib/python2.7/site-packages/pre_commit/resources/commit-msg-tmpl'
Check the log at /Users/sobolev/.cache/pre-commit/pre-commit.log
```

When I do `ls /Users/sobolev/.virtualenvs/test-p4WySO70/lib/python2.7/site-packages/pre_commit/resources/commit-msg-tmpl`  that's what is see:

```
(test-p4WySO70) ~/Desktop/test  master ✗                                  ✚ 2 ⚡
» ls /Users/sobolev/.virtualenvs/test-p4WySO70/lib/python2.7/site-packages/pre_commit/resources                
empty_template  pre-push-tmpl  ruby-build.tar.gz
hook-tmpl       rbenv.tar.gz   ruby-download.tar.gz
```


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -29,11 +29,7 @@
     packages=find_packages(exclude=('tests*', 'testing*')),
     package_data={
         'pre_commit': [
-            'resources/hook-tmpl',
-            'resources/pre-push-tmpl',
-            'resources/rbenv.tar.gz',
-            'resources/ruby-build.tar.gz',
-            'resources/ruby-download.tar.gz',
+            'resources/*',
             'resources/empty_template/*',
             'resources/empty_template/.npmignore',
         ],


Test patch:
Repository: pre-commit/pre-commit

Issue:
Autoupdate, select, multiple repositories
Brought up from #657

As noted by @asottile, we can do

`pre-commit autoupdate --repo repo1 --repo repo2 --repo repo3`

to update multiple repositories.

That can be implemented pretty easily with `action='append'` -- and changing the same parts as #657


Discussion:

Resolving patch:
diff --git a/pre_commit/commands/autoupdate.py b/pre_commit/commands/autoupdate.py
--- a/pre_commit/commands/autoupdate.py
+++ b/pre_commit/commands/autoupdate.py
@@ -106,7 +106,7 @@ def _write_new_config_file(path, output):
         f.write(to_write)
 
 
-def autoupdate(runner, tags_only, repo=None):
+def autoupdate(runner, tags_only, repos=()):
     """Auto-update the pre-commit config to the latest versions of repos."""
     migrate_config(runner, quiet=True)
     retv = 0
@@ -120,7 +120,7 @@ def autoupdate(runner, tags_only, repo=None):
             is_local_repo(repo_config) or
             is_meta_repo(repo_config) or
             # Skip updating any repo_configs that aren't for the specified repo
-            repo and repo != repo_config['repo']
+            repos and repo_config['repo'] not in repos
         ):
             output_repos.append(repo_config)
             continue
diff --git a/pre_commit/main.py b/pre_commit/main.py
--- a/pre_commit/main.py
+++ b/pre_commit/main.py
@@ -168,7 +168,8 @@ def main(argv=None):
         ),
     )
     autoupdate_parser.add_argument(
-        '--repo', help='Only update this repository.',
+        '--repo', dest='repos', action='append', metavar='REPO',
+        help='Only update this repository -- may be specified multiple times.',
     )
 
     migrate_config_parser = subparsers.add_parser(
@@ -251,7 +252,7 @@ def main(argv=None):
             return autoupdate(
                 runner,
                 tags_only=not args.bleeding_edge,
-                repo=args.repo,
+                repos=args.repos,
             )
         elif args.command == 'migrate-config':
             return migrate_config(runner)


Test patch:
diff --git a/tests/commands/autoupdate_test.py b/tests/commands/autoupdate_test.py
--- a/tests/commands/autoupdate_test.py
+++ b/tests/commands/autoupdate_test.py
@@ -138,7 +138,7 @@ def test_autoupdate_out_of_date_repo_with_correct_repo_name(
     runner = Runner('.', C.CONFIG_FILE)
     before = open(C.CONFIG_FILE).read()
     repo_name = 'file://{}'.format(out_of_date_repo.path)
-    ret = autoupdate(runner, tags_only=False, repo=repo_name)
+    ret = autoupdate(runner, tags_only=False, repos=(repo_name,))
     after = open(C.CONFIG_FILE).read()
     assert ret == 0
     assert before != after
@@ -158,7 +158,7 @@ def test_autoupdate_out_of_date_repo_with_wrong_repo_name(
     runner = Runner('.', C.CONFIG_FILE)
     before = open(C.CONFIG_FILE).read()
     # It will not update it, because the name doesn't match
-    ret = autoupdate(runner, tags_only=False, repo='wrong_repo_name')
+    ret = autoupdate(runner, tags_only=False, repos=('wrong_repo_name',))
     after = open(C.CONFIG_FILE).read()
     assert ret == 0
     assert before == after