dir shadows a built-in. We use it throughout the manifest code, which
is unfortunate.
This commit updates just manifestrevlog to be more well behaved.
.. api:: renamed manifest.manifestrevlog.init dir argument to tree
hg-reviewers |
dir shadows a built-in. We use it throughout the manifest code, which
is unfortunate.
This commit updates just manifestrevlog to be more well behaved.
.. api:: renamed manifest.manifestrevlog.init dir argument to tree
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Path | Packages | |||
---|---|---|---|---|
M | mercurial/bundlerepo.py (2 lines) | |||
M | mercurial/changegroup.py (2 lines) | |||
M | mercurial/manifest.py (25 lines) | |||
M | mercurial/upgrade.py (2 lines) |
Status | Author | Revision | |
---|---|---|---|
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg |
self.filteredrevs = () | self.filteredrevs = () | ||||
return changelog.changelog.revision(self, nodeorrev, raw=True) | return changelog.changelog.revision(self, nodeorrev, raw=True) | ||||
finally: | finally: | ||||
self.filteredrevs = oldfilter | self.filteredrevs = oldfilter | ||||
class bundlemanifest(bundlerevlog, manifest.manifestrevlog): | class bundlemanifest(bundlerevlog, manifest.manifestrevlog): | ||||
def __init__(self, opener, cgunpacker, linkmapper, dirlogstarts=None, | def __init__(self, opener, cgunpacker, linkmapper, dirlogstarts=None, | ||||
dir=''): | dir=''): | ||||
manifest.manifestrevlog.__init__(self, opener, dir=dir) | manifest.manifestrevlog.__init__(self, opener, tree=dir) | ||||
bundlerevlog.__init__(self, opener, self.indexfile, cgunpacker, | bundlerevlog.__init__(self, opener, self.indexfile, cgunpacker, | ||||
linkmapper) | linkmapper) | ||||
if dirlogstarts is None: | if dirlogstarts is None: | ||||
dirlogstarts = {} | dirlogstarts = {} | ||||
if self.bundle.version == "03": | if self.bundle.version == "03": | ||||
dirlogstarts = _getfilestarts(self.bundle) | dirlogstarts = _getfilestarts(self.bundle) | ||||
self._dirlogstarts = dirlogstarts | self._dirlogstarts = dirlogstarts | ||||
self._linkmapper = linkmapper | self._linkmapper = linkmapper |
fclnodes[n] = clnode | fclnodes[n] = clnode | ||||
return clnode | return clnode | ||||
return lookupmflinknode | return lookupmflinknode | ||||
while tmfnodes: | while tmfnodes: | ||||
tree, nodes = tmfnodes.popitem() | tree, nodes = tmfnodes.popitem() | ||||
store = dirlog(tree) | store = dirlog(tree) | ||||
if not self._filematcher.visitdir(store._dir[:-1] or '.'): | if not self._filematcher.visitdir(store._tree[:-1] or '.'): | ||||
prunednodes = [] | prunednodes = [] | ||||
else: | else: | ||||
frev, flr = store.rev, store.linkrev | frev, flr = store.rev, store.linkrev | ||||
prunednodes = [n for n in nodes | prunednodes = [n for n in nodes | ||||
if flr(frev(n)) not in commonrevs] | if flr(frev(n)) not in commonrevs] | ||||
if tree and not prunednodes: | if tree and not prunednodes: | ||||
continue | continue |
self._dirty = True | self._dirty = True | ||||
self.write() | self.write() | ||||
self._read = False | self._read = False | ||||
class manifestrevlog(revlog.revlog): | class manifestrevlog(revlog.revlog): | ||||
'''A revlog that stores manifest texts. This is responsible for caching the | '''A revlog that stores manifest texts. This is responsible for caching the | ||||
full-text manifest contents. | full-text manifest contents. | ||||
''' | ''' | ||||
def __init__(self, opener, dir='', dirlogcache=None, indexfile=None, | def __init__(self, opener, tree='', dirlogcache=None, indexfile=None, | ||||
treemanifest=False): | treemanifest=False): | ||||
"""Constructs a new manifest revlog | """Constructs a new manifest revlog | ||||
`indexfile` - used by extensions to have two manifests at once, like | `indexfile` - used by extensions to have two manifests at once, like | ||||
when transitioning between flatmanifeset and treemanifests. | when transitioning between flatmanifeset and treemanifests. | ||||
`treemanifest` - used to indicate this is a tree manifest revlog. Opener | `treemanifest` - used to indicate this is a tree manifest revlog. Opener | ||||
options can also be used to make this a tree manifest revlog. The opener | options can also be used to make this a tree manifest revlog. The opener | ||||
if opts is not None: | if opts is not None: | ||||
cachesize = opts.get('manifestcachesize', cachesize) | cachesize = opts.get('manifestcachesize', cachesize) | ||||
optiontreemanifest = opts.get('treemanifest', False) | optiontreemanifest = opts.get('treemanifest', False) | ||||
self._treeondisk = optiontreemanifest or treemanifest | self._treeondisk = optiontreemanifest or treemanifest | ||||
self._fulltextcache = manifestfulltextcache(cachesize) | self._fulltextcache = manifestfulltextcache(cachesize) | ||||
if dir: | if tree: | ||||
assert self._treeondisk, 'opts is %r' % opts | assert self._treeondisk, 'opts is %r' % opts | ||||
if indexfile is None: | if indexfile is None: | ||||
indexfile = '00manifest.i' | indexfile = '00manifest.i' | ||||
if dir: | if tree: | ||||
indexfile = "meta/" + dir + indexfile | indexfile = "meta/" + tree + indexfile | ||||
self._dir = dir | self._tree = tree | ||||
# The dirlogcache is kept on the root manifest log | # The dirlogcache is kept on the root manifest log | ||||
if dir: | if tree: | ||||
self._dirlogcache = dirlogcache | self._dirlogcache = dirlogcache | ||||
else: | else: | ||||
self._dirlogcache = {'': self} | self._dirlogcache = {'': self} | ||||
super(manifestrevlog, self).__init__(opener, indexfile, | super(manifestrevlog, self).__init__(opener, indexfile, | ||||
# only root indexfile is cached | # only root indexfile is cached | ||||
checkambig=not bool(dir), | checkambig=not bool(tree), | ||||
mmaplargeindex=True) | mmaplargeindex=True) | ||||
def _setupmanifestcachehooks(self, repo): | def _setupmanifestcachehooks(self, repo): | ||||
"""Persist the manifestfulltextcache on lock release""" | """Persist the manifestfulltextcache on lock release""" | ||||
if not util.safehasattr(repo, '_lockref'): | if not util.safehasattr(repo, '_lockref'): | ||||
return | return | ||||
self._fulltextcache._opener = repo.cachevfs | self._fulltextcache._opener = repo.cachevfs | ||||
@property | @property | ||||
def fulltextcache(self): | def fulltextcache(self): | ||||
return self._fulltextcache | return self._fulltextcache | ||||
def clearcaches(self, clear_persisted_data=False): | def clearcaches(self, clear_persisted_data=False): | ||||
super(manifestrevlog, self).clearcaches() | super(manifestrevlog, self).clearcaches() | ||||
self._fulltextcache.clear(clear_persisted_data=clear_persisted_data) | self._fulltextcache.clear(clear_persisted_data=clear_persisted_data) | ||||
self._dirlogcache = {self._dir: self} | self._dirlogcache = {self._tree: self} | ||||
def dirlog(self, d): | def dirlog(self, d): | ||||
if d: | if d: | ||||
assert self._treeondisk | assert self._treeondisk | ||||
if d not in self._dirlogcache: | if d not in self._dirlogcache: | ||||
mfrevlog = manifestrevlog(self.opener, d, | mfrevlog = manifestrevlog(self.opener, d, | ||||
self._dirlogcache, | self._dirlogcache, | ||||
treemanifest=self._treeondisk) | treemanifest=self._treeondisk) | ||||
n = self.addrevision(text, transaction, link, p1, p2, cachedelta) | n = self.addrevision(text, transaction, link, p1, p2, cachedelta) | ||||
else: | else: | ||||
# The first parent manifest isn't already loaded, so we'll | # The first parent manifest isn't already loaded, so we'll | ||||
# just encode a fulltext of the manifest and pass that | # just encode a fulltext of the manifest and pass that | ||||
# through to the revlog layer, and let it handle the delta | # through to the revlog layer, and let it handle the delta | ||||
# process. | # process. | ||||
if self._treeondisk: | if self._treeondisk: | ||||
assert readtree, "readtree must be set for treemanifest writes" | assert readtree, "readtree must be set for treemanifest writes" | ||||
m1 = readtree(self._dir, p1) | m1 = readtree(self._tree, p1) | ||||
m2 = readtree(self._dir, p2) | m2 = readtree(self._tree, p2) | ||||
n = self._addtree(m, transaction, link, m1, m2, readtree) | n = self._addtree(m, transaction, link, m1, m2, readtree) | ||||
arraytext = None | arraytext = None | ||||
else: | else: | ||||
text = m.text() | text = m.text() | ||||
n = self.addrevision(text, transaction, link, p1, p2) | n = self.addrevision(text, transaction, link, p1, p2) | ||||
arraytext = bytearray(text) | arraytext = bytearray(text) | ||||
if arraytext is not None: | if arraytext is not None: | ||||
self.fulltextcache[n] = arraytext | self.fulltextcache[n] = arraytext | ||||
return n | return n | ||||
def _addtree(self, m, transaction, link, m1, m2, readtree): | def _addtree(self, m, transaction, link, m1, m2, readtree): | ||||
# If the manifest is unchanged compared to one parent, | # If the manifest is unchanged compared to one parent, | ||||
# don't write a new revision | # don't write a new revision | ||||
if self._dir != '' and (m.unmodifiedsince(m1) or m.unmodifiedsince(m2)): | if self._tree != '' and (m.unmodifiedsince(m1) or m.unmodifiedsince( | ||||
m2)): | |||||
return m.node() | return m.node() | ||||
def writesubtree(subm, subp1, subp2): | def writesubtree(subm, subp1, subp2): | ||||
sublog = self.dirlog(subm.dir()) | sublog = self.dirlog(subm.dir()) | ||||
sublog.add(subm, transaction, link, subp1, subp2, None, None, | sublog.add(subm, transaction, link, subp1, subp2, None, None, | ||||
readtree=readtree) | readtree=readtree) | ||||
m.writesubtrees(m1, m2, writesubtree) | m.writesubtrees(m1, m2, writesubtree) | ||||
text = m.dirtext() | text = m.dirtext() | ||||
n = None | n = None | ||||
if self._dir != '': | if self._tree != '': | ||||
# Double-check whether contents are unchanged to one parent | # Double-check whether contents are unchanged to one parent | ||||
if text == m1.dirtext(): | if text == m1.dirtext(): | ||||
n = m1.node() | n = m1.node() | ||||
elif text == m2.dirtext(): | elif text == m2.dirtext(): | ||||
n = m2.node() | n = m2.node() | ||||
if not n: | if not n: | ||||
n = self.addrevision(text, transaction, link, m1.node(), m2.node()) | n = self.addrevision(text, transaction, link, m1.node(), m2.node()) |
"""Obtain a revlog from a repo path. | """Obtain a revlog from a repo path. | ||||
An instance of the appropriate class is returned. | An instance of the appropriate class is returned. | ||||
""" | """ | ||||
if path == '00changelog.i': | if path == '00changelog.i': | ||||
return changelog.changelog(repo.svfs) | return changelog.changelog(repo.svfs) | ||||
elif path.endswith('00manifest.i'): | elif path.endswith('00manifest.i'): | ||||
mandir = path[:-len('00manifest.i')] | mandir = path[:-len('00manifest.i')] | ||||
return manifest.manifestrevlog(repo.svfs, dir=mandir) | return manifest.manifestrevlog(repo.svfs, tree=mandir) | ||||
else: | else: | ||||
#reverse of "/".join(("data", path + ".i")) | #reverse of "/".join(("data", path + ".i")) | ||||
return filelog.filelog(repo.svfs, path[5:-2]) | return filelog.filelog(repo.svfs, path[5:-2]) | ||||
def _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse, deltabothparents): | def _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse, deltabothparents): | ||||
"""Copy revlogs between 2 repos.""" | """Copy revlogs between 2 repos.""" | ||||
revcount = 0 | revcount = 0 | ||||
srcsize = 0 | srcsize = 0 |