__init__.py
173 lines
| 6.4 KiB
| text/x-python
|
PythonLexer
Augie Fackler
|
r39243 | # Copyright 2016-present Facebook. All Rights Reserved. | ||
# | ||||
# fastannotate: faster annotate implementation using linelog | ||||
# | ||||
# This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | ||||
"""yet another annotate implementation that might be faster (EXPERIMENTAL) | ||||
The fastannotate extension provides a 'fastannotate' command that makes | ||||
use of the linelog data structure as a cache layer and is expected to | ||||
be faster than the vanilla 'annotate' if the cache is present. | ||||
In most cases, fastannotate requires a setup that mainbranch is some pointer | ||||
that always moves forward, to be most efficient. | ||||
Using fastannotate together with linkrevcache would speed up building the | ||||
annotate cache greatly. Run "debugbuildlinkrevcache" before | ||||
"debugbuildannotatecache". | ||||
:: | ||||
[fastannotate] | ||||
# specify the main branch head. the internal linelog will only contain | ||||
# the linear (ignoring p2) "mainbranch". since linelog cannot move | ||||
# backwards without a rebuild, this should be something that always moves | ||||
# forward, usually it is "master" or "@". | ||||
mainbranch = master | ||||
# fastannotate supports different modes to expose its feature. | ||||
# a list of combination: | ||||
# - fastannotate: expose the feature via the "fastannotate" command which | ||||
# deals with everything in a most efficient way, and provides extra | ||||
# features like --deleted etc. | ||||
# - fctx: replace fctx.annotate implementation. note: | ||||
# a. it is less efficient than the "fastannotate" command | ||||
# b. it will make it practically impossible to access the old (disk | ||||
# side-effect free) annotate implementation | ||||
# c. it implies "hgweb". | ||||
# - hgweb: replace hgweb's annotate implementation. conflict with "fctx". | ||||
# (default: fastannotate) | ||||
modes = fastannotate | ||||
# default format when no format flags are used (default: number) | ||||
defaultformat = changeset, user, date | ||||
# serve the annotate cache via wire protocol (default: False) | ||||
# tip: the .hg/fastannotate directory is portable - can be rsynced | ||||
server = True | ||||
# build annotate cache on demand for every client request (default: True) | ||||
# disabling it could make server response faster, useful when there is a | ||||
# cronjob building the cache. | ||||
serverbuildondemand = True | ||||
# update local annotate cache from remote on demand | ||||
Augie Fackler
|
r39246 | client = False | ||
Augie Fackler
|
r39243 | |||
# path to use when connecting to the remote server (default: default) | ||||
remotepath = default | ||||
# minimal length of the history of a file required to fetch linelog from | ||||
# the server. (default: 10) | ||||
clientfetchthreshold = 10 | ||||
# for "fctx" mode, always follow renames regardless of command line option. | ||||
# this is a BC with the original command but will reduced the space needed | ||||
# for annotate cache, and is useful for client-server setup since the | ||||
# server will only provide annotate cache with default options (i.e. with | ||||
# follow). do not affect "fastannotate" mode. (default: True) | ||||
forcefollow = True | ||||
# for "fctx" mode, always treat file as text files, to skip the "isbinary" | ||||
# check. this is consistent with the "fastannotate" command and could help | ||||
# to avoid a file fetch if remotefilelog is used. (default: True) | ||||
forcetext = True | ||||
# use unfiltered repo for better performance. | ||||
unfilteredrepo = True | ||||
# sacrifice correctness in some corner cases for performance. it does not | ||||
# affect the correctness of the annotate cache being built. the option | ||||
# is experimental and may disappear in the future (default: False) | ||||
perfhack = True | ||||
""" | ||||
Augie Fackler
|
r39245 | # TODO from import: | ||
# * `branch` is probably the wrong term, throughout the code. | ||||
# | ||||
# * replace the fastannotate `modes` configuration with a collection | ||||
# of booleans. | ||||
# | ||||
# * Use the templater instead of bespoke formatting | ||||
# | ||||
# * rename the config knob for updating the local cache from a remote server | ||||
# | ||||
# * revise wireprotocol for sharing annotate files | ||||
# | ||||
# * figure out a sensible default for `mainbranch` (with the caveat | ||||
# that we probably also want to figure out a better term than | ||||
# `branch`, see above) | ||||
# | ||||
# * format changes to the revmap file (maybe use length-encoding | ||||
# instead of null-terminated file paths at least?) | ||||
Augie Fackler
|
r39243 | |||
from mercurial.i18n import _ | ||||
from mercurial import ( | ||||
error as hgerror, | ||||
localrepo, | ||||
registrar, | ||||
) | ||||
from . import ( | ||||
commands, | ||||
protocol, | ||||
) | ||||
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||||
# be specifying the version(s) of Mercurial they are tested with, or | ||||
# leave the attribute unspecified. | ||||
Augie Fackler
|
r43347 | testedwith = b'ships-with-hg-core' | ||
Augie Fackler
|
r39243 | |||
cmdtable = commands.cmdtable | ||||
configtable = {} | ||||
configitem = registrar.configitem(configtable) | ||||
Augie Fackler
|
r43347 | configitem(b'fastannotate', b'modes', default=[b'fastannotate']) | ||
configitem(b'fastannotate', b'server', default=False) | ||||
configitem(b'fastannotate', b'client', default=False) | ||||
configitem(b'fastannotate', b'unfilteredrepo', default=True) | ||||
configitem(b'fastannotate', b'defaultformat', default=[b'number']) | ||||
configitem(b'fastannotate', b'perfhack', default=False) | ||||
configitem(b'fastannotate', b'mainbranch') | ||||
configitem(b'fastannotate', b'forcetext', default=True) | ||||
configitem(b'fastannotate', b'forcefollow', default=True) | ||||
configitem(b'fastannotate', b'clientfetchthreshold', default=10) | ||||
configitem(b'fastannotate', b'serverbuildondemand', default=True) | ||||
configitem(b'fastannotate', b'remotepath', default=b'default') | ||||
Augie Fackler
|
r39243 | |||
def uisetup(ui): | ||||
Augie Fackler
|
r43347 | modes = set(ui.configlist(b'fastannotate', b'modes')) | ||
if b'fctx' in modes: | ||||
modes.discard(b'hgweb') | ||||
Augie Fackler
|
r39243 | for name in modes: | ||
Augie Fackler
|
r43347 | if name == b'fastannotate': | ||
Augie Fackler
|
r39243 | commands.registercommand() | ||
Augie Fackler
|
r43347 | elif name == b'hgweb': | ||
Augie Fackler
|
r39243 | from . import support | ||
Augie Fackler
|
r43346 | |||
Augie Fackler
|
r39243 | support.replacehgwebannotate() | ||
Augie Fackler
|
r43347 | elif name == b'fctx': | ||
Augie Fackler
|
r39243 | from . import support | ||
Augie Fackler
|
r43346 | |||
Augie Fackler
|
r39243 | support.replacefctxannotate() | ||
commands.wrapdefault() | ||||
else: | ||||
Augie Fackler
|
r43347 | raise hgerror.Abort(_(b'fastannotate: invalid mode: %s') % name) | ||
Augie Fackler
|
r39243 | |||
Augie Fackler
|
r43347 | if ui.configbool(b'fastannotate', b'server'): | ||
Augie Fackler
|
r39243 | protocol.serveruisetup(ui) | ||
Augie Fackler
|
r43346 | |||
Augie Fackler
|
r39247 | def extsetup(ui): | ||
Augie Fackler
|
r39243 | # fastannotate has its own locking, without depending on repo lock | ||
Augie Fackler
|
r39247 | # TODO: avoid mutating this unless the specific repo has it enabled | ||
Augie Fackler
|
r43347 | localrepo.localrepository._wlockfreeprefix.add(b'fastannotate/') | ||
Augie Fackler
|
r39243 | |||
Augie Fackler
|
r43346 | |||
Augie Fackler
|
r39243 | def reposetup(ui, repo): | ||
Augie Fackler
|
r43347 | if ui.configbool(b'fastannotate', b'client'): | ||
Augie Fackler
|
r39243 | protocol.clientreposetup(ui, repo) | ||