##// END OF EJS Templates
manifest: subclass the new `repository.imanifestlog` Protocol class...
manifest: subclass the new `repository.imanifestlog` Protocol class This is the same transformation as 3a90a6fd710d did for dirstate, but the CamelCase naming was already cleaned up here. See 4ef6dbc27a99 for the benefits of explicit subclassing.

File last commit:

r53060:7346f93b default
r53381:d371efa7 default
Show More
statichttprepo.py
284 lines | 8.4 KiB | text/x-python | PythonLexer
mpm@selenic.com
Separate out old-http support...
r1101 # statichttprepo.py - simple http repository class for mercurial
#
# This provides read-only repo access to repositories exported via static http
#
Raphaël Gomès
contributor: change mentions of mpm to olivia...
r47575 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
mpm@selenic.com
Separate out old-http support...
r1101 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
mpm@selenic.com
Separate out old-http support...
r1101
Matt Harbison
typing: add `from __future__ import annotations` to most files...
r52756 from __future__ import annotations
Gregory Szorc
statichttprepo: use absolute_import
r25978
import errno
from .i18n import _
Joerg Sonnenberger
node: introduce nodeconstants class...
r47538 from .node import sha1nodeconstants
Gregory Szorc
statichttprepo: use absolute_import
r25978 from . import (
Martijn Pieters
branchmap: encapsulate cache updating in the map itself...
r41764 branchmap,
Gregory Szorc
statichttprepo: use absolute_import
r25978 changelog,
error,
localrepo,
manifest,
namespaces,
Yuya Nishihara
statichttprepo: do not use platform path separator to build a URL...
r34944 pathutil,
Gregory Szorc
statichttprepo: use str to appease Python 3...
r41452 pycompat,
share-safe: add support for static-http repository...
r49514 requirements as requirementsmod,
Gregory Szorc
statichttprepo: use absolute_import
r25978 url,
util,
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.statichttprepo'...
r31241 vfs as vfsmod,
Gregory Szorc
statichttprepo: use absolute_import
r25978 )
urlutil: extract `url` related code from `util` into the new module...
r47669 from .utils import (
urlutil,
)
Bryan O'Sullivan
Move urllib error handling from revlog into statichttprepo, where it belongs.
r1325
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 urlerr = util.urlerr
urlreq = util.urlreq
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
py3: use class X: instead of class X(object):...
r49801 class httprangereader:
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274 def __init__(self, url, opener):
# we assume opener has HTTPRangeHandler
self.url = url
self.pos = 0
self.opener = opener
Nicolas Dumazet
static-http: mimic more closely localrepo (issue2164: allow clone -r )...
r11066 self.name = url
Gregory Szorc
statichttprepo: implement __enter__ and __exit__ on httprangeheader...
r27705
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.close()
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274 def seek(self, pos):
self.pos = pos
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
statichttprepo: stop shadowing the `bytes` builtin...
r52793 def read(self, n: int = -1):
Gregory Szorc
statichttprepo: use str to appease Python 3...
r41452 req = urlreq.request(pycompat.strurl(self.url))
Matt Harbison
statichttprepo: fix `httprangereader.read()` for py3...
r52792 end = ''
Matt Harbison
statichttprepo: stop shadowing the `bytes` builtin...
r52793 if n == 0:
Matt Harbison
statichttprepo: fix `httprangereader.read()` for py3...
r52792 return b''
Matt Harbison
statichttprepo: stop shadowing the `bytes` builtin...
r52793 elif n > 0:
end = "%d" % (self.pos + n - 1)
Alexander Boyd
statichttprepo: don't send Range header when requesting entire file...
r16882 if self.pos or end:
Augie Fackler
cleanup: remove pointless r-prefixes on single-quoted strings...
r43906 req.add_header('Range', 'bytes=%d-%s' % (self.pos, end))
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274
Bryan O'Sullivan
Move urllib error handling from revlog into statichttprepo, where it belongs.
r1325 try:
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274 f = self.opener.open(req)
data = f.read()
Augie Fackler
statichttprepo: remove wrong getattr ladder...
r25196 code = f.code
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 except urlerr.httperror as inst:
Dirkjan Ochtman
make static-http work with empty repos (issue965)
r6028 num = inst.code == 404 and errno.ENOENT or None
Joerg Sonnenberger
statichttprepo: explicitly convert error message to str (issue6247)...
r46818 # Explicitly convert the exception to str as Py3 will try
# convert it to local encoding and with as the HTTPResponse
# instance doesn't support encode.
raise IOError(num, str(inst))
timeless
pycompat: switch to util.urlreq/util.urlerr for py3 compat
r28883 except urlerr.urlerror as inst:
Gregory Szorc
statichttprepo: use URLError.reason directly...
r41451 raise IOError(None, inst.reason)
mpm@selenic.com
Separate out old-http support...
r1101
Patrick Mezard
statichttprepo: handle remote not supporting Range headers...
r8612 if code == 200:
# HTTPRangeHandler does nothing if remote does not support
# Range headers and returns the full entity. Let's slice it.
Matt Harbison
statichttprepo: stop shadowing the `bytes` builtin...
r52793 if n > 0 and (self.pos + n) < len(data):
data = data[self.pos : self.pos + n]
Matt Harbison
statichttprepo: fix `httprangereader.read()` for py3...
r52792 elif self.pos < len(data):
data = data[self.pos :]
Patrick Mezard
statichttprepo: handle remote not supporting Range headers...
r8612 else:
Matt Harbison
statichttprepo: fix `httprangereader.read()` for py3...
r52792 data = b''
Matt Harbison
statichttprepo: stop shadowing the `bytes` builtin...
r52793 elif 0 < n < len(data):
data = data[:n]
Patrick Mezard
statichttprepo: handle remote not supporting Range headers...
r8612 self.pos += len(data)
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274 return data
Augie Fackler
formatting: blacken the codebase...
r43346
Siddharth Agarwal
statichttprepo.httprangeheader: implement readlines...
r20055 def readlines(self):
return self.read().splitlines(True)
Augie Fackler
formatting: blacken the codebase...
r43346
Nicolas Dumazet
static-http: mimic more closely localrepo (issue2164: allow clone -r )...
r11066 def __iter__(self):
Siddharth Agarwal
statichttprepo.httprangeheader: implement readlines...
r20055 return iter(self.readlines())
Augie Fackler
formatting: blacken the codebase...
r43346
Nicolas Dumazet
static-http: mimic more closely localrepo (issue2164: allow clone -r )...
r11066 def close(self):
pass
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
statichttprepo: move HTTPRangeHandler from byterange and delete the latter...
r36443 # _RangeError and _HTTPRangeHandler were originally in byterange.py,
# which was itself extracted from urlgrabber. See the last version of
# byterange.py from history if you need more information.
class _RangeError(IOError):
"""Error raised when an unsatisfiable range is requested."""
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
statichttprepo: move HTTPRangeHandler from byterange and delete the latter...
r36443 class _HTTPRangeHandler(urlreq.basehandler):
"""Handler that enables HTTP Range headers.
This was extremely simple. The Range header is a HTTP feature to
begin with so all this class does is tell urllib2 that the
"206 Partial Content" response from the HTTP server is what we
expected.
"""
def http_error_206(self, req, fp, code, msg, hdrs):
# 206 Partial Content Response
r = urlreq.addinfourl(fp, hdrs, req.get_full_url())
r.code = code
r.msg = msg
return r
def http_error_416(self, req, fp, code, msg, hdrs):
# HTTP's Range Not Satisfiable error
Matt Harbison
statichttprepo: unbyteify several IOError messages...
r51174 raise _RangeError('Requested Range Not Satisfiable')
Augie Fackler
statichttprepo: move HTTPRangeHandler from byterange and delete the latter...
r36443
Augie Fackler
formatting: blacken the codebase...
r43346
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274 def build_opener(ui, authinfo):
# urllib cannot handle URLs with embedded user or passwd
urlopener = url.opener(ui, authinfo)
Augie Fackler
statichttprepo: move HTTPRangeHandler from byterange and delete the latter...
r36443 urlopener.add_handler(_HTTPRangeHandler())
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274
Pierre-Yves David
vfs: use 'vfs' module directly in 'mercurial.statichttprepo'...
r31241 class statichttpvfs(vfsmod.abstractvfs):
Dan Villiom Podlaski Christiansen
statichttprepo: make the opener a subclass of abstractopener
r14091 def __init__(self, base):
self.base = base
vfs: give all vfs an options attribute by default...
r43295 self.options = {}
Dan Villiom Podlaski Christiansen
statichttprepo: make the opener a subclass of abstractopener
r14091
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 def __call__(self, path, mode=b'r', *args, **kw):
if mode not in (b'r', b'rb'):
Matt Harbison
statichttprepo: unbyteify several IOError messages...
r51174 raise IOError('Permission denied')
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 f = b"/".join((self.base, urlreq.quote(path)))
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274 return httprangereader(f, urlopener)
Matt Harbison
vfs: use @abstractmethod instead of homebrewing abstract methods...
r52777 def _auditpath(self, path: bytes, mode: bytes) -> None:
raise NotImplementedError
Matt Harbison
statichttprepo: fix the vfs.join() method to match the base class definition...
r51173 def join(self, path, *insidef):
FUJIWARA Katsunori
vfs: define "join()" in each classes derived from "abstractvfs"...
r17725 if path:
Matt Harbison
statichttprepo: fix the vfs.join() method to match the base class definition...
r51173 return pathutil.join(self.base, path, *insidef)
FUJIWARA Katsunori
vfs: define "join()" in each classes derived from "abstractvfs"...
r17725 else:
return self.base
FUJIWARA Katsunori
scmutil: rename classes from "opener" to "vfs"...
r17649 return statichttpvfs
mpm@selenic.com
Separate out old-http support...
r1101
Augie Fackler
formatting: blacken the codebase...
r43346
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 class statichttppeer(localrepo.localpeer):
def local(self):
return None
Augie Fackler
formatting: blacken the codebase...
r43346
Sune Foldager
peer: introduce canpush and improve error message
r17193 def canpush(self):
return False
Peter Arrenbrecht
peer: introduce real peer classes...
r17192
Augie Fackler
formatting: blacken the codebase...
r43346
class statichttprepository(
localrepo.localrepository, localrepo.revlogfilestorage
):
FUJIWARA Katsunori
localrepo: make supported features manageable in each repositories individually...
r19778 supported = localrepo.localrepository._basesupported
Matt Harbison
manifest: drop the CamelCase name for `manifest.manifestlog`...
r52963 manifestlog: manifest.manifestlog
Matt Harbison
typing: lock in new pytype gains from making revlog related classes typeable...
r52719
mpm@selenic.com
Separate out old-http support...
r1101 def __init__(self, ui, path):
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 self._url = path
mpm@selenic.com
Separate out old-http support...
r1101 self.ui = ui
Benoit Boissinot
switch to the .hg/store layout, fix the tests
r3853
Nicolas Dumazet
static-http: mimic more closely localrepo (issue2164: allow clone -r )...
r11066 self.root = path
urlutil: extract `url` related code from `util` into the new module...
r47669 u = urlutil.url(path.rstrip(b'/') + b"/.hg")
Brodie Rao
httprepo/sshrepo: use url.url...
r13819 self.path, authinfo = u.authinfo()
Benoit Boissinot
statichttprepo: cleanups, use url.py (proxy, password support)...
r7274
Pierre-Yves David
statichttp: use 'repo.vfs' as the main attribute...
r31147 vfsclass = build_opener(ui, authinfo)
self.vfs = vfsclass(self.path)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.cachevfs = vfsclass(self.vfs.join(b'cache'))
Pierre-Yves David
phases: mechanism to allow extension to alter initial computation of phase...
r15922 self._phasedefaults = []
Dirkjan Ochtman
make static-http work with empty repos (issue965)
r6028
Ryan McElroy
namespaces: remove weakref; always pass in repo...
r23561 self.names = namespaces.namespaces()
Gregory Szorc
localrepo: move filtername to __init__...
r32730 self.filtername = None
repoview: introduce a `experimental.extra-filter-revs` config...
r42417 self._extrafilterid = None
Raphaël Gomès
sidedata-exchange: add `wanted_sidedata` and `sidedata_computers` to repos...
r47447 self._wanted_sidedata = set()
statichttp: add the missing `features` attribute...
r47999 self.features = set()
Sean Farley
namespaces: add bookmarks to the names data structure...
r23558
Benoit Boissinot
add "requires" file to the repo, specifying the requirements
r3851 try:
Gregory Szorc
statichttprepo: use new functions for requirements validation...
r39730 requirements = set(self.vfs.read(b'requires').splitlines())
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
Adrian Buehlmann
introduce new function scmutil.readrequires...
r14482 requirements = set()
Thomas Arendsen Hein
Fix Debian bug #494889 (fetching from static-http://... broken)...
r7178 # check if it is a non-empty old-style repository
try:
Matt Harbison
statichttprepo: use a context manager to handle a file descriptor...
r52791 with self.vfs(b"00changelog.i") as fp:
fp.read(1)
Manuel Jacob
py3: catch FileNotFoundError instead of checking errno == ENOENT
r50201 except FileNotFoundError:
Thomas Arendsen Hein
Fix Debian bug #494889 (fetching from static-http://... broken)...
r7178 # we do not care about empty old-style repositories here
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b"'%s' does not appear to be an hg repository") % path
Matt Mackall
error: move repo errors...
r7637 raise error.RepoError(msg)
share-safe: add support for static-http repository...
r49514 if requirementsmod.SHARESAFE_REQUIREMENT in requirements:
storevfs = vfsclass(self.vfs.join(b'store'))
requirements |= set(storevfs.read(b'requires').splitlines())
Benoit Boissinot
add "requires" file to the repo, specifying the requirements
r3851
Gregory Szorc
statichttprepo: use new functions for requirements validation...
r39730 supportedrequirements = localrepo.gathersupportedrequirements(ui)
Augie Fackler
formatting: blacken the codebase...
r43346 localrepo.ensurerequirementsrecognized(
requirements, supportedrequirements
)
Gregory Szorc
localrepo: move requirements reasonability testing to own function...
r39731 localrepo.ensurerequirementscompatible(ui, requirements)
Joerg Sonnenberger
node: introduce nodeconstants class...
r47538 self.nodeconstants = sha1nodeconstants
self.nullid = self.nodeconstants.nullid
Gregory Szorc
statichttprepo: use new functions for requirements validation...
r39730
Benoit Boissinot
add "requires" file to the repo, specifying the requirements
r3851 # setup store
Gregory Szorc
localrepo: move store() from store module...
r39734 self.store = localrepo.makestore(requirements, self.path, vfsclass)
Matt Mackall
statichttp: use store class...
r6897 self.spath = self.store.path
Angel Ezquerra
localrepo: remove all external users of localrepo.sopener...
r23878 self.svfs = self.store.opener
Raphaël Gomès
revlog: add the glue to use the Rust `InnerRevlog` from Python...
r53060 # We can't use Rust because the Rust code cannot cope with the
# `httprangereader` (yet?)
self.svfs.rust_compatible = False
Matt Mackall
statichttp: use store class...
r6897 self.sjoin = self.store.join
Idan Kamara
scmutil: update cached copy when filecached attribute is assigned (issue3263)...
r16115 self._filecache = {}
Peter Arrenbrecht
peer: introduce real peer classes...
r17192 self.requirements = requirements
Benoit Boissinot
add "requires" file to the repo, specifying the requirements
r3851
Joerg Sonnenberger
node: introduce nodeconstants class...
r47538 rootmanifest = manifest.manifestrevlog(self.nodeconstants, self.svfs)
Augie Fackler
formatting: blacken the codebase...
r43346 self.manifestlog = manifest.manifestlog(
self.svfs, self, rootmanifest, self.narrowmatch()
)
Angel Ezquerra
localrepo: remove all external users of localrepo.sopener...
r23878 self.changelog = changelog.changelog(self.svfs)
Greg Ward
localrepo: rename in-memory tag cache instance attributes (issue548)....
r9146 self._tags = None
mpm@selenic.com
Separate out old-http support...
r1101 self.nodetagscache = None
Martijn Pieters
branchmap: encapsulate cache updating in the map itself...
r41764 self._branchcaches = branchmap.BranchMapCache()
Durham Goode
revbranchcache: move out of branchmap onto localrepo...
r24373 self._revbranchcache = None
Benoit Boissinot
cleanup of revlog.group when repository is local...
r1598 self.encodepats = None
self.decodepats = None
Durham Goode
revbranchcache: move cache writing to the transaction finalizer...
r24377 self._transref = None
dirstate: only reload the dirstate when it may have changed...
r51023 self._dirstate = None
Peter Arrenbrecht
peer: introduce real peer classes...
r17192
def _restrictcapabilities(self, caps):
Pierre-Yves David
statichttp: respect localrepo _restrictcapabilities...
r20962 caps = super(statichttprepository, self)._restrictcapabilities(caps)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return caps.difference([b"pushkey"])
mpm@selenic.com
Separate out old-http support...
r1101
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 def url(self):
Matt Mackall
Autodetect static-http
r7211 return self._url
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673
mpm@selenic.com
Separate out old-http support...
r1101 def local(self):
return False
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740
Manuel Jacob
pull: add --remote-hidden option and pass it through peer creation...
r51309 def peer(self, path=None, remotehidden=False):
return statichttppeer(self, path=path, remotehidden=remotehidden)
Peter Arrenbrecht
peer: introduce real peer classes...
r17192
Gregory Szorc
statichttprepo: implement wlock() (issue5613)...
r33605 def wlock(self, wait=True):
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.LockUnavailable(
0,
lock: properly convert error to bytes...
r52179 pycompat.sysstr(_(b'lock not available')),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'lock',
_(b'cannot lock static-http repository'),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
statichttprepo: implement wlock() (issue5613)...
r33605
Martin Geisler
do not pretend to lock static-http repositories (issue994)
r7005 def lock(self, wait=True):
Pulkit Goyal
statichttprepo: use LockUnavailable() instead of Abort() for lock (API)...
r46004 raise error.LockUnavailable(
0,
lock: properly convert error to bytes...
r52179 pycompat.sysstr(_(b'lock not available')),
Pulkit Goyal
statichttprepo: use LockUnavailable() instead of Abort() for lock (API)...
r46004 b'lock',
_(b'cannot lock static-http repository'),
)
Martin Geisler
do not pretend to lock static-http repositories (issue994)
r7005
Pierre-Yves David
statichttprepo: do not try to write caches...
r29738 def _writecaches(self):
Augie Fackler
formatting: blacken the codebase...
r43346 pass # statichttprepository are read only
Pierre-Yves David
statichttprepo: do not try to write caches...
r29738
Manuel Jacob
pull: add --remote-hidden option and pass it through peer creation...
r51309 def make_peer(
ui, path, create, intents=None, createopts=None, remotehidden=False
):
Vadim Gelfer
clean up hg.py: move repo constructor code into each repo module
r2740 if create:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot create new static-http repository'))
peer: pass the `path` to the statichttp peer...
r50657 url = path.loc[7:]
Manuel Jacob
pull: add --remote-hidden option and pass it through peer creation...
r51309 return statichttprepository(ui, url).peer(
path=path, remotehidden=remotehidden
)