diff --git a/hgext3rd/perftweaks.py b/hgext3rd/perftweaks.py --- a/hgext3rd/perftweaks.py +++ b/hgext3rd/perftweaks.py @@ -16,8 +16,10 @@ from mercurial import ( branchmap, + commands, dispatch, extensions, + localrepo, merge, namespaces, phases, @@ -40,6 +42,7 @@ wrapfunction(branchmap, 'read', _branchmapread) wrapfunction(branchmap, 'replacecache', _branchmapreplacecache) wrapfunction(branchmap, 'updatecache', _branchmapupdatecache) + wrapfunction(commands, '_docommit', _docommit) if ui.configbool('perftweaks', 'preferdeltas'): wrapfunction(revlog.revlog, '_isgooddelta', _isgooddelta) @@ -158,6 +161,34 @@ partial.update(repo, None) repo._branchcaches[repo.filtername] = partial +# _docommit accesses "branchheads" just to decide whether to show "(created new +# head)" or not. Accessing branchheads requires calling "headrevs()" which is +# expensive since it scans entire changelog. We can just test if "." has any +# existing children to know if there is a new head or not. +def _singlebranchheads(orig, repo, branch): + unfi = repo.unfiltered() + dotrev = unfi['.'].rev() + children = None + try: + children = unfi.changelog.index._children(dotrev) + except Exception: + pass + if (repo.ui.configbool('tweakdefaults', 'allowbranch', True) + or children is None): + return orig(repo, branch) + if children: + # dotrev is not a head. Return a faked head so the new rev is not part + # of it and "created new head" will be printed. + return ['\0' * 20] + else: + # dotrev is a head. Return a list containing that head. + return [repo.changelog.node(dotrev)] + +def _docommit(orig, ui, repo, *pats, **opts): + with extensions.wrappedfunction(localrepo.localrepository, + 'branchheads', _singlebranchheads): + return orig(ui, repo, *pats, **opts) + def _branchmapwrite(orig, self, repo): if repo.ui.configbool('perftweaks', 'disablebranchcache'): # Since we don't read the branchcache, don't bother writing it.