diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py --- a/hgext/lfs/wrapper.py +++ b/hgext/lfs/wrapper.py @@ -337,7 +337,7 @@ setattr(self, name, getattr(othervfs, name)) -def _prefetchfiles(repo, revs, match): +def _prefetchfiles(repo, revmatches): """Ensure that required LFS blobs are present, fetching them as a group if needed.""" if not util.safehasattr(repo.svfs, b'lfslocalblobstore'): @@ -347,7 +347,7 @@ oids = set() localstore = repo.svfs.lfslocalblobstore - for rev in revs: + for rev, match in revmatches: ctx = repo[rev] for f in ctx.walk(match): p = pointerfromctx(ctx, f) diff --git a/hgext/remotefilelog/__init__.py b/hgext/remotefilelog/__init__.py --- a/hgext/remotefilelog/__init__.py +++ b/hgext/remotefilelog/__init__.py @@ -1118,10 +1118,10 @@ return orig(repo, remote, *args, **kwargs) -def _fileprefetchhook(repo, revs, match): +def _fileprefetchhook(repo, revmatches): if isenabled(repo): allfiles = [] - for rev in revs: + for rev, match in revmatches: if rev == nodemod.wdirrev or rev is None: continue ctx = repo[rev] diff --git a/mercurial/archival.py b/mercurial/archival.py --- a/mercurial/archival.py +++ b/mercurial/archival.py @@ -364,7 +364,7 @@ if total: files.sort() scmutil.prefetchfiles( - repo, [ctx.rev()], scmutil.matchfiles(repo, files) + repo, [(ctx.rev(), scmutil.matchfiles(repo, files))] ) progress = repo.ui.makeprogress( _(b'archiving'), unit=_(b'files'), total=total diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -2138,7 +2138,9 @@ for file in repo[rev].files(): if not match or match(file): allfiles.add(file) - scmutil.prefetchfiles(repo, revs, scmutil.matchfiles(repo, allfiles)) + match = scmutil.matchfiles(repo, allfiles) + revmatches = [(rev, match) for rev in revs] + scmutil.prefetchfiles(repo, revmatches) def export( @@ -2997,14 +2999,14 @@ try: if mfnode and mfl[mfnode].find(file)[0]: if _catfmtneedsdata(basefm): - scmutil.prefetchfiles(repo, [ctx.rev()], matcher) + scmutil.prefetchfiles(repo, [(ctx.rev(), matcher)]) write(file) return 0 except KeyError: pass if _catfmtneedsdata(basefm): - scmutil.prefetchfiles(repo, [ctx.rev()], matcher) + scmutil.prefetchfiles(repo, [(ctx.rev(), matcher)]) for abs in ctx.walk(matcher): write(abs) @@ -3769,11 +3771,11 @@ needdata = (b'revert', b'add', b'undelete') oplist = [actions[name][0] for name in needdata] prefetch = scmutil.prefetchfiles - matchfiles = scmutil.matchfiles + matchfiles = scmutil.matchfiles( + repo, [f for sublist in oplist for f in sublist] + ) prefetch( - repo, - [ctx.rev()], - matchfiles(repo, [f for sublist in oplist for f in sublist]), + repo, [(ctx.rev(), matchfiles)], ) match = scmutil.match(repo[None], pats) _performrevert( diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -2540,8 +2540,12 @@ # using things like remotefilelog. scmutil.prefetchfiles( self.repo(), - [self.p1().rev()], - scmutil.matchfiles(self.repo(), self._cache.keys()), + [ + ( + self.p1().rev(), + scmutil.matchfiles(self.repo(), self._cache.keys()), + ) + ], ) for path in self._cache.keys(): diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1121,8 +1121,14 @@ matchfiles = scmutil.matchfiles prefetch( repo, - [ctx.rev()], - matchfiles(repo, [f for sublist in oplist for f, args, msg in sublist]), + [ + ( + ctx.rev(), + matchfiles( + repo, [f for sublist in oplist for f, args, msg in sublist] + ), + ) + ], ) diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -2666,7 +2666,11 @@ prefetchmatch = scmutil.matchfiles( repo, list(modifiedset | addedset | removedset) ) - scmutil.prefetchfiles(repo, [ctx1.rev(), ctx2.rev()], prefetchmatch) + revmatches = [ + (ctx1.rev(), prefetchmatch), + (ctx2.rev(), prefetchmatch), + ] + scmutil.prefetchfiles(repo, revmatches) def difffn(opts, losedata): return trydiff( diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -1880,18 +1880,29 @@ ] -def prefetchfiles(repo, revs, match): +def prefetchfiles(repo, revmatches): """Invokes the registered file prefetch functions, allowing extensions to ensure the corresponding files are available locally, before the command - uses them.""" - if match: - # The command itself will complain about files that don't exist, so - # don't duplicate the message. - match = matchmod.badmatch(match, lambda fn, msg: None) - else: - match = matchall(repo) + uses them. + + Args: + revmatches: a list of (revision, match) tuples to indicate the files to + fetch at each revision. If any of the match elements is None, it matches + all files. + """ - fileprefetchhooks(repo, revs, match) + def _matcher(m): + if m: + assert isinstance(m, matchmod.basematcher) + # The command itself will complain about files that don't exist, so + # don't duplicate the message. + return matchmod.badmatch(m, lambda fn, msg: None) + else: + return matchall(repo) + + revbadmatches = [(rev, _matcher(match)) for (rev, match) in revmatches] + + fileprefetchhooks(repo, revbadmatches) # a list of (repo, revs, match) prefetch functions diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -639,7 +639,7 @@ rev = self._state[1] ctx = self._repo[rev] scmutil.prefetchfiles( - self._repo, [ctx.rev()], scmutil.matchfiles(self._repo, files) + self._repo, [(ctx.rev(), scmutil.matchfiles(self._repo, files))] ) total = abstractsubrepo.archive(self, archiver, prefix, match) for subpath in ctx.substate: