o ]Lb-@sddlmZddlZddlZddlZddlZddlmZddlm Z m Z m Z ddl m Z ddlmZmZmZmZmZmZm Z mZmZddlmZmZdd lmZed Zej Z d Z!d d Z"ddZ#Gddde$Z%Gddde$Z&ddZ'ddZ(hdZ)Gddde$Z*zej+Z*Wn e,yYnwe-ej.Gddde$Z/d@ddZ0dd Z1d!d"Z2d#d$Z3d%d&Z4e-ej.Gd'd(d(e$Z5Gd)d*d*ej6Z7d+Z8Gd,d-d-e9Z:e-ej;Gd.d/d/e$Ze-ej?Gd2d3d3e$Z@e-ejAGd4d5d5e$ZBe-ej?Gd6d7d7e$ZCe-ejAGd8d9d9e$ZDGd:d;d;e5ZEGdd?d?e<ZGdS)A)absolute_importN)_)binhexnullrev)getattr) encodingerrormatchmdiffpathutilpolicypycompatrevlogutil) repositoryr) constantsparsersiccs|r|dddkrtdd}|D]D}|dur#||kr#td|}|d\}}t|}|dd}|tvrE|dd}|d8}nd}|d|krQtd |t||fVqdS) N "Manifest did not end in a newline.#Manifest lines not in sorted order.rInvalid manifest line) ValueError splitlinessplitlen_manifestflagsr)nodelendataprevlfnnlflagsr*4/usr/lib/python3/dist-packages/mercurial/manifest.py_parse0s&     r,cCsLg}g}|D]\}}}|||d|t||fqt|d|S)N%s%s%s r)appendr_checkforbiddenjoin)itfileslinesr&r'flr*r*r+_textKs  r5c@(eZdZddZddZddZeZdS)lazymanifestitercCsd|_||_dSNr)poslmselfr:r*r*r+__init__Y zlazymanifestiter.__init__cC|SNr*r<r*r*r+__iter__]zlazymanifestiter.__iter__cCsnz |j|j\}}Wn tytw|dkr$|jd7_|dS|jd7_|d|}|||S)Nrrrr)r:_getr9 IndexError StopIterationfind)r<r#r9zeroposr*r*r+next`s   zlazymanifestiter.nextN__name__ __module__ __qualname__r=rBrI__next__r*r*r*r+r7Xs  r7c@r6)lazymanifestiterentriescC||_d|_dSr8)r:r9r;r*r*r+r=pr>z lazymanifestiterentries.__init__cCr?r@r*rAr*r*r+rBtrCz lazymanifestiterentries.__iter__cCs z |j|j\}}Wn tytw|dkr"|jd7_|S|d|}|d|}|dks:|dks:||kr?td||d|}|tvrR||d}n||d}d}|d|jj krgtdt ||jj |j|d|}|jd7_|||||fS)Nrrrrrrr) r:rDr9rErFrGr StorageErrorr!_nodelen unhexlify extrainfo)r<r#r9rHnlposr)hlenhashvalr*r*r+rIws0      zlazymanifestiterentries.nextNrJr*r*r*r+rOos rOcCs,t||||}|r|t|d@7}|S)N)rchr)r#extrar9lengthsr*r*r+rSsrScCs||k||kSr@r*)abr*r*r+_cmpr_>rltxc@seZdZdZ    d,ddZddZdd Zd d Zd d ZddZ ddZ ddZ ddZ ddZ ddZddZddZddZd-d d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+ZdS). _lazymanifestaA pure python manifest backed by a byte string. It is supplimented with internal lists as it is modified, until it is compacted back to a pure byte string. ``data`` is the initial manifest data. ``positions`` is a list of offsets, one per manifest entry. Positive values are offsets into ``data``, negative values are offsets into the ``extradata`` list. When an entry is removed, its entry is dropped from ``positions``. The values are encoded such that when walking the list and indexing into ``data`` or ``extradata`` as appropriate, the entries are sorted by filename. ``extradata`` is a list of (key, hash, flags) for entries that were added or modified since the manifest was created or compacted. NFcCs|||_|dur!|||_dgt|j|_||_g|_d|_dS|dd|_|dd|_|dd|_||_||_dS)NrF)rR findlines positionsr rTr# extradata hasremovals)r<r"r#rfrTrgrhr*r*r+r=s    z_lazymanifest.__init__cCs|sgS|d}|dks|dddkrtddg}|d|d}|t|dkrd|dkrd||d||d|d|d}||krNtd|}|d|d}|t|dkrd|dks1|S)Nrrrrrrr)rGrr r.)r<r#r9rfr$nextsr*r*r+res  z_lazymanifest.findlinescCs0|j|}|dkr|j|fS|j| ddfS)Nrrr)rfr#rg)r<indexr9r*r*r+rDs  z_lazymanifest._getcCs8|dkr|j||jd|dS|j| ddS)Nrrr)r#rGrg)r<r9r*r*r+_getkeysz_lazymanifest._getkeycCsvd}t|jd}||kr9||d}|j|}||}t||}|dkr(|S|dkr1|d}n|d}||ks dS)Nrrrrr rfrkr_r<keyfirstlastmidpointnextpos candidaterr*r*r+bsearchs      z_lazymanifest.bsearchcCs~d}t|jd}||kr;||d}|j|}||}t||}|dkr*|dfS|dkr3|d}n|d}||ks |dfS)NrrrTFrlrmr*r*r+bsearch2s      z_lazymanifest.bsearch2cCs||dkSNr)rur<rnr*r*r+ __contains__z_lazymanifest.__contains__c Cs,t|ts td||}|dkrt||\}}|dkr'|d|dfS|d|}|d|}d|krAt|jksDJJt|j t|jksPJ|dks\|dks\||krat d||d}||d|}|t vrx|d8}nd }|d|j krt dt||j ||d|} | |fS) Ns'getitem: manifest keys must be a bytes.rrrrrrrr) isinstancebytes TypeErrorruKeyErrorrDrGr rfrTr rQr!rRrS) r<rnneedler#r9rHrUrVr)rWr*r*r+ __getitem__s.    "    z_lazymanifest.__getitem__cCs||\}}|s t|j|}|jd||j|dd|_|jd||j|dd|_|dkrN|jd|d|j|dd|_d|_dSdS)NrrrT)rvr~rfrTr#rh)r<rnrfoundcurr*r*r+ __delitem__-s ""& z_lazymanifest.__delitem__cCsVt|ts tdt|trt|dkrtd|d}t|tr't|dvr+td|d}t|tr:t|dkr?td|||\}}|rv|j|}|dkr`|||df|j| d<dS|j|||dft|j |j|<dS|j|||df|jd|t|j g|j|d|_|j d|dg|j |d|_ dS) Ns-setitem: manifest keys must be a byte string.rs1Manifest values must be a tuple of (node, flags).r s-node must be a 20-byte or 32-byte byte stringrs'flags must a 0 or 1 byte string, got %r) r{r|r}tupler rvrfrgr.rT)r<rnvaluerWr)rrr9r*r*r+ __setitem__:s8       z_lazymanifest.__setitem__cCst|j|j|j|j|j|jSr@)rdrRr#rfrTrgrhrAr*r*r+copy]sz_lazymanifest.copyc Cst|jdkr |js dSg}d}d}dgt|j|_|t|jkr|j|dkr|j|}|} ||j|<|d7}|t|jksH|j|dkrIn |jrZ|jd||j|dkrZn||j||7}|j|}q1|jd|}|dkrx|d7}|||7}||j||nc|t|jkr|j|dkr|j|}|j| d}|||||j|<d}t|ddkrd }t|d|krt |d|d|j|<|t|d7}|d7}|t|jkr|j|dks|t|jks"d ||_d |_g|_dS) NrTrs rrrrrF) r rgrhrfrTr#rGr._packordr0) r<r%ioffsetrlast_cutend_cuttrVr*r*r+_compacths\       / z_lazymanifest._compactcCs8|d}t|dvs J|ddt||ddS)Nrrrrrr)r r)r<dr'r*r*r+rs z_lazymanifest._packcCs||jSr@)rr#rAr*r*r+textsz_lazymanifest.textcCsi}|D]+\}}}||vr||fdf||<q||}||f|kr+||f|f||<q|r1d||<q|D]\}}}||vrGd||ff||<q6|S)z2Finds changes between the current manifest and m2.NrN) iterentries)r<m2cleandifffne1r)e2r*r*r+rs z_lazymanifest.diffcCt|Sr@)rOrAr*r*r+rz_lazymanifest.iterentriescCrr@r7rAr*r*r+iterkeysrz_lazymanifest.iterkeyscCrr@rrAr*r*r+rBrz_lazymanifest.__iter__cC t|jSr@)r rfrAr*r*r+__len__ z_lazymanifest.__len__cCs8t|jd}|D]\}}}||r||f||<q |Sr)rdrRr)r<filterfncr&r'r4r*r*r+ filtercopys  z_lazymanifest.filtercopy)NNNFF)rKrLrM__doc__r=rerDrkrurvryrrrrrrrrrrrBrrr*r*r*r+rds4   # ;  rdc@seZdZdd(d)Zd*d+Zd=d,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Z dS)? manifestdictrcCs||_t|||_dSr@)rRrd_lm)r<r"r#r*r*r+r=szmanifestdict.__init__cCs|j|dSr8rrxr*r*r+rrzzmanifestdict.__getitem__cCs |j|Sr@rrxr*r*r+rGrzmanifestdict.findcCrr@r rrAr*r*r+rrzmanifestdict.__len__cCst|jdkSr8rrAr*r*r+ __nonzero__szmanifestdict.__nonzero__cCs|||f|j|<dSr@)r)r)r<rnnoder*r*r+rszmanifestdict.__setitem__cCs|durdS||jvSNFrrxr*r*r+rys zmanifestdict.__contains__cCs |j|=dSr@rrxr*r*r+r zmanifestdict.__delitem__cC |jSr@)rrBrAr*r*r+rBrzmanifestdict.__iter__cCrr@)rrrAr*r*r+rrzmanifestdict.iterkeyscC t|Sr@listrrAr*r*r+keysrzmanifestdict.keysNcsP|durt|dd}t|fdd||DSfdd|DS)7Set of files in this manifest that are not in the otherNcSdSr@r*)pathmsgr*r*r+ z)manifestdict.filesnotin..ch|]}|vr|qSr*r*.0r&)sm2r*r+ z*manifestdict.filesnotin..crr*r*r)rr*r+r r)matchmodbadmatchsetwalk)r<rr r*)rrr+ filesnotins zmanifestdict.filesnotincC t|Sr@r dirsrAr*r*r+_dirs zmanifestdict._dirscC|jSr@rrAr*r*r+rzmanifestdict.dirscCs ||jvSr@r)r<dirr*r*r+hasdirrzmanifestdict.hasdircs:|}t|dko|p|otfdd|DS)znChecks whether we can correctly and quickly iterate over matcher files instead of over manifest files.dc3s|]}|vVqdSr@r*)rrrAr*r+ z.manifestdict._filesfastpath..)r2r isexactprefixall)r<r r2r*rAr+_filesfastpaths  zmanifestdict._filesfastpathccs|rt|D]}|Vq dSt|}||r,t|D] }||vr)|Vq dS|D]}||vr9||||r@|Vq.|dt|D] }||sW| |dqJdS)zGenerates matching file names. Equivalent to manifest.matches(match).iterkeys(), but without creating an entirely new manifest. It also reports nonexistent files by marking them bad with match.bad(). Nr) alwaysiterrr2rsortedremovediscardrbadr<r r&fsetrr*r*r+r!s0         zmanifestdict.walkcCsn|r|S||r)t|j}|j}|D] }||vr&|||j|<q|St|j}|j||_|S)z6generate a new manifest filtered by the match argument)rrrrrRrr2r)r<r mr:rr*r*r+_matchesFs    zmanifestdict._matchesFcCs6|r||}||}|j||dS|j|j|S)zFinds changes between the current manifest and m2. Args: m2: the manifest to which this manifest should be compared. clean: if true, include files unchanged between these manifests with a None value in the returned dictionary. The result is returned as a dict with filename as key and values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the nodeid in the current/other manifest and fl1/fl2 is the flag in the current/other manifest. Where the file does not exist, the nodeid will be None and the flags will be the empty string. r)rrr)r<rr rm1r*r*r+rWs   zmanifestdict.diffcCs&|tvrtd|||f|j|<dS)NInvalid manifest flag set.)r!r}r)r<rnflagr*r*r+setflaglszmanifestdict.setflagcCs(z|j|dWSty|YSwr8rr~)r<rndefaultr*r*r+getqs  zmanifestdict.getcCs&z|j|dWStyYdSw)Nrrrrxr*r*r+r)ws  zmanifestdict.flagscCst|j}|j|_|Sr@)rrRrr)r<rr*r*r+r}s  zmanifestdict.copycCdd|jDS)Ncs|] }|ddVqdSNrr*rxr*r*r+rz%manifestdict.items..rrrAr*r*r+itemszmanifestdict.itemscCr)Ncsrrr*rr*r*r+rrz)manifestdict.iteritems..rrAr*r*r+ iteritemsrzmanifestdict.iteritemscCrr@rrAr*r*r+rrzmanifestdict.iterentriescCrr@)rrrAr*r*r+rrzmanifestdict.textcCsTg}d}d}dg}d}t|}t|}t|tkr|D]]\} } t|| |\}} | s;|j| \} } d| t| | f}n|| krGtt d| d}|durc||krc||krc|| kr[| }|rb| |q|durr| ||d |g|}| }|g}q|dur| ||d |gt ||\}}||fSt |}tt|t|}||fS)zGiven a base manifest text as a bytearray and a list of changes relative to that text, compute a delta that can be used by revlog. Nrrr-s!failed to remove %s from manifest)rbufferrr FASTDELTA_TEXTDIFF_THRESHOLD_msearchrrAssertionErrorrr.r0 _addlistdelta bytearrayrr textdiff)r<basechangesdeltadstartdenddlinestartaddbufr&todeleteendhr4r% deltatext arraytextr*r*r+ fastdeltasL      zmanifestdict.fastdeltarr@r)!rKrLrMr=rrGrr__bool__rryrrBrrr propertycacherrrrrrrrrr)rrrrrr r*r*r*r+rs>    %   rc sfdd}|s ||fSt|s}||kr`||d}|}|dkrA|d|dkrA|d8}|dkrA|d|dks/||d}t|||krZ||ddd}n|}||ks||d}||}||kr|||dd}||dfS||fS) aEreturn a tuple (start, end) that says where to find s within m. If the string is found m[start:end] are the line containing that string. If start == end the string was not found and they indicate the proper sorted insertion point. m should be a buffer, a memoryview or a byte string. s is a byte stringcsD|kr ||d|kr |d7}|kr ||d|ks|S)Nrr*)rrlenmrr*r+advancesz_msearch..advancerrrrr()r r|) rr\lohirmidrrrr*rr+rs.     rcCs6|D]}d|vs d|vrttdt|qdS)z'Check filenames for illegal characters.r s)'\n' and '\r' disallowed in filenames: %rN)r rQrrbytestr)r%r&r*r*r+r/sr/cCsjd}t}|D]\}}}||||7}|r|t|7}|}q|||d7}ddd|D}||fS)Nrrcss.|]\}}}td||t||VqdS)s>lllN)structpackr )rrrcontentr*r*r+r s  z _addlistdelta..)rr0)addlistrcurrentposition newaddlistrrrrr*r*r+rs  rcCs,d|vr|dd\}}|d|fSd|fS)N/rr)r)r&rsubpathr*r*r+ _splittopdirs rcCrr@r*r\r*r*r+rrrc@seZdZd^ddZddZddZdd Zd d Zd d ZddZ ddZ e Z ddZ e jddZddZddZddZddZddZeZd d!Zd"d#Zd$d%Zd&d'Zd_d)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd3d4Zd5d6Z d7d8Z!d9d:Z"d_d;d<Z#e$d=d>Z%d?d@Z&dAdBZ'dCdDZ(dEdFZ)dGdHZ*dIdJZ+dKdLZ,d`dNdOZ-dPdQZ.dRdSZ/dTdUZ0dVdWZ1dXdYZ2dZd[Z3d_d\d]Z4d(S)a treemanifestrcCsp||_||_|jj|_|jj|_t|_t|_d|_ i|_ i|_ i|_ i|_ |r6dd}|||d|_ dSdS)NFcSstd)Ns4treemanifest constructor only accepts flat manifests)r)subdirsubmr*r*r+ readsubtree0sz*treemanifest.__init__..readsubtreeT)_dir nodeconstantsnullid_noder"rR_noop _loadfunc _copyfunc_dirtyr _lazydirs_files_flagsparse)r<r&rrr$r*r*r+r=!s     ztreemanifest.__init__cCs |j|Sr@r%)r<rr*r*r+_subpath8rztreemanifest._subpathcCs`|j}|j}t|jD]\}\}}}|r!||||||<q ||||||<q i|_dSr@)rr2rrr-r)r<selfdirsrrrr$docopyr*r*r+ _loadalllazy;s ztreemanifest._loadalllazycCs`|j|}|r.|\}}}|r|||||j|<n |||||j|<|j|=dSdSr@)r-rr2rr)r<rvrr$r4r*r*r+ _loadlazyGs   ztreemanifest._loadlazycCsD|sdS|dks |dkr|dS|j}|D]}||dq|S)Nallthisr)r5r7)r<visitloadlazykr*r*r+_loadchildrensetlazyQsz!treemanifest._loadchildrensetlazycCsg}t|jD]\}}|j|}|r|d|dkr!||qt|jD]\}}||jvr6||q(|D] }||||q9dS)amload items in t1 and t2 if they're needed for diffing. The criteria currently is: - if it's not present in _lazydirs in either t1 or t2, load it in the other (it may already be loaded or it may not exist, doesn't matter) - if it's present in _lazydirs in both, compare the nodeid; if it differs, load it in both rN)rrr-rr.r7)r<t1t2 toloadlazyrv1v2r*r*r+ _loaddifflazy]s       ztreemanifest._loaddifflazycCs:|t|j}||jD]}||7}q|Sr@)_loadr r.r5rvaluesr)r<sizerr*r*r+rss  ztreemanifest.__len__cCs | Sr@_isemptyrAr*r*r+r{rztreemanifest.__nonzero__cCsX||js|jrtdd|jDrdS||j p+tdd|jDS)Ncss|]}| VqdSr@rGrrr*r*r+rsz(treemanifest._isempty..Fcss|]}|VqdSr@rGrIr*r*r+rr)rDr.ranyrEr5rrAr*r*r+rHs ztreemanifest._isemptycCs*d|jt|jt|jtu|jt|fS)Ns;)r%rr(boolr*r)r,idrAr*r*r+__repr__s ztreemanifest.__repr__cCr)z}The directory that this tree manifest represents, including a trailing '/'. Empty string for the repo root directory.r1rAr*r*r+rsztreemanifest.dircCs|jrJ|jS)zThis node of this instance. nullid for unsaved instances. Should be updated when the instance is read or written from a revlog. r,r(rAr*r*r+rs ztreemanifest.nodecCrPr)r(r,r<rr*r*r+setnoder>ztreemanifest.setnodeccsx||tt|j|jD]"\}}||jvr/||||j |dfVq| D]}|Vq3qdSr) rDr5r itertoolschainrrr.r2r/rr)r<pr'rr*r*r+rs  ztreemanifest.iterentriesccsv||tt|j|jD]!\}}||jvr)|||fVqt |D] \}}||fVq.qdSr@) rDr5rrQrRrrr.r2rr)r<rSr'r&snr*r*r+rs  ztreemanifest.itemsccs^||tt|j|jD]}||jvr!||Vq|j|D]}|Vq&qdSr@)rDr5rrQrRrr.r2)r<rSr&r*r*r+rs ztreemanifest.iterkeyscCrr@rrAr*r*r+rrztreemanifest.keyscC|Sr@)rrAr*r*r+rBrztreemanifest.__iter__cCsV|durdS|t|\}}|r&||||jvrdS|j||S||jvSr)rDrr7rryr.r<r&rrr*r*r+rys    ztreemanifest.__contains__NcCsP|t|\}}|r!||||jvr|S|j|||S|j||Sr@)rDrr7rrr.)r<r&rrrr*r*r+rs   ztreemanifest.getcCs<|t|\}}|r|||j||S|j|Sr@)rDrr7rrr.rVr*r*r+rs    ztreemanifest.__getitem__cCsf|t|\}}|r ||||jvrdS|j||S||jvs*||jvr,dS|j|dSr)rDrr7rr)r-r/rrVr*r*r+r)s   ztreemanifest.flagscCsJ|t|\}}|r|||j||S|j||j|dfSr)rDrr7rrGr.r/rrVr*r*r+rGs   ztreemanifest.findcCsn|t|\}}|r%|||j|||j|r$|j|=n |j|=||jvr2|j|=d|_dSNT) rDrr7rrrHr.r/r,rVr*r*r+rs    ztreemanifest.__delitem__cCs|dusJ|t|\}}|r2||||jvr(t|j|||j|<|j|||n t|dvs:J||j |<d|_ dS)NrT) rDrr7rr!r&r2rr r.r,)r<r&r'rrr*r*r+rs        ztreemanifest.__setitem__cCsL|jtur|jt}|_||dS|jtur$|jt}|_||dSdSr@)r*r)r+)r<lfcfr*r*r+rD2s    ztreemanifest._loadcCs||tvrtd|t|\}}|r4||||jvr*t|j|||j|<|j| ||n||j |<d|_ dS)z/Set the flags (symlink, executable) for path f.rTN) r!r}rDrr7rr!r&r2rr/r,)r<r&r)rrr*r*r+r:s       ztreemanifest.setflagcs`tjj}j|_j|_jtur*fdd}jtur%|||S||_|Sj|_|S)NcshddtjD|_|j}tjD] \}}|||<qtj|_tj|_dS)NcSs"i|] \}\}}}|||dfqSTr*)rrr'rtrr*r*r+ Ss  z8treemanifest.copy.._copyfunc..) rDrrr-rrdictr.r/)r\sdirsrr6rAr*r+r+Qs z$treemanifest.copy.._copyfunc)r!r&r%r(r,r+r)r*)r<rr+r*rAr+rKs   ztreemanifest.copycsN|r|s|}||}||Stfdd|S)rcs|j|jkr|js|jsdS||||t|jD]\}}||jvr6|j|}||q"|q"|j D]}||j vrP | |qAdSr@) r(r,rDrCrrrupdaterr.addr2)r>r?rrrr _filesnotinr2r<r*r+rans      z,treemanifest.filesnotin.._filesnotin)rrrr)r<rr rr*r`r+res     ztreemanifest.filesnotincCrr@rrAr*r*r+_alldirsrztreemanifest._alldirscCrr@)rbrAr*r*r+rrztreemanifest.dirscCs\|t|\}}|r ||||jvr|j||SdS|d}||jvp-||jvS)NFr)rDrr7rrr-)r<rtopdirr"dirslashr*r*r+rs   ztreemanifest.hasdirccs|rt|D]}|Vq dSt|}||D]}||vr'|||Vq|dt|D] }||sA| |dq4dS)zxGenerates matching file names. It also reports nonexistent files by marking them bad with match.bad(). Nr) rrrr2_walkrrrrrrr*r*r+rs        ztreemanifest.walkccs||jdd}|sdS|||}tt|jt|jD],}||jvr8||}||r7|Vq$|rB|dd|vrP|j| |D]}|VqJq$dS)z5Recursively generates matching file names for walk().Nr) visitchildrensetr%rDr=rrrr.r2re)r<r r:rSfullpr&r*r*r+res"   ztreemanifest._walkcCs|r|S||S)zCrecursively generate a new manifest filtered by the match argument.)rr_matches_inner)r<r r*r*r+rs ztreemanifest._matchesc Cs|r|S||jdd}|dkr|St|j|j}|s%|S||jD]*}|dkr7||vr7q,||}||sAq,|j||j|<||j vrV|j ||j |<q,| |}t |j D]\}}|rq|dd|vrqqb||}|s||j |<qb|sd|_|S)Nrr8r9T)rrrfr%r!r&rDr.r2r/r=rrrrhrHr,) r<r r:retrrgrr#rr*r*r+rhs<      ztreemanifest._matches_innercCstr@)FastdeltaUnavailable)r<rrr*r*r+r rztreemanifest.fastdeltaFc s|r|s|}||}|j|dSitjfdd}g}||||r?|\}}|||||s1S)rrc s^|j|jkr|js|jsdS||||t|jD]\}}|j|}|||fq"t|jD]\}}||jvrK||fq;t|j D]8\}}|j |d}|j |d} |j |d} || kss|| kr||f| | ff| |<qRrd| |<qRt|j D]\}} ||j vr|j |d} d| | ff| |<qdS)zicompares two tree manifests and append new tree-manifests which needs to be compared to stackNrr) r(r,rDrCrrrrr.r.r/r2) r>r?stackrrrrn1fl1n2fl2r emptytreeresultr<r*r+_iterativediff s6   z)treemanifest.diff.._iterativediff)rrrr!r&pop) r<rr rrrsstacklsr>r?r*rpr+rs       ztreemanifest.diffcCs|j o |j o |j|jkSr@rN)r<rr*r*r+unmodifiedsince0sztreemanifest.unmodifiedsincecCs||j}t|j|D]2\}}}|dkr|d}||df||<q d|vr/|||<|r.|||q ||j|<|r;||j|<q dS)NrbrF)r-r,rRrr.r/)r<rr$selflazyr&r'r4r*r*r+r03s   ztreemanifest.parsecCs|t|S)z3Get the full data of this manifest as a bytestring.)rDr5rrAr*r*r+rJs ztreemanifest.textcsbjddtjD}fddjD}fddjD}tt|||S)zGet the full data of this directory as a bytestring. Make sure that any submanifests have been written first, so their nodeids are correct. cSs&g|]\}}|dd|ddfqS)Nrrrbr*)rrr6r*r*r+ Usz(treemanifest.dirtext..cs&g|]}|ddj|jdfqS)Nrrb)rr()rrrAr*r+rxXs&cs g|] }|j||fqSr*)r.rr)r<r*r+rxYs ) rDr)rrr-rr.r5r)r<lazydirsrr2r*ryr+dirtextOs ztreemanifest.dirtextcsfdd}||_dS)Ncs|d|_dSr)r0r,r gettextr$r*r+_load_for_read]s z)treemanifest.read.._load_for_read)r*)r<r}r$r~r*r|r+read\s ztreemanifest.readc s|||t|jfdd}||jdd}||}|dks.|dkr0d}t|jD]+\}}|rE|dd|vrEq6|||} |||} | |jj krZ| | } } ||| | |q6dS)Ncs(|j|}|r |dS|j|jSr8)r-rrr()rrldrqr*r+getnodeis z+treemanifest.writesubtrees..getnoderr9r8) rDr!r&rfr%r=rrrr') r<rr writesubtreer rr:rr#subp1subp2r*rr+ writesubtreescs$       ztreemanifest.writesubtreesccs||r||jddsdS|r||jddr|V||t|jD]\}}|j|dD]}|Vq5q+dS)zReturns an iterator of the subtrees of this manifest, including this manifest itself. If `matcher` is provided, it only returns subtrees that match. Nr)matcher)visitdirr%rDr5rrr walksubtrees)r<rrr#subtreer*r*r+r}sztreemanifest.walksubtrees)rrr@r)5rKrLrMr=r2r5r7r=rCrrr rHr strmethodrMrrrPrrrrrrBryrrr)rGrrrDrrrr rbrrrrerrhr rrvr0rr{rrrr*r*r*r+r!sd                ) = r!cseZdZdZdZfddZfddZddZfd d Zfd d Z fd dZ fddZ fddZ fddZ dfdd Zdfdd ZZS)manifestfulltextcachezFile-backed LRU cache for the manifest cache File consists of entries, up to EOF: - 20 bytes node, 4 bytes length, manifest data These are written in reverse cache order (oldest to newest). smanifestfulltextcachecs&tt||d|_d|_d|_dSr)superrr=r,_read_opener)r<max __class__r*r+r=s zmanifestfulltextcache.__init__c s|js|jdur dSzW||jG}tt|j} |d}t|dkr%n,z t d|dd}Wn tj y<Ynwt ||}t||krKn|||qWdn1s[wYWn t yjYnwd|_d|_ dS)NTr>LrF)rr_filerrrrr runpackr rIOErrorr,)r<fprrrFrrr*r+rs6       zmanifestfulltextcache.readcCs|jr|jdur dSzL|j|jdddd7}|jj} |j|jvr9||j|t dt |j ||j ||jur?n|j}qWdWdS1sOwYWdSt y`YdSw)NwT) atomictemp checkambigr) r,rr_headr$rn_cachewriterrr rr)r<rrr*r*r+rs,     &  zmanifestfulltextcache.writec|js|tt|Sr@)rrrrrrArr*r+rzmanifestfulltextcache.__len__cs|js|tt||Sr@)rrrrryr<r<rr*r+rysz"manifestfulltextcache.__contains__crr@)rrrrrBrArr*r+rBrzmanifestfulltextcache.__iter__cs>|js||j||ju}tt||}|rd|_|SrW) rrrrrrrrr,)r<r<setdirtyrrr*r+rsz!manifestfulltextcache.__getitem__cs*|js|tt|||d|_dSrW)rrrrrr,)r<r<r6rr*r+rs z!manifestfulltextcache.__setitem__cs(|js|tt||d|_dSrW)rrrrrr,rrr*r+rs z!manifestfulltextcache.__delitem__Ncs"|js|tt|j||dS)N)r)rrrrr)r<r<rrr*r+rszmanifestfulltextcache.getFcs*tt||rd|_|d|_dS)NTF)rrclearr,rrr<clear_persisted_datarr*r+rs  zmanifestfulltextcache.clearr@r)rKrLrMrrr=rrrryrBrrrrr __classcell__r*r*rr+rs       rc@seZdZdZdS)rjz;Exception raised when fastdelta isn't usable on a manifest.N)rKrLrMrr*r*r*r+rjsrjc@sLeZdZdZ   dBddZddZed d ZdCd d Zd dZ  dDddZ ddZ ddZ ddZ ddZddZddZddZdd Zd!d"Zd#d$ZdEd%d&ZdEd'd(Zd)d*Zd+d,Zd-d.Zdddejdfd/d0Z   dFd1d2Zd3d4Zd5d6Zd7d8Z d9d:Z!d;d<Z"     dGd=d>Z#ed?d@Z$e$j%dAd@Z$dS)HmanifestrevlogznA revlog that stores manifest texts. This is responsible for caching the full-text manifest contents. rNFc Cs||_d}d}t|dd}|dur|d|}|dd}|p ||_t||_|r2|js2Jd|d} |r.persistmanifestcache) r safehasattr wcachevfsrr _currentlock _wlockrefweakrefref _afterlock)r<rrr*rr+_setupmanifestcachehooksZs    z'manifestrevlog._setupmanifestcachehookscCrr@)rrAr*r*r+ fulltextcachevszmanifestrevlog.fulltextcachecCs(|j|jj|d|j|i|_dSN)r)r clearcachesrrrrrr*r*r+rzs zmanifestrevlog.clearcachescCsF|r|jsJ||jvrt|j|j||j|jd}||j|<|j|S)N)r!)rrrr&r)r<rmfrevlogr*r*r+dirlogs    zmanifestrevlog.dirlogc  CsDzK||jvr tt|tddt|Dddt|D} ||j|| \} } |j|| f} t | }|j |||||| }|j |}WnKty|j r||s[Jd| saJd||j|}||j|}|j||||||| d}d} n|}|j |||||}|j |}t|} Ynw| dur| |j|<|S)aadd some manifest entry in to the manifest log input: m: the manifest dict we want to store transaction: the open transaction p1: manifest-node of p1 p2: manifest-node of p2 added: file added/changed compared to parent removed: file removed compared to parent tree manifest input: readtree: a function to read a subtree match: a filematcher for the subpart of the tree manifest cSg|]}|dfqSrr*rr*r*r+rxz&manifestrevlog.add..cSrrZr*rr*r*r+rxrs,readtree must be set for treemanifest writess/match must be specified for treemanifest writesr N)rrjr/heapqmergerr rrevrr addrevisionrrr_addtreerr)r<r transactionlinkp1p2addedremovedreadtreer workr r cachedeltarrr'rrr*r*r+r_sD          zmanifestrevlog.addc sjdkr||s||r|Sfdd}||||||} d} jdkrD| |kr:|} n | |krD|} | sZj| ||} j| } || | S)Nrc s.|}|j|||dd|d dS)Nrr )rrr_)r#rrr sublogrrr<rr*r+rs z-manifestrevlog._addtree..writesubtree)rrvrrr{rrrP) r<rrrrrrr rrr'rr*rr+rs,       zmanifestrevlog._addtreecCrr@)r rrAr*r*r+rrzmanifestrevlog.__len__cCrr@)rrBrAr*r*r+rBrzmanifestrevlog.__iter__cC |j|Sr@)rrrOr*r*r+r rzmanifestrevlog.revcCrr@)rrr<rr*r*r+r rzmanifestrevlog.nodecCrr@)rlookupr<rr*r*r+rrzmanifestrevlog.lookupcCrr@)r parentrevsrr*r*r+rrzmanifestrevlog.parentrevscCrr@)rparentsrOr*r*r+rrzmanifestrevlog.parentscCrr@)rlinkrevrr*r*r+rrzmanifestrevlog.linkrevcCrr@)r checksizerAr*r*r+rrzmanifestrevlog.checksizecC|jj||dSN)_df)rrevisionr<rrr*r*r+rr`zmanifestrevlog.revisioncCrr)rrawdatarr*r*r+r!r`zmanifestrevlog.rawdatacC|j||Sr@)rrevdiff)r<rev1rev2r*r*r+r$rzzmanifestrevlog.revdiffcCrr@)rcmp)r<rrr*r*r+r'rzzmanifestrevlog.cmpcCrr@)r deltaparentrr*r*r+r*rzmanifestrevlog.deltaparentcC|jj||||||dS)N) nodesorder revisiondataassumehaveparentrevisions deltamodesidedata_helpers)r emitrevisions)r<nodesrrrrrr*r*r+r- zmanifestrevlog.emitrevisionscCr)N) alwayscache addrevisioncbduplicaterevisioncb)raddgroup)r<deltas linkmapperrrrrr*r*r+r?rzmanifestrevlog.addgroupcCrr@)rrawsizerr*r*r+r Qrzmanifestrevlog.rawsizecCrr@)r getstrippoint)r<minlinkr*r*r+r Trzmanifestrevlog.getstrippointcCrr@)rstrip)r<r rr*r*r+rWrzzmanifestrevlog.stripcCrr@)rr2rAr*r*r+r2Zrzmanifestrevlog.filescKs,t|ts td|jj||jfi|S)Ns"expected manifestrevlog to clone())r{rr ProgrammingErrorrclone)r<tr destrevlogkwargsr*r*r+r]s  zmanifestrevlog.clonecCs|jj|||||dS)N)exclusivefiles sharedfilesrevisionscount trackedsize storedsize)r storageinfo)r<rrrrrr*r*r+rcszmanifestrevlog.storageinfocCs|jjSr@rrrAr*r*r+rszmanifestrevlog.openercCs ||j_dSr@rrr*r*r+rws )rNFr)NNr@)FNN)FFFFF)&rKrLrMrr=rpropertyrrrr_rrrBrrrrrrrrrrrrrCG_DELTAMODE_STDrrr r rr2rrrsetterr*r*r*r+rsl >   L*      rc@sLeZdZdZddZddZdddZd d Zdd d ZddZ ddZ dS)raA collection class representing the collection of manifest snapshots referenced by commits in the repository. In this situation, 'manifest' refers to the abstract concept of a snapshot of the list of files in the given commit. Consumers of the output of this class do not care about the implementation details of the actual manifests they receive (i.e. tree or flat or lazily loaded, etc).cCsz|j|_d}d}t|dd}|dur|d|}|d|}||_||_|j|||_i|_t ||jd<||_ dS)NFrrrrr) r&rr_treemanifests _rootstorer _narrowmatch _dirmancacher lrucachedict _cachesize)r<rr rootstore narrowmatchusetreemanifestrrr*r*r+r=s     zmanifestlog.__init__cCs |d|S)zgRetrieves the manifest instance for the given node. Throws a LookupError if not found. r)rrOr*r*r+rs zmanifestlog.__getitem__TcCs||j|dvr|j||S|js&|j|dds&t|j||S|rF|jjr=|r6| | |t |||}n t td||rN|j ||jrXt |d|}nt||}||jjkrz|j|}|svt|j}||j|<|||<|S)zRetrieves the manifest instance for the given node. Throws a LookupError if not found. `verify` - if True an exception will be thrown if the node is not in the revlog r*Nrs9cannot ask for manifest directory '%s' in a flat manifestr)r"rr!rrexcludeddirmanifestctxr&r rrrtreemanifestctxr Abortrr manifestctxr'rr#r$)r<rrverifyrmancacher*r*r+rs:       zmanifestlog.getcCrr@)r r)r<rr*r*r+rrzmanifestlog.getstorageFcCs|j|jj|ddSr)r"rr rrr*r*r+rs zmanifestlog.clearcachescCrr@)r rrOr*r*r+rrzmanifestlog.revcCs|jjj|dS)N)r)r r update_caches)r<rr*r*r+r.r`zmanifestlog.update_cachesNrZr) rKrLrMrr=rrrrrr.r*r*r*r+r|s /  rc@s6eZdZddZddZddZddZd d d Zd S) memmanifestctxcCs||_t|jj|_dSr@) _manifestlogrr&r" _manifestdict)r<rr*r*r+r=szmemmanifestctx.__init__cC |jdSrr0rrAr*r*r+_storagerzmemmanifestctx._storagecCt|j}||_|Sr@r/r0rrr1r<memmfr*r*r+r zmemmanifestctx.copycCrr@)r1rAr*r*r+rrzmemmanifestctx.readNc Cs |j|j|||||||dS)Nr)r4r_r1)r<rrrrrrr r*r*r+rszmemmanifestctx.writer@rKrLrMr=r4rrrr*r*r*r+r/s r/c@s`eZdZdZddZddZddZdd Zed d Z d d Z dddZ dddZ ddZ dS)r+zxA class representing a single revision of a manifest, including its contents, its parent revs, and its linkrev. cCs||_d|_||_dSr@)r0_datar()r<rrr*r*r+r=s zmanifestctx.__init__cCr2rr3rAr*r*r+r4rzmanifestctx._storagecCrr@r(rAr*r*r+rrzmanifestctx.nodecCr5r@r6r7r*r*r+rr9zmanifestctx.copycC||jSr@r4rr(rAr*r*r+rzmanifestctx.parentscCs|jdurC|jj}|j|jkrt|j|_|jS|}|j|jvr,t |j|j}n| |j}t |}||j|j<t|j||_|jSr@) r;r0r&r(r'rr"r4rrrrr)r<ncstorerr r*r*r+rs       zmanifestctx.readFcCsD|}||j}||}|tkr|||vr|S|S)aCalls either readdelta or read, based on which would be less work. readdelta is called if the delta is against the p1, and therefore can be read quickly. If `shallow` is True, nothing changes since this is a flat manifest. )r4rr(rrr readdeltarr<shallowrArtrr*r*r+readfast/s   zmanifestctx.readfastcCs:|}||j}t||||}t|jj |S)a Returns a manifest containing just the entries that are present in this manifest, but not in its p1 manifest. This is efficient to read if the revlog delta is already p1. Changing the value of `shallow` has no effect on flat manifests. ) r4rr(r patchtextrrrr&r")r<rDrArtrr*r*r+rB=s zmanifestctx.readdeltacC||Sr@rrGrxr*r*r+rGIrzzmanifestctx.findNr)rKrLrMrr=r4rrr rrrErBrGr*r*r*r+r+s     r+c@s8eZdZd ddZddZddZdd Zdd d Zd S)memtreemanifestctxrcCs||_||_t|j|_dSr@)r0r%r!r& _treemanifest)r<rrr*r*r+r=Oszmemtreemanifestctx.__init__cCr2rr3rAr*r*r+r4Trzmemtreemanifestctx._storagecCs t|j|jd}|j|_|SNr)rIr0r%rJrr7r*r*r+rWs zmemtreemanifestctx.copycCrr@)rJrAr*r*r+r\rzmemtreemanifestctx.readNc s.fdd}jj||||||||d S)Ncsj||Sr@r0rr)rrrAr*r+r`z*memtreemanifestctx.write..readtreer)r4r_rJ) r<rrrrrrr rr*rAr+r_s zmemtreemanifestctx.writer r@r:r*r*r*r+rIMs  rIc@s\eZdZddZddZddZddZd d Zed d Z dddZ dddZ ddZ dS)r)cCs||_||_d|_||_dSr@)r0r%r;r()r<rrrr*r*r+r=rs ztreemanifestctx.__init__cCsB|jj}|s||jddst|jj|jS|j|jSrw)r0r!rrr%excludedmanifestrevlogr&r)r<r&r*r*r+r4s ztreemanifestctx._storagecsjdurqjjjjkrtjj_jSjrFtjjjd}fdd}fdd}| ||| j|_jSjj vrVt j j}nj}t|}|j j<tjjj|d_jS)NrLcs jSr@)rr(r*r<rAr*r+r}rz%treemanifestctx.read..gettextcsjj||ddS)NF)r,rM)rr#rAr*r+r$sz)treemanifestctx.read..readsubtree)rr)r;r4r(r0r&r'r!rr%rrPrrrrr)r<rr}r$rr r*rPr+rs,        ztreemanifestctx.readcCrr@r<rAr*r*r+rrztreemanifestctx.nodecCs"t|j|jd}||_|SrK)rIr0r%rrrJr7r*r*r+rsztreemanifestctx.copycCr=r@r>rAr*r*r+rr?ztreemanifestctx.parentsFcCs|}|r||j}t||||}t|jj |S|||j}|j |j | |}|}t|j j|j d}t||D]\} \\} } \} } | rb| || <| rb|| | qJ|S)aReturns a manifest containing just the entries that are present in this manifest, but not in its p1 manifest. This is efficient to read if the revlog delta is already p1. If `shallow` is True, this will read the delta for this directory, without recursively reading subdirectory manifests. Instead, any subdirectory entry will be reported as it appears in the manifest, i.e. the subdirectory will be reported among files and distinguished only by its 't' flag. rL)r4rr(r rFrrrr&r"r0rr%rrr!rrrr)r<rDrArtrr0m0rmdr&n0fl0rlrmr*r*r+rBs   $ ztreemanifestctx.readdeltacCsb|}||j}||}|tkr |||vr |j|dS|r-t|jj | |jS| S)a#Calls either readdelta or read, based on which would be less work. readdelta is called if the delta is against the p1, and therefore can be read quickly. If `shallow` is True, it only returns the entries from this manifest, and not any submanifests. )rD) r4rr(rrrrBrr&r"rrrCr*r*r+rEs   ztreemanifestctx.readfastcCrGr@rHrxr*r*r+rGrzztreemanifestctx.findNr) rKrLrMr=r4rrrr rrBrErGr*r*r*r+r)ps !    r)cs(eZdZdZfddZddZZS) excludeddiraStand-in for a directory that is excluded from the repository. With narrowing active on a repository that uses treemanifests, some of the directory revlogs will be excluded from the resulting clone. This is a huge storage win for clients, but means we need some sort of pseudo-manifest to surface to internals so we can detect a merge conflict outside the narrowspec. That's what this class is: it stands in for a directory whose node is known, but whose contents are unknown. cs0tt|||||_||jd<d|jd<dS)Nrrb)rrVr=r(r.r/r<r&rrrr*r+r=s zexcludeddir.__init__cCr?r@r*rAr*r*r+r rCzexcludeddir.copy)rKrLrMrr=rrr*r*rr+rVs  rVc@s2eZdZdZddZddZd ddZd d Zd S) r(zBcontext wrapper for excludeddir - see that docstring for rationalecCs||_||_||_dSr@)r&r%r(rWr*r*r+r= s zexcludeddirmanifestctx.__init__cCst|j|j|jSr@)rVr&r%r(rAr*r*r+r rNzexcludeddirmanifestctx.readFcCrUr@)r)r<rDr*r*r+rE rzexcludeddirmanifestctx.readfastcGtd|j)Ns.attempt to write manifest from excluded dir %sr rr%)r<argsr*r*r+r zexcludeddirmanifestctx.writeNr)rKrLrMrr=rrErr*r*r*r+r( s   r(c@s@eZdZdZddZddZddZdd Zd d Zd d Z dS)rOa\Stand-in for excluded treemanifest revlogs. When narrowing is active on a treemanifest repository, we'll have references to directories we can't see due to the revlog being skipped. This class exists to conform to the manifestrevlog interface for those directories and proactively prevent writes to outside the narrowspec. cCs||_||_dSr@)r&r%)r<r&rr*r*r+r=( r>zexcludedmanifestrevlog.__init__cCrX)Ns(attempt to get length of excluded dir %srYrAr*r*r+r, r[zexcludedmanifestrevlog.__len__cCrX)Ns'attempt to get rev from excluded dir %srYrOr*r*r+r1 r[zexcludedmanifestrevlog.revcCrX)Ns+attempt to get linkrev from excluded dir %srYrOr*r*r+r6 r[zexcludedmanifestrevlog.linkrevcCrX)Ns(attempt to get node from excluded dir %srYrr*r*r+r; r[zexcludedmanifestrevlog.nodecOrr@r*)r<rZrr*r*r+r_@ szexcludedmanifestrevlog.addN) rKrLrMrr=rrrrr_r*r*r*r+rO s  rO)rN)H __future__rrrQrri18nrrrrrrrr r r rr r rrr interfacesr interfaceutil revlogutilsrr importmodrr rr,r5objectr7rOrSr_r!rd lazymanifestAttributeError implementer imanifestdictrrr/rrr)r!r#rr Exceptionrjimanifeststorager imanifestlogrimanifestrevisionwritabler/imanifestrevisionstoredr+rIr)rVr(rOr*r*r*r+s~   ,   %6    k+  t  g b  O "{