diff --git a/pre_commit/commands/autoupdate.py b/pre_commit/commands/autoupdate.py index 33a347302..5cb978e92 100644 --- a/pre_commit/commands/autoupdate.py +++ b/pre_commit/commands/autoupdate.py @@ -36,24 +36,36 @@ def from_config(cls, config: Dict[str, Any]) -> 'RevInfo': return cls(config['repo'], config['rev'], None) def update(self, tags_only: bool, freeze: bool) -> 'RevInfo': + git_cmd = ('git', *git.NO_FS_MONITOR) + if tags_only: - tag_cmd = ('git', 'describe', 'FETCH_HEAD', '--tags', '--abbrev=0') + tag_cmd = ( + *git_cmd, 'describe', + 'FETCH_HEAD', '--tags', '--abbrev=0', + ) else: - tag_cmd = ('git', 'describe', 'FETCH_HEAD', '--tags', '--exact') + tag_cmd = ( + *git_cmd, 'describe', + 'FETCH_HEAD', '--tags', '--exact', + ) with tmpdir() as tmp: git.init_repo(tmp, self.repo) - cmd_output_b('git', 'fetch', 'origin', 'HEAD', '--tags', cwd=tmp) + cmd_output_b( + *git_cmd, 'fetch', 'origin', 'HEAD', '--tags', + cwd=tmp, + ) try: rev = cmd_output(*tag_cmd, cwd=tmp)[1].strip() except CalledProcessError: - cmd = ('git', 'rev-parse', 'FETCH_HEAD') + cmd = (*git_cmd, 'rev-parse', 'FETCH_HEAD') rev = cmd_output(*cmd, cwd=tmp)[1].strip() frozen = None if freeze: - exact = cmd_output('git', 'rev-parse', rev, cwd=tmp)[1].strip() + exact_rev_cmd = (*git_cmd, 'rev-parse', rev) + exact = cmd_output(*exact_rev_cmd, cwd=tmp)[1].strip() if exact != rev: rev, frozen = exact, rev return self._replace(rev=rev, frozen=frozen) diff --git a/pre_commit/git.py b/pre_commit/git.py index 6264529d5..883723ea1 100644 --- a/pre_commit/git.py +++ b/pre_commit/git.py @@ -12,9 +12,11 @@ from pre_commit.util import cmd_output from pre_commit.util import cmd_output_b - logger = logging.getLogger(__name__) +# see #2046 +NO_FS_MONITOR = ('-c', 'core.useBuiltinFSMonitor=false') + def zsplit(s: str) -> List[str]: s = s.strip('\0') @@ -185,10 +187,11 @@ def init_repo(path: str, remote: str) -> None: if os.path.isdir(remote): remote = os.path.abspath(remote) + git = ('git', *NO_FS_MONITOR) env = no_git_env() # avoid the user's template so that hooks do not recurse - cmd_output_b('git', 'init', '--template=', path, env=env) - cmd_output_b('git', 'remote', 'add', 'origin', remote, cwd=path, env=env) + cmd_output_b(*git, 'init', '--template=', path, env=env) + cmd_output_b(*git, 'remote', 'add', 'origin', remote, cwd=path, env=env) def commit(repo: str = '.') -> None: diff --git a/tests/commands/autoupdate_test.py b/tests/commands/autoupdate_test.py index b2bad6014..7316eb97a 100644 --- a/tests/commands/autoupdate_test.py +++ b/tests/commands/autoupdate_test.py @@ -5,6 +5,7 @@ import yaml import pre_commit.constants as C +from pre_commit import envcontext from pre_commit import git from pre_commit import util from pre_commit.commands.autoupdate import _check_hooks_still_exist_at_rev @@ -176,6 +177,14 @@ def test_autoupdate_out_of_date_repo(out_of_date, tmpdir, store): assert cfg.read() == fmt.format(out_of_date.path, out_of_date.head_rev) +def test_autoupdate_with_core_useBuiltinFSMonitor(out_of_date, tmpdir, store): + # force the setting on "globally" for git + home = tmpdir.join('fakehome').ensure_dir() + home.join('.gitconfig').write('[core]\nuseBuiltinFSMonitor = true\n') + with envcontext.envcontext((('HOME', str(home)),)): + test_autoupdate_out_of_date_repo(out_of_date, tmpdir, store) + + def test_autoupdate_pure_yaml(out_of_date, tmpdir, store): with mock.patch.object(util, 'Dumper', yaml.SafeDumper): test_autoupdate_out_of_date_repo(out_of_date, tmpdir, store)