def readdelta(self, shallow=False): p1, p2 = self.parents mf = self.read() parentmf = self._manifestlog[p1].read() treemf = mf._treemanifest() ptreemf = parentmf._treemanifest() if treemf is not None and ptreemf is not None: diff = ptreemf.diff(treemf) result = manifest.manifestdict() for path, ((oldn, oldf), (newn, newf)) in diff.iteritems(): if newn is not None: result[path] = newn if newf: result.setflag(path, newf) return mf._converttohybridmanifest(result) rl = self._revlog if rl._usemanifestv2: # Need to perform a slow delta r0 = revlog.deltaparent(revlog.rev(self._node)) m0 = manifest.manifestctx(self._manifestlog, rl.node(r0)).read() m1 = self.read() md = manifest.manifestdict() for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).iteritems(): if n1: md[f] = n1 if fl1: md.setflag(f, fl1) return md r = rl.rev(self._node) d = mdiff.patchtext(rl.revdiff(rl.deltaparent(r), r)) return manifest.manifestdict(d)
def __init__(self, *args, **kwargs): super(HgCommitBuilder, self).__init__(*args, **kwargs) self._any_changes = False self._changelist = [] self._removed = [] self._changed = [] self._hgrepo = self.repository._hgrepo self._transaction = self._hgrepo.transaction("commit") self._parent_changeset_ids = [] self._parent_manifests = [] self._parent_manifest_ids = [] self._extra = {} self._linkrev = len(self.repository._hgrepo) self._validate_revprops(self._revprops) for i in range(2): if len(self.parents) > i: csid = self.repository.lookup_bzr_revision_id( self.parents[i])[0] hgchange = self._hgrepo.changelog.read(csid) manifest_id = hgchange[0] manifest = self._hgrepo.manifestlog[manifest_id].read() self._parent_manifest_ids.append(manifest_id) self._parent_manifests.append(manifest) self._parent_changeset_ids.append(csid) else: self._parent_manifests.append(manifestdict()) self._parent_manifest_ids.append(mercurial.node.nullid) self._parent_changeset_ids.append(mercurial.node.nullid) self._manifest = self._parent_manifests[0].copy()
def testIntersectFiles(self): m = manifestmod.manifestdict(A_HUGE_MANIFEST) m2 = m.intersectfiles(['file1', 'file200', 'file300']) w = ('file1\0%sx\n' 'file200\0%sl\n' 'file300\0%s\n') % (HASH_2, HASH_1, HASH_1) self.assertEqual(w, m2.text())
def loadflat(): # This should eventually be made lazy loaded, so consumers can # access the node/p1/linkrev data without having to parse the # whole manifest. data = self._revlog.revision(self._node) arraytext = bytearray(data) self._revlog._fulltextcache[self._node] = arraytext return manifest.manifestdict(data)
def _flatmanifest(self): if self.__flatmanifest is None: if self.loadflat is not None: # Load the manifest and cache it. self.__flatmanifest = self.loadflat() if isinstance(self.__flatmanifest, hybridmanifest): # See comment in extsetup to see why we have to do that self.__flatmanifest = self.__flatmanifest._flatmanifest() elif self.__cachedmanifest not in (None, False): # build a flat manifest from the text of the fastmanifest. self.__flatmanifest = manifest.manifestdict( self.__cachedmanifest.text()) elif self.__treemanifest not in (None, False): # build a flat manifest from the text of the fastmanifest. self.__flatmanifest = manifest.manifestdict( self.__treemanifest.text()) assert isinstance(self.__flatmanifest, manifest.manifestdict) return self.__flatmanifest
def readfast(self, shallow=False): """readfast returns a manifest containing either A) the list of files added/modified in this manifest or B) the entire manifest, depending on which is faster to compute. In a flat manifest world, option A is very fast if the delta base is equal to p1. In a tree world, we don't have that optimization, but we have efficient diffs, so we use that instead. """ mf = self.read() p1, p2 = self.parents if p1 == revlog.nullid: return mf parentmf = self._manifestlog[p1].read() fastmf = None pfastmf = None # If both trees, take diff fast path treemf = mf._treemanifest() ptreemf = parentmf._treemanifest() if treemf is not None and ptreemf is not None: fastmf = treemf pfastmf = ptreemf if fastmf is None: # If both cached, take diff fast path cachedmf = mf._cachedmanifest() pcachedmf = parentmf._cachedmanifest() if cachedmf is not None and pcachedmf is not None: fastmf = cachedmf pfastmf = pcachedmf if fastmf is not None: diff = pfastmf.diff(fastmf) result = manifest.manifestdict() for path, ((oldn, oldf), (newn, newf)) in diff.iteritems(): if newn is not None: result[path] = newn result.setflag(path, newf) else: # Otherwise, fall back to flat readfast flatctx = manifest.manifestctx(self._manifestlog, self._node) result = flatctx.readfast(shallow=shallow) return mf._converttohybridmanifest(result)
def creategen(self, tr, fileinfo, reusefilelogs): mrevlog = self._repo.manifestlog._revlog clog = self._repo.changelog cp1 = self._p1ctx.node() cp2 = nullid p1 = self._repo[cp1] mp1 = p1.manifestnode() mp2 = nullid mf = manifest.manifestdict() p1mf = p1.manifest().copy() changed = [] for info in fileinfo.values(): localname = info['localname'] baserev = info['baserev'] mf[localname] = self._repo.file(localname).node(baserev) changed.append(localname) for localfile in reusefilelogs: mf[localfile] = p1mf[localfile] linkrev = len(self._repo) oldmp1 = mp1 mp1 = mrevlog.addrevision(mf.text(mrevlog._usemanifestv2), tr, linkrev, mp1, mp2) self._ui.debug('changelist %d: writing manifest. ' 'node: %s p1: %s p2: %s linkrev: %d\n' % ( self._cl, short(mp1), short(oldmp1), short(mp2), linkrev)) desc = 'p4fastimport synchronizing client view' username = P4_ADMIN_USER self._ui.debug('changelist %d: writing changelog: %s\n' % ( self._cl, desc)) cp1 = self.writechangelog( clog, mp1, changed, desc, tr, cp1, cp2, username, None, self._cl) yield self._cl, cp1
def parsemanifest(self, text): return manifestmod.manifestdict(text)
def creategen(self, tr, fileinfo): mrevlog = self._repo.manifestlog._revlog clog = self._repo.changelog cp1 = self._p1ctx.node() cp2 = nullid p1 = self._repo[cp1] mp1 = p1.manifestnode() mp2 = nullid if self._importset.isbranchpoint: mf = manifest.manifestdict() else: mf = p1.manifest().copy() for i, change in enumerate(self._importset.changelists): self._ui.progress(_('importing change'), pos=i, item=change, unit='changes', total=len(self._importset.changelists)) added, modified, removed = change.files changed = set() # generate manifest mappings of filenames to filenodes for depotname in removed: if depotname not in self._importset.filelist: continue localname = fileinfo[depotname]['localname'] if localname in mf: changed.add(localname) del mf[localname] for depotname in added + modified: if depotname not in self._importset.filelist: continue info = fileinfo[depotname] localname, baserev = info['localname'], info['baserev'] if self._ui.configbool('p4fastimport', 'checksymlinks', True): # Under rare situations, when a symlink points to a # directory, the P4 server can report a file "under" it (as # if it really were a directory). 'p4 sync' reports this as # an error and continues, but 'hg update' will abort if it # encounters this. We need to keep such damage out of the # hg repository. depotparentname = os.path.dirname(depotname) # The manifest's flags for the parent haven't been updated # to reflect this changelist yet. If the parent's flags are # changing right now, use them. Otherwise, use the # manifest's flags. parentflags = None parentinfo = fileinfo.get(depotparentname, None) if parentinfo: parentflags = parentinfo['flags'].get(change.cl, None) localparentname = localname while parentflags is None: # This P4 commit didn't change parent's flags at all. # Therefore, we can consult the Hg metadata. localparentname = os.path.dirname(localparentname) if localparentname == '': # There was no parent file above localname; only # directories. That's good/expected. parentflags = '' break parentflags = mf.flags(localparentname, None) if 'l' in parentflags: # It turns out that some parent is a symlink, so this # file can't exist. However, we already wrote the # filelog! Oh well. Just don't reference it in the # manifest. # TODO: hgfilelog.strip()? msg = _("warning: ignoring {} because it's under a " "symlink ({})\n").format(localname, localparentname) self._ui.warn(msg) continue hgfilelog = self._repo.file(localname) try: mf[localname] = hgfilelog.node(baserev) except (error.LookupError, IndexError): raise error.Abort("can't find rev %d for %s cl %d" % ( baserev, localname, change.cl)) changed.add(localname) flags = info['flags'].get(change.cl, '') if flags != mf.flags(localname): mf.setflag(localname, flags) fileinfo[depotname]['baserev'] += 1 linkrev = self._importset.linkrev(change.cl) oldmp1 = mp1 mp1 = mrevlog.addrevision(mf.text(mrevlog._usemanifestv2), tr, linkrev, mp1, mp2) self._ui.debug('changelist %d: writing manifest. ' 'node: %s p1: %s p2: %s linkrev: %d\n' % ( change.cl, short(mp1), short(oldmp1), short(mp2), linkrev)) desc = change.parsed['desc'] if desc == '': desc = '** empty changelist description **' desc = desc.decode('ascii', 'ignore') shortdesc = desc.splitlines()[0] username = change.parsed['user'] username = self.usermap.get(username, username) self._ui.debug('changelist %d: writing changelog: %s\n' % ( change.cl, shortdesc)) cp1 = self.writechangelog( clog, mp1, changed, desc, tr, cp1, cp2, username, (change.parsed['time'], 0), change.cl) yield change.cl, cp1 self._ui.progress(_('importing change'), pos=None)
def read(self, sha): if sha == nullid: return manifest.manifestdict() return overlaymanifest(self.repo, sha)