Repository: pre-commit/pre-commit

Issue:
[WinError 123] The syntax for filename, directory name, or volume label is incorrect: ''
I try to install pre-commit with the manual from [pre-commit.com](pre-commit.com).

At step 3 I get the following error message on a Windows 10 machine:

`[WinError 123] The syntax for filename, directory name, or volume label is incorrect: ''`

---

**.pre-commit-config.yaml**
```
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
-   repo: https://server/Sandbox/Repo/_git/Repo
    rev: v2.4.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
    -   id: check-added-large-files
```

---

### error information

```
An unexpected error has occurred: OSError: [WinError 123] Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch: ''
```

```
Traceback (most recent call last):
  File "c:\user\programme\python\python37-32\lib\site-packages\pre_commit\error_handler.py", line 72, in error_handler
    yield
  File "c:\user\programme\python\python37-32\lib\site-packages\pre_commit\main.py", line 294, in main
    _adjust_args_and_chdir(args)
  File "c:\user\programme\python\python37-32\lib\site-packages\pre_commit\main.py", line 125, in _adjust_args_and_chdir
    os.chdir(git.get_root())
OSError: [WinError 123] Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch: ''
```

---

--version
Python 3.7.3
pre-commit 1.20.0



Discussion:
This looks like your `git` is broken, what does the following say:

```bash
which -a git
git rev-parse --show-toplevel
```

you should get something like

```console
asott@asottile-laptop MINGW64 ~/workspace/pre-commit (master)
$ which -a git
/mingw64/bin/git
/mingw64/bin/git
/cmd/git
/mingw64/bin/git

asott@asottile-laptop MINGW64 ~/workspace/pre-commit (master)
$ git rev-parse --show-toplevel
C:/Users/asott/workspace/pre-commit
```

Also could you please include the command you ran, the full unedited output, and the contents of the log file it mentions?
Sorry I forget to mention. 

```
$ which -a git
/mingw64/bin/git
/mingw64/bin/git
/cmd/git
```

```
$ git rev-parse --show-toplevel
C:/Users/user/Desktop/Sandbox/Repo
```

---

## Command

```
pre-commit install
```

---

## Output

```
An unexpected error has occurred: OSError: [WinError 123] Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch: ''
Check the log at C:\Users\user/.cache\pre-commit\pre-commit.log
```

---

## Log File

### version information

```
pre-commit version: 1.20.0
sys.version:
    3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)]
sys.executable: c:\user\programme\python\python37-32\python.exe
os.name: nt
sys.platform: win32
```

### error information

```
An unexpected error has occurred: OSError: [WinError 123] Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch: ''
```

```
Traceback (most recent call last):
  File "c:\user\programme\python\python37-32\lib\site-packages\pre_commit\error_handler.py", line 72, in error_handler
    yield
  File "c:\user\programme\python\python37-32\lib\site-packages\pre_commit\main.py", line 294, in main
    _adjust_args_and_chdir(args)
  File "c:\user\programme\python\python37-32\lib\site-packages\pre_commit\main.py", line 125, in _adjust_args_and_chdir
    os.chdir(git.get_root())
OSError: [WinError 123] Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch: ''

```
that's very strange!  from the trace it looks like the same command being called from python is returning 0 but not printing the git root -- can you try a few more things for me?

```bash
python -c "from pre_commit.util import cmd_output; print(cmd_output('git', 'rev-parse', '--show-toplevel'))"
```

For me it produces something like:

```console
$ python -c "from pre_commit.util import cmd_output; print(cmd_output('git', 'rev-parse', '--show-toplevel'))"
(0, 'C:/Users/asott/AppData/Local/Temp/astpretty\n', '')
```
### Input

```
python -c "from pre_commit.util import cmd_output; print(cmd_output('git', 'rev-parse', '--show-toplevel'))"
```

### Output

```
(0, '', '')
```
How about this one?

```bash
python -c "from pre_commit.parse_shebang import find_executable; print(find_executable('git'))"
```

```console
$ python -c "from pre_commit.parse_shebang import find_executable; print(find_executable('git'))"
C:\Program Files\Git\mingw64\bin\git.exe
```
### Input

```
python -c "from pre_commit.parse_shebang import find_executable; print(find_executable('git'))"
```

### Output

```
C:\Username\Programme\Git\cmd\git.exe
```

(custom path)
what happens if you run the `rev-parse --show-toplevel` command with that executable?
### Input

```
C:\Username\Programme\Git\cmd\git.exe rev-parse --show-toplevel
```

### Output

```
"" (null)
```
that seems to be the problem then!  could you try reinstalling `git` maybe?
@asottile I reinstall git, when I execute `pre-commit install` inside `Repo\.git\hooks` (where `.pre-commit-config.yaml` stored) I still get `null` as output when I execute `git rev-parse --show-toplevel`.

If I excute `git rev-parse --show-toplevel` in `Repo` it returns `C:/Users/user/Desktop/Sandbox/Repo`. Does this change something?
the pre-commit configuration should be inside the root of your repository (also where you'll run `pre-commit install` from) -- does that change things?

oh wow I just tried this, `git` is the wackiest thing!?

Resolving patch:
diff --git a/pre_commit/main.py b/pre_commit/main.py
--- a/pre_commit/main.py
+++ b/pre_commit/main.py
@@ -122,12 +122,20 @@ def _adjust_args_and_chdir(args):
         args.repo = os.path.abspath(args.repo)
 
     try:
-        os.chdir(git.get_root())
+        toplevel = git.get_root()
     except CalledProcessError:
         raise FatalError(
             'git failed. Is it installed, and are you in a Git repository '
             'directory?',
         )
+    else:
+        if toplevel == '':
+            raise FatalError(
+                'git toplevel unexpectedly empty! make sure you are not '
+                'inside the `.git` directory of your repository.',
+            )
+        else:
+            os.chdir(toplevel)
 
     args.config = os.path.relpath(args.config)
     if args.command in {'run', 'try-repo'}:


Test patch:
diff --git a/tests/main_test.py b/tests/main_test.py
--- a/tests/main_test.py
+++ b/tests/main_test.py
@@ -39,6 +39,11 @@ def test_adjust_args_and_chdir_not_in_git_dir(in_tmpdir):
         main._adjust_args_and_chdir(Args())
 
 
+def test_adjust_args_and_chdir_in_dot_git_dir(in_git_dir):
+    with in_git_dir.join('.git').as_cwd(), pytest.raises(FatalError):
+        main._adjust_args_and_chdir(Args())
+
+
 def test_adjust_args_and_chdir_noop(in_git_dir):
     args = Args(command='run', files=['f1', 'f2'])
     main._adjust_args_and_chdir(args)