1616from pre_commit .clientlib import LOCAL
1717from pre_commit .clientlib import META
1818from pre_commit .commands .migrate_config import migrate_config
19- from pre_commit .store import Store
2019from pre_commit .util import CalledProcessError
2120from pre_commit .util import cmd_output
2221from pre_commit .util import cmd_output_b
2726class RevInfo (NamedTuple ):
2827 repo : str
2928 rev : str
30- frozen : str | None
29+ frozen : str | None = None
30+ hook_ids : frozenset [str ] = frozenset ()
3131
3232 @classmethod
3333 def from_config (cls , config : dict [str , Any ]) -> RevInfo :
34- return cls (config ['repo' ], config ['rev' ], None )
34+ return cls (config ['repo' ], config ['rev' ])
3535
3636 def update (self , tags_only : bool , freeze : bool ) -> RevInfo :
3737 with tempfile .TemporaryDirectory () as tmp :
@@ -63,7 +63,19 @@ def update(self, tags_only: bool, freeze: bool) -> RevInfo:
6363 exact = cmd_output (* _git , 'rev-parse' , rev )[1 ].strip ()
6464 if exact != rev :
6565 rev , frozen = exact , rev
66- return self ._replace (rev = rev , frozen = frozen )
66+
67+ try :
68+ cmd_output (* _git , 'checkout' , rev , '--' , C .MANIFEST_FILE )
69+ except CalledProcessError :
70+ pass # this will be caught by manifest validating code
71+ try :
72+ manifest = load_manifest (os .path .join (tmp , C .MANIFEST_FILE ))
73+ except InvalidManifestError as e :
74+ raise RepositoryCannotBeUpdatedError (str (e ))
75+ else :
76+ hook_ids = frozenset (hook ['id' ] for hook in manifest )
77+
78+ return self ._replace (rev = rev , frozen = frozen , hook_ids = hook_ids )
6779
6880
6981class RepositoryCannotBeUpdatedError (RuntimeError ):
@@ -73,17 +85,10 @@ class RepositoryCannotBeUpdatedError(RuntimeError):
7385def _check_hooks_still_exist_at_rev (
7486 repo_config : dict [str , Any ],
7587 info : RevInfo ,
76- store : Store ,
7788) -> None :
78- try :
79- path = store .clone (repo_config ['repo' ], info .rev )
80- manifest = load_manifest (os .path .join (path , C .MANIFEST_FILE ))
81- except InvalidManifestError as e :
82- raise RepositoryCannotBeUpdatedError (str (e ))
83-
8489 # See if any of our hooks were deleted with the new commits
8590 hooks = {hook ['id' ] for hook in repo_config ['hooks' ]}
86- hooks_missing = hooks - { hook [ 'id' ] for hook in manifest }
91+ hooks_missing = hooks - info . hook_ids
8792 if hooks_missing :
8893 raise RepositoryCannotBeUpdatedError (
8994 f'Cannot update because the update target is missing these '
@@ -139,7 +144,6 @@ def _write_new_config(path: str, rev_infos: list[RevInfo | None]) -> None:
139144
140145def autoupdate (
141146 config_file : str ,
142- store : Store ,
143147 tags_only : bool ,
144148 freeze : bool ,
145149 repos : Sequence [str ] = (),
@@ -161,9 +165,9 @@ def autoupdate(
161165 continue
162166
163167 output .write (f'Updating { info .repo } ... ' )
164- new_info = info .update (tags_only = tags_only , freeze = freeze )
165168 try :
166- _check_hooks_still_exist_at_rev (repo_config , new_info , store )
169+ new_info = info .update (tags_only = tags_only , freeze = freeze )
170+ _check_hooks_still_exist_at_rev (repo_config , new_info )
167171 except RepositoryCannotBeUpdatedError as error :
168172 output .write_line (error .args [0 ])
169173 rev_infos .append (None )
0 commit comments