D7144: status: use unfiltered repo if we're getting status of working copy
martinvonz (Martin von Zweigbergk)
phabricator at mercurial-scm.org
Wed Oct 30 20:48:44 UTC 2019
martinvonz added a comment.
In D7144#105248 <https://phab.mercurial-scm.org/D7144#105248>, @mharbison72 wrote:
> The comment about maybe affecting extensions made me think of df463ca0adef <https://phab.mercurial-scm.org/rHGdf463ca0adefbf6ffa084cfd8031dcfc6c944f8e>. I never figured out what the issue was.
I suspect that's because largefiles creates a repo subclass and that subclass does not have the `__getattr__` and `__setattr__` overrides that `repoview` does, so setting `lfstatus`or `_largefilesenabled` on that subclass won't propagate it to the parent.
In D7144#105352 <https://phab.mercurial-scm.org/D7144#105352>, @marmoute wrote:
> In D7144#105048 <https://phab.mercurial-scm.org/D7144#105048>, @martinvonz wrote:
>
>> In D7144#105039 <https://phab.mercurial-scm.org/D7144#105039>, @marmoute wrote:
>>
>>> I have a couple of questions:
>>>
>>> […]
>>>
>>> - This could cause issue to extensions, can we abtract the unfiltering though a function so that extension can rewrap it ?
>>
>> To make sure I address it properly, what's the issue(s) you're thinking of?
>
> Imagine you are an extension writer adding extra information on status (eg: tell the user if his stack is behind and he needs to rebase). If you get an unfiltered repository, any operation you run (eg: a revset to check the graph, will go horribly wrong). So we need need at minimum an easy way to disable the unfiltering if an extension needs to do it.
>
> In D7144#105066 <https://phab.mercurial-scm.org/D7144#105066>, @martinvonz wrote:
>
>> In D7144#105065 <https://phab.mercurial-scm.org/D7144#105065>, @marmoute wrote:
>>
>>> Another question is " Why are we loading the changelog if we don't need it ?". If the code were not accessing the changelog, we could not pay the filtering code (and save other parsing cost).
>>
>> We load the changelog when we do `repo['.']`. I had added a hack (https://www.mercurial-scm.org/repo/hg/file/4565a0afc289/mercurial/localrepo.py#l1539) to try to avoid that, but it was no longer effective. I think using the unfiltered repo is a better solution anyway.
>
> If the performance gain are clear, using an unfiltered repository seems like a reasonable gain/risk move. However I would prefer this to remain temporary. Keeping the repository filtering aligned to the current semantic is important to avoid surprise and obscure bug in the future. We need an overall effort to reduce the filtering impact anyway (independantly from this series).
> In the case here, I wonder if we have and easy way to prevent the filtering computation kick in, as it is clearly unnecessary.
>
> - can you share a profile of what takes time with the filtering version
> - Do you know which part is triggering the filtering ?
I'll get back to you about the other things later, but I think the following profile answers these last questions:
| 100.0% 0.19s dispatch.py: _callcatch line 36: dispatch.run()
| 100.0% 0.19s scmutil.py: callcatch line 433: return scmutil.callcatch(ui...
| 100.0% 0.19s dispatch.py: _runcatchfunc line 177: return func()
| 100.0% 0.19s hg.py: repository line 414: return _dispatch(req)
\ 52.6% 0.10s localrepo.py: status line 6831: opts.get(b'subrepos'),
\ 31.6% 0.06s localrepo.py: __getitem__ line 3248: return self[node1].status(
| 31.6% 0.06s repoview.py: changelog line 1547: rev = self.changelog.rev(ch...
| 31.6% 0.06s repoview.py: filterrevs line 278: revs = filterrevs(unfi, sel...
| 31.6% 0.06s repoview.py: computehidden line 217: repo.filteredrevcache[filte...
\ 15.8% 0.03s repoview.py: hideablerevsline 87: hidden = hideablerevs(repo)
| 15.8% 0.03s obsolete.py: getrevs line 39: obsoletes = obsolete.getrev...
| 15.8% 0.03s obscache.py: <lambda> line 905: repo.obsstore.caches[name] ...
| 15.8% 0.03s obscache.py: _computeobsoletesetline 469: wrapped = lambda repo: _com...
| 10.5% 0.02s phases.py: getrevset line 434: notpublic = repo._phasecach...
\ 5.3% 0.01s scmutil.py: __get__ line 106: return super(_basefilecache...
| 5.3% 0.01s localrepo.py: _phasecacheline 1636: entry.obj = self.func(obj)
| 5.3% 0.01s phases.py: __init__line 1432: return phases.phasecache(se...
| 5.3% 0.01s phases.py: _readrootsline 235: self.phaseroots, self.dirty...
\ 5.3% 0.01s phases.py: loadphaserevsline 243: self.loadphaserevs(repo) #...
| 5.3% 0.01s phases.py: _getphaserevsnativeline 325: res = self._getphaserevsnat...
| 5.3% 0.01s changelog.py: rev line 301: pycompat.maplist(repo.chang...
\ 10.5% 0.02s repoview.py: pinnedrevs line 89: hidden = set(hidden - pinne...
\ 5.3% 0.01s repoview.py: <genexpr> line 58: pinned.update(rev(t[0]) for...
\ 5.3% 0.01s tags.py: readlocaltagsline 55: tagsmod.readlocaltags(repo....
| 5.3% 0.01s tags.py: _readtagsline 255: ui, repo, data.splitlines()...
| 5.3% 0.01s tags.py: _readtaghistline 337: ui, repo, lines, fn, recode...
\ 5.3% 0.01s repoview.py: _revealancestorsline 96: _revealancestors(pfunc, hid...
| 5.3% 0.01s smartset.py: _iterfilterline 73: stack = list(revs)
| 5.3% 0.01s smartset.py: __init__ line 467: l = baseset(r for r in self)
| 5.3% 0.01s smartset.py: <genexpr> line 242: data = list(data)
| 5.3% 0.01s smartset.py: _iterfilterline 467: l = baseset(r for r in self)
| 5.3% 0.01s smartset.py: <lambda> line 421: if cond(x):
\ 21.1% 0.04s context.py: status line 3249: node2, match, ignored, clea...
| 21.1% 0.04s localrepo.py: narrowmatch line 424: ctx1, r, match, listignored...
| 21.1% 0.04s context.py: _dirstatestatusline 1878: s = self._dirstatestatus(ma...
| 21.1% 0.04s dirstate.py: status line 1788: match, subrepos, ignored=ig...
| 21.1% 0.04s dirstate.py: walk line 1117: self.walk(match, subrepos, ...
\ 15.8% 0.03s dirstate.py: traverse line 1018: traverse([d], alreadynormed)
| 5.3% 0.01s dirstate.py: __contains__line 1001: if nf in dmap:
\ 5.3% 0.01s scmutil.py: __get__ line 911: ignore = self._ignore
| 5.3% 0.01s dirstate.py: _ignore line 1636: entry.obj = self.func(obj)
| 5.3% 0.01s match.py: match line 167: return matchmod.match(self....
| 5.3% 0.01s match.py: _buildkindpatsmatcherline 277: badfn=None,
| 5.3% 0.01s match.py: __init__ line 127: m = matchercls(root, kindpa...
| 5.3% 0.01s match.py: _buildmatchline 673: self._pats, self.matchfn = ...
| 5.3% 0.01s match.py: _buildregexmatchline 1368: regex, mf = _buildregexmatc...
| 5.3% 0.01s match.py: _rematcherline 1417: matcher = _rematcher(fullre...
| 5.3% 0.01s util.py: compile line 52: m = util.re.compile(regex)
| 5.3% 0.01s re.py: compile line 2168: return remod.compile(pat, f...
| 5.3% 0.01s re.py: _compile line 194: return _compile(pattern, fl...
| 5.3% 0.01s sre_compile.py: compile line 249: p = sre_compile.compile(pat...
| 5.3% 0.01s sre_parse.py: parse line 572: p = sre_parse.parse(p, flags)
| 5.3% 0.01s sre_parse.py: _parse_subline 735: p = _parse_sub(source, patt...
| 5.3% 0.01s sre_parse.py: _parse line 343: itemsappend(_parse(source, ...
| 5.3% 0.01s sre_parse.py: append line 448: subpatternappend((LITERAL, ...
\ 21.1% 0.04s ui.py: pager line 6843: ui.pager(b'status')
| 21.1% 0.04s ui.py: _runpager line 1289: if self._runpager(pagercmd,...
| 21.1% 0.04s subprocess.py: __init__ line 1347: env=procutil.tonativeenv(pr...
| 21.1% 0.04s subprocess.py: _execute_child line 394: errread, errwrite)
| 21.1% 0.04s subprocess.py: _eintr_retry_callline 1023: data = _eintr_retry_call(os...
\ 15.8% 0.03s extensions.py: load line 294: load(ui, name, path, loadin...
| 15.8% 0.03s extensions.py: _importext line 211: mod = _importext(name, path...
\ 10.5% 0.02s extensions.py: _importh line 127: mod = _importh(b"hgext3rd.%...
| 10.5% 0.02s demandimportpy2.py: _demandimportline 107: mod = __import__(pycompat.s...
| 10.5% 0.02s demandimportpy2.py: _hgextimportline 181: return _hgextimport(_origim...
| 10.5% 0.02s __init__.py: <module> line 44: return importfunc(name, glo...
\ 5.3% 0.01s demandimportpy2.py: __getattr__line 344: eh.merge(obsexchange.eh)
| 5.3% 0.01s demandimportpy2.py: _loadline 157: self._load()
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 97: _origimport, head, globals,...
| 5.3% 0.01s obsexchange.py: <module>line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: __getattr__line 36: eh.merge(obsdiscovery.eh)
| 5.3% 0.01s demandimportpy2.py: _loadline 157: self._load()
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 97: _origimport, head, globals,...
| 5.3% 0.01s obsdiscovery.py: <module>line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: __getattr__line 332: class _obshashcache(obscach...
| 5.3% 0.01s demandimportpy2.py: _loadline 157: self._load()
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 97: _origimport, head, globals,...
| 5.3% 0.01s obscache.py: <module>line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: __getattr__line 28: obsstorefilecache = localre...
| 5.3% 0.01s demandimportpy2.py: _loadline 157: self._load()
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 97: _origimport, head, globals,...
| 5.3% 0.01s localrepo.py: <module>line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: _demandimportline 30: from . import (
| 5.3% 0.01s demandimportpy2.py: processfromitemline 278: processfromitem(mod, x)
\ 5.3% 0.01s cmdutil.py: findcmd line 332: aliases, entry = cmdutil.fi...
| 5.3% 0.01s cmdutil.py: findpossibleline 859: choice, allcmds = findpossi...
\ 5.3% 0.01s extensions.py: _importh line 122: mod = _importh(b"hgext.%s" ...
| 5.3% 0.01s demandimportpy2.py: _demandimportline 107: mod = __import__(pycompat.s...
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 181: return _hgextimport(_origim...
| 5.3% 0.01s phabricator.py: <module> line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: __getattr__line 51: help.CATEGORY_ORDER.insert(
| 5.3% 0.01s demandimportpy2.py: _load line 157: self._load()
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 97: _origimport, head, globals,...
| 5.3% 0.01s help.py: <module> line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: __getattr__line 592: addtopicsymbols(b'filesets'...
| 5.3% 0.01s demandimportpy2.py: _load line 157: self._load()
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 97: _origimport, head, globals,...
| 5.3% 0.01s fileset.py: <module> line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: _demandimportline 15: from . import (
| 5.3% 0.01s demandimportpy2.py: processfromitemline 278: processfromitem(mod, x)
\ 5.3% 0.01s scmutil.py: revpair line 6782: ctx1, ctx2 = scmutil.revpai...
| 5.3% 0.01s localrepo.py: __getitem__ line 732: return repo[b'.'], repo[None]
| 5.3% 0.01s dirstate.py: p1 line 1542: node = self.dirstate.p1()
| 5.3% 0.01s localrepo.py: _dirstatevalidateline 293: return self._validate(self....
| 5.3% 0.01s localrepo.py: __get__ line 1460: self.changelog.rev(node)
| 5.3% 0.01s scmutil.py: __get__ line 106: return super(_basefilecache...
| 5.3% 0.01s localrepo.py: changelog line 1636: entry.obj = self.func(obj)
| 5.3% 0.01s store.py: changelog line 1440: return self.store.changelog...
| 5.3% 0.01s changelog.py: __init__ line 424: return changelog.changelog(...
| 5.3% 0.01s demandimportpy2.py: _load line 157: self._load()
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 97: _origimport, head, globals,...
| 5.3% 0.01s changelog.py: <module> line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: __getattr__ line 354: class changelog(revlog.revl...
| 5.3% 0.01s demandimportpy2.py: _load line 157: self._load()
| 5.3% 0.01s demandimportpy2.py: _hgextimportline 97: _origimport, head, globals,...
| 5.3% 0.01s revlog.py: <module> line 44: return importfunc(name, glo...
| 5.3% 0.01s demandimportpy2.py: _demandimportline 39: from .revlogutils.constants...
| 5.3% 0.01s demandimportpy2.py: processfromitemline 278: processfromitem(mod, x)
\ 5.3% 0.01s fancyopts.py: fancyopts line 922: args = fancyopts.fancyopts(...
---
Sample count: 103
Total time: 0.180000 seconds (0.190000 wall)
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST ACTION
https://phab.mercurial-scm.org/D7144/new/
REVISION DETAIL
https://phab.mercurial-scm.org/D7144
To: martinvonz, #hg-reviewers
Cc: mharbison72, pulkit, marmoute, mercurial-devel
More information about the Mercurial-devel
mailing list