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 | ||||