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()) |
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) |