| 36 | return cls(config['repo'], config['rev']) |
| 37 | |
| 38 | def update(self, tags_only: bool, freeze: bool) -> RevInfo: |
| 39 | with tempfile.TemporaryDirectory() as tmp: |
| 40 | _git = ('git', *git.NO_FS_MONITOR, '-C', tmp) |
| 41 | |
| 42 | if tags_only: |
| 43 | tag_opt = '--abbrev=0' |
| 44 | else: |
| 45 | tag_opt = '--exact' |
| 46 | tag_cmd = (*_git, 'describe', 'FETCH_HEAD', '--tags', tag_opt) |
| 47 | |
| 48 | git.init_repo(tmp, self.repo) |
| 49 | cmd_output_b(*_git, 'config', 'extensions.partialClone', 'true') |
| 50 | cmd_output_b( |
| 51 | *_git, 'fetch', 'origin', 'HEAD', |
| 52 | '--quiet', '--filter=blob:none', '--tags', |
| 53 | ) |
| 54 | |
| 55 | try: |
| 56 | rev = cmd_output(*tag_cmd)[1].strip() |
| 57 | except CalledProcessError: |
| 58 | rev = cmd_output(*_git, 'rev-parse', 'FETCH_HEAD')[1].strip() |
| 59 | else: |
| 60 | if tags_only: |
| 61 | rev = git.get_best_candidate_tag(rev, tmp) |
| 62 | |
| 63 | frozen = None |
| 64 | if freeze: |
| 65 | exact = cmd_output(*_git, 'rev-parse', rev)[1].strip() |
| 66 | if exact != rev: |
| 67 | rev, frozen = exact, rev |
| 68 | |
| 69 | try: |
| 70 | # workaround for windows -- see #2865 |
| 71 | cmd_output_b(*_git, 'show', f'{rev}:{C.MANIFEST_FILE}') |
| 72 | cmd_output(*_git, 'checkout', rev, '--', C.MANIFEST_FILE) |
| 73 | except CalledProcessError: |
| 74 | pass # this will be caught by manifest validating code |
| 75 | try: |
| 76 | manifest = load_manifest(os.path.join(tmp, C.MANIFEST_FILE)) |
| 77 | except InvalidManifestError as e: |
| 78 | raise RepositoryCannotBeUpdatedError(f'[{self.repo}] {e}') |
| 79 | else: |
| 80 | hook_ids = frozenset(hook['id'] for hook in manifest) |
| 81 | |
| 82 | return self._replace(rev=rev, frozen=frozen, hook_ids=hook_ids) |
| 83 | |
| 84 | |
| 85 | class RepositoryCannotBeUpdatedError(RuntimeError): |