# Path: pre_commit/errors.py
# class FatalError(RuntimeError):
#     pass
# 
# Path: pre_commit/util.py
# class CalledProcessError(RuntimeError):
#     def __init__(
#             self,
#             returncode: int,
#             cmd: tuple[str, ...],
#             expected_returncode: int,
#             stdout: bytes,
#             stderr: bytes | None,
#     ) -> None:
#         super().__init__(returncode, cmd, expected_returncode, stdout, stderr)
#         self.returncode = returncode
#         self.cmd = cmd
#         self.expected_returncode = expected_returncode
#         self.stdout = stdout
#         self.stderr = stderr
# 
#     def __bytes__(self) -> bytes:
#         def _indent_or_none(part: bytes | None) -> bytes:
#             if part:
#                 return b'\n    ' + part.replace(b'\n', b'\n    ')
#             else:
#                 return b' (none)'
# 
#         return b''.join((
#             f'command: {self.cmd!r}\n'.encode(),
#             f'return code: {self.returncode}\n'.encode(),
#             f'expected return code: {self.expected_returncode}\n'.encode(),
#             b'stdout:', _indent_or_none(self.stdout), b'\n',
#             b'stderr:', _indent_or_none(self.stderr),
#         ))
# 
#     def __str__(self) -> str:
#         return self.__bytes__().decode()
# 
# Path: pre_commit/util.py
# def cmd_output(*cmd: str, **kwargs: Any) -> tuple[int, str, str | None]:
#     returncode, stdout_b, stderr_b = cmd_output_b(*cmd, **kwargs)
#     stdout = stdout_b.decode() if stdout_b is not None else None
#     stderr = stderr_b.decode() if stderr_b is not None else None
#     return returncode, stdout, stderr
# 
# Path: pre_commit/util.py
# def cmd_output_b(
#         *cmd: str,
#         retcode: int | None = 0,
#         **kwargs: Any,
# ) -> tuple[int, bytes, bytes | None]:
#     _setdefault_kwargs(kwargs)
# 
#     try:
#         cmd = parse_shebang.normalize_cmd(cmd)
#     except parse_shebang.ExecutableNotFoundError as e:
#         returncode, stdout_b, stderr_b = e.to_output()
#     else:
#         try:
#             proc = subprocess.Popen(cmd, **kwargs)
#         except OSError as e:
#             returncode, stdout_b, stderr_b = _oserror_to_output(e)
#         else:
#             stdout_b, stderr_b = proc.communicate()
#             returncode = proc.returncode
# 
#     if retcode is not None and retcode != returncode:
#         raise CalledProcessError(returncode, cmd, retcode, stdout_b, stderr_b)
# 
#     return returncode, stdout_b, stderr_b


import logging
import os.path
import sys
from typing import MutableMapping
from pre_commit.errors import FatalError
from pre_commit.util import CalledProcessError
from pre_commit.util import cmd_output
from pre_commit.util import cmd_output_b
        if status[0] in {'C', 'R'}:  # renames / moves have an additional arg
            parts.pop()
        if status[1] == 'A':
            intent_to_add.append(filename)
    return intent_to_add


def get_all_files() -> list[str]:
    return zsplit(cmd_output('git', 'ls-files', '-z')[1])


def get_changed_files(old: str, new: str) -> list[str]:
    diff_cmd = ('git', 'diff', '--name-only', '--no-ext-diff', '-z')
    try:
        _, out, _ = cmd_output(*diff_cmd, f'{old}...{new}')
    except CalledProcessError:  # pragma: no cover (new git)
        # on newer git where old and new do not have a merge base git fails
        # so we try a full diff (this is what old git did for us!)
        _, out, _ = cmd_output(*diff_cmd, f'{old}..{new}')

    return zsplit(out)


def head_rev(remote: str) -> str:
    _, out, _ = cmd_output('git', 'ls-remote', '--exit-code', remote, 'HEAD')
    return out.split()[0]


def has_diff(*args: str, repo: str = '.') -> bool:
    cmd = ('git', 'diff', '--quiet', '--no-ext-diff', *args)

# Path: pre_commit/errors.py
# class FatalError(RuntimeError):
#     pass
# 
# Path: pre_commit/util.py
# class CalledProcessError(RuntimeError):
#     def __init__(
#             self,
#             returncode: int,
#             cmd: tuple[str, ...],
#             expected_returncode: int,
#             stdout: bytes,
#             stderr: bytes | None,
#     ) -> None:
#         super().__init__(returncode, cmd, expected_returncode, stdout, stderr)
#         self.returncode = returncode
#         self.cmd = cmd
#         self.expected_returncode = expected_returncode
#         self.stdout = stdout
#         self.stderr = stderr
# 
#     def __bytes__(self) -> bytes:
#         def _indent_or_none(part: bytes | None) -> bytes:
#             if part:
#                 return b'\n    ' + part.replace(b'\n', b'\n    ')
#             else:
#                 return b' (none)'
# 
#         return b''.join((
#             f'command: {self.cmd!r}\n'.encode(),
#             f'return code: {self.returncode}\n'.encode(),
#             f'expected return code: {self.expected_returncode}\n'.encode(),
#             b'stdout:', _indent_or_none(self.stdout), b'\n',
#             b'stderr:', _indent_or_none(self.stderr),
#         ))
# 
#     def __str__(self) -> str:
#         return self.__bytes__().decode()
# 
# Path: pre_commit/util.py
# def cmd_output(*cmd: str, **kwargs: Any) -> tuple[int, str, str | None]:
#     returncode, stdout_b, stderr_b = cmd_output_b(*cmd, **kwargs)
#     stdout = stdout_b.decode() if stdout_b is not None else None
#     stderr = stderr_b.decode() if stderr_b is not None else None
#     return returncode, stdout, stderr
# 
# Path: pre_commit/util.py
# def cmd_output_b(
#         *cmd: str,
#         retcode: int | None = 0,
#         **kwargs: Any,
# ) -> tuple[int, bytes, bytes | None]:
#     _setdefault_kwargs(kwargs)
# 
#     try:
#         cmd = parse_shebang.normalize_cmd(cmd)
#     except parse_shebang.ExecutableNotFoundError as e:
#         returncode, stdout_b, stderr_b = e.to_output()
#     else:
#         try:
#             proc = subprocess.Popen(cmd, **kwargs)
#         except OSError as e:
#             returncode, stdout_b, stderr_b = _oserror_to_output(e)
#         else:
#             stdout_b, stderr_b = proc.communicate()
#             returncode = proc.returncode
# 
#     if retcode is not None and retcode != returncode:
#         raise CalledProcessError(returncode, cmd, retcode, stdout_b, stderr_b)
# 
#     return returncode, stdout_b, stderr_b


# Path: pre_commit/git.py
import logging
import os.path
import sys
from typing import MutableMapping
from pre_commit.errors import FatalError
from pre_commit.util import CalledProcessError
from pre_commit.util import cmd_output
from pre_commit.util import cmd_output_b

        if status[0] in {'C', 'R'}:  # renames / moves have an additional arg
            parts.pop()
        if status[1] == 'A':
            intent_to_add.append(filename)
    return intent_to_add


def get_all_files() -> list[str]:
    return zsplit(cmd_output('git', 'ls-files', '-z')[1])


def get_changed_files(old: str, new: str) -> list[str]:
    diff_cmd = ('git', 'diff', '--name-only', '--no-ext-diff', '-z')
    try:
        _, out, _ = cmd_output(*diff_cmd, f'{old}...{new}')
    except CalledProcessError:  # pragma: no cover (new git)
        # on newer git where old and new do not have a merge base git fails
        # so we try a full diff (this is what old git did for us!)
        _, out, _ = cmd_output(*diff_cmd, f'{old}..{new}')

    return zsplit(out)


def head_rev(remote: str) -> str:
    _, out, _ = cmd_output('git', 'ls-remote', '--exit-code', remote, 'HEAD')
    return out.split()[0]


def has_diff(*args: str, repo: str = '.') -> bool:
    cmd = ('git', 'diff', '--quiet', '--no-ext-diff', *args)

    return cmd_output_b(*cmd, cwd=repo, retcode=None)[0] == 1