hgext/remotefilelog/__init__.py
changeset 40560 fc2766860796
parent 40559 ed19958dbf5d
child 40562 b35a096b9bff
equal deleted inserted replaced
40559:ed19958dbf5d 40560:fc2766860796
   207 # be specifying the version(s) of Mercurial they are tested with, or
   207 # be specifying the version(s) of Mercurial they are tested with, or
   208 # leave the attribute unspecified.
   208 # leave the attribute unspecified.
   209 testedwith = 'ships-with-hg-core'
   209 testedwith = 'ships-with-hg-core'
   210 
   210 
   211 repoclass = localrepo.localrepository
   211 repoclass = localrepo.localrepository
   212 repoclass._basesupported.add(shallowrepo.requirement)
   212 repoclass._basesupported.add(constants.SHALLOWREPO_REQUIREMENT)
   213 
   213 
   214 def uisetup(ui):
   214 def uisetup(ui):
   215     """Wraps user facing Mercurial commands to swap them out with shallow
   215     """Wraps user facing Mercurial commands to swap them out with shallow
   216     versions.
   216     versions.
   217     """
   217     """
   229     extensions.wrapcommand(commands.table, 'log', log)
   229     extensions.wrapcommand(commands.table, 'log', log)
   230     extensions.wrapcommand(commands.table, 'pull', pull)
   230     extensions.wrapcommand(commands.table, 'pull', pull)
   231 
   231 
   232     # Prevent 'hg manifest --all'
   232     # Prevent 'hg manifest --all'
   233     def _manifest(orig, ui, repo, *args, **opts):
   233     def _manifest(orig, ui, repo, *args, **opts):
   234         if shallowrepo.requirement in repo.requirements and opts.get('all'):
   234         if (constants.SHALLOWREPO_REQUIREMENT in repo.requirements
       
   235             and opts.get('all')):
   235             raise error.Abort(_("--all is not supported in a shallow repo"))
   236             raise error.Abort(_("--all is not supported in a shallow repo"))
   236 
   237 
   237         return orig(ui, repo, *args, **opts)
   238         return orig(ui, repo, *args, **opts)
   238     extensions.wrapcommand(commands.table, "manifest", _manifest)
   239     extensions.wrapcommand(commands.table, "manifest", _manifest)
   239 
   240 
   254 
   255 
   255 def cloneshallow(orig, ui, repo, *args, **opts):
   256 def cloneshallow(orig, ui, repo, *args, **opts):
   256     if opts.get('shallow'):
   257     if opts.get('shallow'):
   257         repos = []
   258         repos = []
   258         def pull_shallow(orig, self, *args, **kwargs):
   259         def pull_shallow(orig, self, *args, **kwargs):
   259             if shallowrepo.requirement not in self.requirements:
   260             if constants.SHALLOWREPO_REQUIREMENT not in self.requirements:
   260                 repos.append(self.unfiltered())
   261                 repos.append(self.unfiltered())
   261                 # set up the client hooks so the post-clone update works
   262                 # set up the client hooks so the post-clone update works
   262                 setupclient(self.ui, self.unfiltered())
   263                 setupclient(self.ui, self.unfiltered())
   263 
   264 
   264                 # setupclient fixed the class on the repo itself
   265                 # setupclient fixed the class on the repo itself
   265                 # but we also need to fix it on the repoview
   266                 # but we also need to fix it on the repoview
   266                 if isinstance(self, repoview.repoview):
   267                 if isinstance(self, repoview.repoview):
   267                     self.__class__.__bases__ = (self.__class__.__bases__[0],
   268                     self.__class__.__bases__ = (self.__class__.__bases__[0],
   268                                                 self.unfiltered().__class__)
   269                                                 self.unfiltered().__class__)
   269                 self.requirements.add(shallowrepo.requirement)
   270                 self.requirements.add(constants.SHALLOWREPO_REQUIREMENT)
   270                 self._writerequirements()
   271                 self._writerequirements()
   271 
   272 
   272                 # Since setupclient hadn't been called, exchange.pull was not
   273                 # Since setupclient hadn't been called, exchange.pull was not
   273                 # wrapped. So we need to manually invoke our version of it.
   274                 # wrapped. So we need to manually invoke our version of it.
   274                 return exchangepull(orig, self, *args, **kwargs)
   275                 return exchangepull(orig, self, *args, **kwargs)
   310                         if c != 'v2']
   311                         if c != 'v2']
   311                 if bundle2:
   312                 if bundle2:
   312                     return False, None
   313                     return False, None
   313                 supported, requirements = orig(pullop, bundle2=bundle2)
   314                 supported, requirements = orig(pullop, bundle2=bundle2)
   314                 if requirements is not None:
   315                 if requirements is not None:
   315                     requirements.add(shallowrepo.requirement)
   316                     requirements.add(constants.SHALLOWREPO_REQUIREMENT)
   316                 return supported, requirements
   317                 return supported, requirements
   317             extensions.wrapfunction(
   318             extensions.wrapfunction(
   318                 streamclone, 'canperformstreamclone', canperformstreamclone)
   319                 streamclone, 'canperformstreamclone', canperformstreamclone)
   319         else:
   320         else:
   320             def stream_in_shallow(orig, repo, remote, requirements):
   321             def stream_in_shallow(orig, repo, remote, requirements):
   321                 setup_streamout(repo, remote)
   322                 setup_streamout(repo, remote)
   322                 requirements.add(shallowrepo.requirement)
   323                 requirements.add(constants.SHALLOWREPO_REQUIREMENT)
   323                 return orig(repo, remote, requirements)
   324                 return orig(repo, remote, requirements)
   324             extensions.wrapfunction(
   325             extensions.wrapfunction(
   325                 localrepo.localrepository, 'stream_in', stream_in_shallow)
   326                 localrepo.localrepository, 'stream_in', stream_in_shallow)
   326 
   327 
   327     try:
   328     try:
   347     # put here intentionally bc doesnt work in uisetup
   348     # put here intentionally bc doesnt work in uisetup
   348     ui.setconfig('hooks', 'update.prefetch', wcpprefetch)
   349     ui.setconfig('hooks', 'update.prefetch', wcpprefetch)
   349     ui.setconfig('hooks', 'commit.prefetch', wcpprefetch)
   350     ui.setconfig('hooks', 'commit.prefetch', wcpprefetch)
   350 
   351 
   351     isserverenabled = ui.configbool('remotefilelog', 'server')
   352     isserverenabled = ui.configbool('remotefilelog', 'server')
   352     isshallowclient = shallowrepo.requirement in repo.requirements
   353     isshallowclient = constants.SHALLOWREPO_REQUIREMENT in repo.requirements
   353 
   354 
   354     if isserverenabled and isshallowclient:
   355     if isserverenabled and isshallowclient:
   355         raise RuntimeError("Cannot be both a server and shallow client.")
   356         raise RuntimeError("Cannot be both a server and shallow client.")
   356 
   357 
   357     if isshallowclient:
   358     if isshallowclient:
   386     extensions.wrapfunction(
   387     extensions.wrapfunction(
   387         changegroup, 'makechangegroup', shallowbundle.makechangegroup)
   388         changegroup, 'makechangegroup', shallowbundle.makechangegroup)
   388 
   389 
   389     def storewrapper(orig, requirements, path, vfstype):
   390     def storewrapper(orig, requirements, path, vfstype):
   390         s = orig(requirements, path, vfstype)
   391         s = orig(requirements, path, vfstype)
   391         if shallowrepo.requirement in requirements:
   392         if constants.SHALLOWREPO_REQUIREMENT in requirements:
   392             s = shallowstore.wrapstore(s)
   393             s = shallowstore.wrapstore(s)
   393 
   394 
   394         return s
   395         return s
   395     extensions.wrapfunction(localrepo, 'makestore', storewrapper)
   396     extensions.wrapfunction(localrepo, 'makestore', storewrapper)
   396 
   397 
   397     extensions.wrapfunction(exchange, 'pull', exchangepull)
   398     extensions.wrapfunction(exchange, 'pull', exchangepull)
   398 
   399 
   399     # prefetch files before update
   400     # prefetch files before update
   400     def applyupdates(orig, repo, actions, wctx, mctx, overwrite, labels=None):
   401     def applyupdates(orig, repo, actions, wctx, mctx, overwrite, labels=None):
   401         if shallowrepo.requirement in repo.requirements:
   402         if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   402             manifest = mctx.manifest()
   403             manifest = mctx.manifest()
   403             files = []
   404             files = []
   404             for f, args, msg in actions['g']:
   405             for f, args, msg in actions['g']:
   405                 files.append((f, hex(manifest[f])))
   406                 files.append((f, hex(manifest[f])))
   406             # batch fetch the needed files from the server
   407             # batch fetch the needed files from the server
   409     extensions.wrapfunction(merge, 'applyupdates', applyupdates)
   410     extensions.wrapfunction(merge, 'applyupdates', applyupdates)
   410 
   411 
   411     # Prefetch merge checkunknownfiles
   412     # Prefetch merge checkunknownfiles
   412     def checkunknownfiles(orig, repo, wctx, mctx, force, actions,
   413     def checkunknownfiles(orig, repo, wctx, mctx, force, actions,
   413                           *args, **kwargs):
   414                           *args, **kwargs):
   414         if shallowrepo.requirement in repo.requirements:
   415         if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   415             files = []
   416             files = []
   416             sparsematch = repo.maybesparsematch(mctx.rev())
   417             sparsematch = repo.maybesparsematch(mctx.rev())
   417             for f, (m, actionargs, msg) in actions.iteritems():
   418             for f, (m, actionargs, msg) in actions.iteritems():
   418                 if sparsematch and not sparsematch(f):
   419                 if sparsematch and not sparsematch(f):
   419                     continue
   420                     continue
   428     extensions.wrapfunction(merge, '_checkunknownfiles', checkunknownfiles)
   429     extensions.wrapfunction(merge, '_checkunknownfiles', checkunknownfiles)
   429 
   430 
   430     # Prefetch files before status attempts to look at their size and contents
   431     # Prefetch files before status attempts to look at their size and contents
   431     def checklookup(orig, self, files):
   432     def checklookup(orig, self, files):
   432         repo = self._repo
   433         repo = self._repo
   433         if shallowrepo.requirement in repo.requirements:
   434         if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   434             prefetchfiles = []
   435             prefetchfiles = []
   435             for parent in self._parents:
   436             for parent in self._parents:
   436                 for f in files:
   437                 for f in files:
   437                     if f in parent:
   438                     if f in parent:
   438                         prefetchfiles.append((f, hex(parent.filenode(f))))
   439                         prefetchfiles.append((f, hex(parent.filenode(f))))
   441         return orig(self, files)
   442         return orig(self, files)
   442     extensions.wrapfunction(context.workingctx, '_checklookup', checklookup)
   443     extensions.wrapfunction(context.workingctx, '_checklookup', checklookup)
   443 
   444 
   444     # Prefetch the logic that compares added and removed files for renames
   445     # Prefetch the logic that compares added and removed files for renames
   445     def findrenames(orig, repo, matcher, added, removed, *args, **kwargs):
   446     def findrenames(orig, repo, matcher, added, removed, *args, **kwargs):
   446         if shallowrepo.requirement in repo.requirements:
   447         if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   447             files = []
   448             files = []
   448             parentctx = repo['.']
   449             parentctx = repo['.']
   449             for f in removed:
   450             for f in removed:
   450                 files.append((f, hex(parentctx.filenode(f))))
   451                 files.append((f, hex(parentctx.filenode(f))))
   451             # batch fetch the needed files from the server
   452             # batch fetch the needed files from the server
   454     extensions.wrapfunction(scmutil, '_findrenames', findrenames)
   455     extensions.wrapfunction(scmutil, '_findrenames', findrenames)
   455 
   456 
   456     # prefetch files before mergecopies check
   457     # prefetch files before mergecopies check
   457     def computenonoverlap(orig, repo, c1, c2, *args, **kwargs):
   458     def computenonoverlap(orig, repo, c1, c2, *args, **kwargs):
   458         u1, u2 = orig(repo, c1, c2, *args, **kwargs)
   459         u1, u2 = orig(repo, c1, c2, *args, **kwargs)
   459         if shallowrepo.requirement in repo.requirements:
   460         if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   460             m1 = c1.manifest()
   461             m1 = c1.manifest()
   461             m2 = c2.manifest()
   462             m2 = c2.manifest()
   462             files = []
   463             files = []
   463 
   464 
   464             sparsematch1 = repo.maybesparsematch(c1.rev())
   465             sparsematch1 = repo.maybesparsematch(c1.rev())
   486 
   487 
   487     # prefetch files before pathcopies check
   488     # prefetch files before pathcopies check
   488     def computeforwardmissing(orig, a, b, match=None):
   489     def computeforwardmissing(orig, a, b, match=None):
   489         missing = list(orig(a, b, match=match))
   490         missing = list(orig(a, b, match=match))
   490         repo = a._repo
   491         repo = a._repo
   491         if shallowrepo.requirement in repo.requirements:
   492         if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   492             mb = b.manifest()
   493             mb = b.manifest()
   493 
   494 
   494             files = []
   495             files = []
   495             sparsematch = repo.maybesparsematch(b.rev())
   496             sparsematch = repo.maybesparsematch(b.rev())
   496             if sparsematch:
   497             if sparsematch:
   513             return orig(lui, repo, *args, **kwargs)
   514             return orig(lui, repo, *args, **kwargs)
   514         finally:
   515         finally:
   515             # repo can be None when running in chg:
   516             # repo can be None when running in chg:
   516             # - at startup, reposetup was called because serve is not norepo
   517             # - at startup, reposetup was called because serve is not norepo
   517             # - a norepo command like "help" is called
   518             # - a norepo command like "help" is called
   518             if repo and shallowrepo.requirement in repo.requirements:
   519             if repo and constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   519                 repo.fileservice.close()
   520                 repo.fileservice.close()
   520     extensions.wrapfunction(dispatch, 'runcommand', runcommand)
   521     extensions.wrapfunction(dispatch, 'runcommand', runcommand)
   521 
   522 
   522     # disappointing hacks below
   523     # disappointing hacks below
   523     templatekw.getrenamedfn = getrenamedfn
   524     templatekw.getrenamedfn = getrenamedfn
   525     revset.symbols['filelog'] = revset.filelog
   526     revset.symbols['filelog'] = revset.filelog
   526     extensions.wrapfunction(cmdutil, 'walkfilerevs', walkfilerevs)
   527     extensions.wrapfunction(cmdutil, 'walkfilerevs', walkfilerevs)
   527 
   528 
   528     # prevent strip from stripping remotefilelogs
   529     # prevent strip from stripping remotefilelogs
   529     def _collectbrokencsets(orig, repo, files, striprev):
   530     def _collectbrokencsets(orig, repo, files, striprev):
   530         if shallowrepo.requirement in repo.requirements:
   531         if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   531             files = list([f for f in files if not repo.shallowmatch(f)])
   532             files = list([f for f in files if not repo.shallowmatch(f)])
   532         return orig(repo, files, striprev)
   533         return orig(repo, files, striprev)
   533     extensions.wrapfunction(repair, '_collectbrokencsets', _collectbrokencsets)
   534     extensions.wrapfunction(repair, '_collectbrokencsets', _collectbrokencsets)
   534 
   535 
   535     # Don't commit filelogs until we know the commit hash, since the hash
   536     # Don't commit filelogs until we know the commit hash, since the hash
   576 
   577 
   577     # changectx wrappers
   578     # changectx wrappers
   578     def filectx(orig, self, path, fileid=None, filelog=None):
   579     def filectx(orig, self, path, fileid=None, filelog=None):
   579         if fileid is None:
   580         if fileid is None:
   580             fileid = self.filenode(path)
   581             fileid = self.filenode(path)
   581         if (shallowrepo.requirement in self._repo.requirements and
   582         if (constants.SHALLOWREPO_REQUIREMENT in self._repo.requirements and
   582             self._repo.shallowmatch(path)):
   583             self._repo.shallowmatch(path)):
   583             return remotefilectx.remotefilectx(self._repo, path,
   584             return remotefilectx.remotefilectx(self._repo, path,
   584                 fileid=fileid, changectx=self, filelog=filelog)
   585                 fileid=fileid, changectx=self, filelog=filelog)
   585         return orig(self, path, fileid=fileid, filelog=filelog)
   586         return orig(self, path, fileid=fileid, filelog=filelog)
   586     extensions.wrapfunction(context.changectx, 'filectx', filectx)
   587     extensions.wrapfunction(context.changectx, 'filectx', filectx)
   587 
   588 
   588     def workingfilectx(orig, self, path, filelog=None):
   589     def workingfilectx(orig, self, path, filelog=None):
   589         if (shallowrepo.requirement in self._repo.requirements and
   590         if (constants.SHALLOWREPO_REQUIREMENT in self._repo.requirements and
   590             self._repo.shallowmatch(path)):
   591             self._repo.shallowmatch(path)):
   591             return remotefilectx.remoteworkingfilectx(self._repo,
   592             return remotefilectx.remoteworkingfilectx(self._repo,
   592                 path, workingctx=self, filelog=filelog)
   593                 path, workingctx=self, filelog=filelog)
   593         return orig(self, path, filelog=filelog)
   594         return orig(self, path, filelog=filelog)
   594     extensions.wrapfunction(context.workingctx, 'filectx', workingfilectx)
   595     extensions.wrapfunction(context.workingctx, 'filectx', workingfilectx)
   595 
   596 
   596     # prefetch required revisions before a diff
   597     # prefetch required revisions before a diff
   597     def trydiff(orig, repo, revs, ctx1, ctx2, modified, added, removed,
   598     def trydiff(orig, repo, revs, ctx1, ctx2, modified, added, removed,
   598                 copy, getfilectx, *args, **kwargs):
   599                 copy, getfilectx, *args, **kwargs):
   599         if shallowrepo.requirement in repo.requirements:
   600         if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   600             prefetch = []
   601             prefetch = []
   601             mf1 = ctx1.manifest()
   602             mf1 = ctx1.manifest()
   602             for fname in modified + added + removed:
   603             for fname in modified + added + removed:
   603                 if fname in mf1:
   604                 if fname in mf1:
   604                     fnode = getfilectx(fname, ctx1).filenode()
   605                     fnode = getfilectx(fname, ctx1).filenode()
   652             return None
   653             return None
   653 
   654 
   654     return getrenamed
   655     return getrenamed
   655 
   656 
   656 def walkfilerevs(orig, repo, match, follow, revs, fncache):
   657 def walkfilerevs(orig, repo, match, follow, revs, fncache):
   657     if not shallowrepo.requirement in repo.requirements:
   658     if not constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   658         return orig(repo, match, follow, revs, fncache)
   659         return orig(repo, match, follow, revs, fncache)
   659 
   660 
   660     # remotefilelog's can't be walked in rev order, so throw.
   661     # remotefilelog's can't be walked in rev order, so throw.
   661     # The caller will see the exception and walk the commit tree instead.
   662     # The caller will see the exception and walk the commit tree instead.
   662     if not follow:
   663     if not follow:
   692     For performance reasons, ``filelog()`` does not show every changeset
   693     For performance reasons, ``filelog()`` does not show every changeset
   693     that affects the requested file(s). See :hg:`help log` for details. For
   694     that affects the requested file(s). See :hg:`help log` for details. For
   694     a slower, more accurate result, use ``file()``.
   695     a slower, more accurate result, use ``file()``.
   695     """
   696     """
   696 
   697 
   697     if not shallowrepo.requirement in repo.requirements:
   698     if not constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   698         return orig(repo, subset, x)
   699         return orig(repo, subset, x)
   699 
   700 
   700     # i18n: "filelog" is a keyword
   701     # i18n: "filelog" is a keyword
   701     pat = revset.getstring(x, _("filelog requires a pattern"))
   702     pat = revset.getstring(x, _("filelog requires a pattern"))
   702     m = match.match(repo.root, repo.getcwd(), [pat], default='relpath',
   703     m = match.match(repo.root, repo.getcwd(), [pat], default='relpath',
   800         validrepos.append(path)
   801         validrepos.append(path)
   801 
   802 
   802         # Protect against any repo or config changes that have happened since
   803         # Protect against any repo or config changes that have happened since
   803         # this repo was added to the repos file. We'd rather this loop succeed
   804         # this repo was added to the repos file. We'd rather this loop succeed
   804         # and too much be deleted, than the loop fail and nothing gets deleted.
   805         # and too much be deleted, than the loop fail and nothing gets deleted.
   805         if shallowrepo.requirement not in repo.requirements:
   806         if constants.SHALLOWREPO_REQUIREMENT not in repo.requirements:
   806             continue
   807             continue
   807 
   808 
   808         if not util.safehasattr(repo, 'name'):
   809         if not util.safehasattr(repo, 'name'):
   809             ui.warn(_("repo %s is a misconfigured remotefilelog repo\n") % path)
   810             ui.warn(_("repo %s is a misconfigured remotefilelog repo\n") % path)
   810             continue
   811             continue
   849         sharedcache.gc(keepkeys)
   850         sharedcache.gc(keepkeys)
   850     elif not filesrepacked:
   851     elif not filesrepacked:
   851         ui.warn(_("warning: no valid repos in repofile\n"))
   852         ui.warn(_("warning: no valid repos in repofile\n"))
   852 
   853 
   853 def log(orig, ui, repo, *pats, **opts):
   854 def log(orig, ui, repo, *pats, **opts):
   854     if shallowrepo.requirement not in repo.requirements:
   855     if constants.SHALLOWREPO_REQUIREMENT not in repo.requirements:
   855         return orig(ui, repo, *pats, **opts)
   856         return orig(ui, repo, *pats, **opts)
   856 
   857 
   857     follow = opts.get('follow')
   858     follow = opts.get('follow')
   858     revs = opts.get('rev')
   859     revs = opts.get('rev')
   859     if pats:
   860     if pats:
   910 
   911 
   911 def wcpprefetch(ui, repo, **kwargs):
   912 def wcpprefetch(ui, repo, **kwargs):
   912     """Prefetches in background revisions specified by bgprefetchrevs revset.
   913     """Prefetches in background revisions specified by bgprefetchrevs revset.
   913     Does background repack if backgroundrepack flag is set in config.
   914     Does background repack if backgroundrepack flag is set in config.
   914     """
   915     """
   915     shallow = shallowrepo.requirement in repo.requirements
   916     shallow = constants.SHALLOWREPO_REQUIREMENT in repo.requirements
   916     bgprefetchrevs = ui.config('remotefilelog', 'bgprefetchrevs')
   917     bgprefetchrevs = ui.config('remotefilelog', 'bgprefetchrevs')
   917     isready = readytofetch(repo)
   918     isready = readytofetch(repo)
   918 
   919 
   919     if not (shallow and bgprefetchrevs and isready):
   920     if not (shallow and bgprefetchrevs and isready):
   920         return
   921         return
   932     repo._afterlock(anon)
   933     repo._afterlock(anon)
   933 
   934 
   934 def pull(orig, ui, repo, *pats, **opts):
   935 def pull(orig, ui, repo, *pats, **opts):
   935     result = orig(ui, repo, *pats, **opts)
   936     result = orig(ui, repo, *pats, **opts)
   936 
   937 
   937     if shallowrepo.requirement in repo.requirements:
   938     if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   938         # prefetch if it's configured
   939         # prefetch if it's configured
   939         prefetchrevset = ui.config('remotefilelog', 'pullprefetch')
   940         prefetchrevset = ui.config('remotefilelog', 'pullprefetch')
   940         bgrepack = repo.ui.configbool('remotefilelog', 'backgroundrepack')
   941         bgrepack = repo.ui.configbool('remotefilelog', 'backgroundrepack')
   941         bgprefetch = repo.ui.configbool('remotefilelog', 'backgroundprefetch')
   942         bgprefetch = repo.ui.configbool('remotefilelog', 'backgroundprefetch')
   942 
   943 
   972         extensions.wrapfunction(remote, 'getbundle', localgetbundle)
   973         extensions.wrapfunction(remote, 'getbundle', localgetbundle)
   973 
   974 
   974     return orig(repo, remote, *args, **kwargs)
   975     return orig(repo, remote, *args, **kwargs)
   975 
   976 
   976 def _fileprefetchhook(repo, revs, match):
   977 def _fileprefetchhook(repo, revs, match):
   977     if shallowrepo.requirement in repo.requirements:
   978     if constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
   978         allfiles = []
   979         allfiles = []
   979         for rev in revs:
   980         for rev in revs:
   980             if rev == nodemod.wdirrev or rev is None:
   981             if rev == nodemod.wdirrev or rev is None:
   981                 continue
   982                 continue
   982             ctx = repo[rev]
   983             ctx = repo[rev]
  1068     used which is the union of dot, draft, pullprefetch and bgprefetchrev.
  1069     used which is the union of dot, draft, pullprefetch and bgprefetchrev.
  1069     File names or patterns can be used to limit which files are downloaded.
  1070     File names or patterns can be used to limit which files are downloaded.
  1070 
  1071 
  1071     Return 0 on success.
  1072     Return 0 on success.
  1072     """
  1073     """
  1073     if not shallowrepo.requirement in repo.requirements:
  1074     if not constants.SHALLOWREPO_REQUIREMENT in repo.requirements:
  1074         raise error.Abort(_("repo is not shallow"))
  1075         raise error.Abort(_("repo is not shallow"))
  1075 
  1076 
  1076     opts = resolveprefetchopts(ui, opts)
  1077     opts = resolveprefetchopts(ui, opts)
  1077     revs = scmutil.revrange(repo, opts.get('rev'))
  1078     revs = scmutil.revrange(repo, opts.get('rev'))
  1078     repo.prefetch(revs, opts.get('base'), pats, opts)
  1079     repo.prefetch(revs, opts.get('base'), pats, opts)