From 73250ff4e32414e2c8fe8c7226aa92591a4001f7 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 20 Jul 2019 14:19:46 -0700 Subject: [PATCH] Fix autoupdate to always use non-shallow clone --- pre_commit/commands/autoupdate.py | 27 +++++++++++++++------------ pre_commit/git.py | 9 +++++++++ pre_commit/store.py | 10 ++-------- tests/commands/gc_test.py | 4 +++- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/pre_commit/commands/autoupdate.py b/pre_commit/commands/autoupdate.py index 11712e17..9701e937 100644 --- a/pre_commit/commands/autoupdate.py +++ b/pre_commit/commands/autoupdate.py @@ -10,6 +10,7 @@ from aspy.yaml import ordered_load from cfgv import remove_defaults import pre_commit.constants as C +from pre_commit import git from pre_commit import output from pre_commit.clientlib import CONFIG_SCHEMA from pre_commit.clientlib import InvalidManifestError @@ -20,6 +21,7 @@ from pre_commit.clientlib import META from pre_commit.commands.migrate_config import migrate_config from pre_commit.util import CalledProcessError from pre_commit.util import cmd_output +from pre_commit.util import tmpdir class RepositoryCannotBeUpdatedError(RuntimeError): @@ -34,19 +36,20 @@ def _update_repo(repo_config, store, tags_only): Args: repo_config - A config for a repository """ - repo_path = store.clone(repo_config['repo'], repo_config['rev']) + with tmpdir() as repo_path: + git.init_repo(repo_path, repo_config['repo']) + cmd_output('git', 'fetch', cwd=repo_path) - cmd_output('git', 'fetch', cwd=repo_path) - tag_cmd = ('git', 'describe', 'origin/master', '--tags') - if tags_only: - tag_cmd += ('--abbrev=0',) - else: - tag_cmd += ('--exact',) - try: - rev = cmd_output(*tag_cmd, cwd=repo_path)[1].strip() - except CalledProcessError: - tag_cmd = ('git', 'rev-parse', 'origin/master') - rev = cmd_output(*tag_cmd, cwd=repo_path)[1].strip() + tag_cmd = ('git', 'describe', 'origin/master', '--tags') + if tags_only: + tag_cmd += ('--abbrev=0',) + else: + tag_cmd += ('--exact',) + try: + rev = cmd_output(*tag_cmd, cwd=repo_path)[1].strip() + except CalledProcessError: + tag_cmd = ('git', 'rev-parse', 'origin/master') + rev = cmd_output(*tag_cmd, cwd=repo_path)[1].strip() # Don't bother trying to update if our rev is the same if rev == repo_config['rev']: diff --git a/pre_commit/git.py b/pre_commit/git.py index 64e449cb..c51930e7 100644 --- a/pre_commit/git.py +++ b/pre_commit/git.py @@ -143,6 +143,15 @@ def has_diff(*args, **kwargs): return cmd_output(*cmd, cwd=repo, retcode=None)[0] +def init_repo(path, remote): + if os.path.isdir(remote): + remote = os.path.abspath(remote) + + env = no_git_env() + cmd_output('git', 'init', path, env=env) + cmd_output('git', 'remote', 'add', 'origin', remote, cwd=path, env=env) + + def commit(repo='.'): env = no_git_env() name, email = 'pre-commit', 'asottile+pre-commit@umich.edu' diff --git a/pre_commit/store.py b/pre_commit/store.py index 08733ab8..55c57a3e 100644 --- a/pre_commit/store.py +++ b/pre_commit/store.py @@ -156,18 +156,13 @@ class Store(object): def clone(self, repo, ref, deps=()): """Clone the given url and checkout the specific ref.""" - if os.path.isdir(repo): - repo = os.path.abspath(repo) - def clone_strategy(directory): + git.init_repo(directory, repo) env = git.no_git_env() def _git_cmd(*args): cmd_output('git', *args, cwd=directory, env=env) - _git_cmd('init', '.') - _git_cmd('remote', 'add', 'origin', repo) - try: self._shallow_clone(ref, _git_cmd) except CalledProcessError: @@ -193,8 +188,7 @@ class Store(object): def _git_cmd(*args): cmd_output('git', *args, cwd=directory, env=env) - _git_cmd('init', '.') - _git_cmd('config', 'remote.origin.url', '<>') + git.init_repo(directory, '<>') _git_cmd('add', '.') git.commit(repo=directory) diff --git a/tests/commands/gc_test.py b/tests/commands/gc_test.py index d2528507..5be86b1b 100644 --- a/tests/commands/gc_test.py +++ b/tests/commands/gc_test.py @@ -5,6 +5,7 @@ from pre_commit import git from pre_commit.clientlib import load_config from pre_commit.commands.autoupdate import autoupdate from pre_commit.commands.gc import gc +from pre_commit.commands.install_uninstall import install_hooks from pre_commit.repository import all_hooks from testing.fixtures import make_config_from_repo from testing.fixtures import make_repo @@ -40,6 +41,7 @@ def test_gc(tempdir_factory, store, in_git_dir, cap_out): store.mark_config_used(C.CONFIG_FILE) # update will clone both the old and new repo, making the old one gc-able + install_hooks(C.CONFIG_FILE, store) assert not autoupdate(C.CONFIG_FILE, store, tags_only=False) assert _config_count(store) == 1 @@ -145,7 +147,7 @@ def test_invalid_manifest_gcd(tempdir_factory, store, in_git_dir, cap_out): store.mark_config_used(C.CONFIG_FILE) # trigger a clone - assert not autoupdate(C.CONFIG_FILE, store, tags_only=False) + install_hooks(C.CONFIG_FILE, store) # we'll "break" the manifest to simulate an old version clone (_, _, path), = store.select_all_repos()