o ]Lbe@s.ddlmZddlZddlZddlZddlZddlZddlmZddl m Z ddl m Z ddl mZmZmZmZm Z mZmZddlmZed Zd Zd d Zd dZe edeZddZddZddZe\Z Z!ddZ"ddZ#ddZ$e eddp~e$Z%dZ&dZ'dd Z(d!Z)d"Z*d"e*dd#Z+d$d%Z,d&d'Z-d(d)Z.e ed*e.Z.d+d,Z/d-d.Z0gd/Z1d0Z2d1Z3d2Z4e5d3Z6d4d5Z7d6d7Z8d8Z9d9Z:d:Z;d;Zd=Z?e9e=BZ@e9e>BZAe:e=BZBe:e>BZCe;e=BZDe;e>BZEed?d?eGZHGd@dAdAeHZIGdBdCdCeGZJGdDdEdEejKZLGdFdGdGeHZMdS)H)absolute_importN)_)getattr)hex) changelogerrormanifestpolicypycompatutilvfs)hashutilparsersi@BcCsl|durdSt|}|dr||tdtd S|dr/||tdtd Std|)zparses a fncache entry and returns whether the entry is tracking a path matched by matcher or not. If matcher is None, returns TrueNTdata/.imeta/s /00manifest.iscannot decode path %s) decodedir startswithlenvisitdirrProgrammingError)pathmatcherr1/usr/lib/python3/dist-packages/mercurial/store.py_matchtrackedpath$s  rcCs|ddddddS)aM >>> _encodedir(b'data/foo.i') 'data/foo.i' >>> _encodedir(b'data/foo.i/bla.i') 'data/foo.i.hg/bla.i' >>> _encodedir(b'data/foo.i.hg/bla.i') 'data/foo.i.hg.hg/bla.i' >>> _encodedir(b'data/foo.i\ndata/foo.i/bla.i\ndata/foo.i.hg/bla.i\n') 'data/foo.i\ndata/foo.i.hg/bla.i\ndata/foo.i.hg.hg/bla.i\n' .hg/.hg.hg/.i/.i.hg/.d/.d.hg/replacerrrr _encodedir7s r& encodedircCs(d|vr|S|ddddddS)z >>> decodedir(b'data/foo.i') 'data/foo.i' >>> decodedir(b'data/foo.i.hg/bla.i') 'data/foo.i/bla.i' >>> decodedir(b'data/foo.i.hg.hg/bla.i') 'data/foo.i.hg/bla.i' rr"r!r rrr#r%rrrrLs   rccsNdddD}tdD]}|Vq tddD]}|Vq|D]}|VqdS)zcharacters that are problematic for filesystems * ascii escapes (0..31) * ascii hi (126..255) * windows specials these characters will be escaped by encodefunctions cSsg|]}t|qSr)ord.0xrrr gz_reserved..z\:*?"<>| ~N)range) winreservedr+rrr _reserved^s r3csd}tj}tt|td}tttdtdd}dd|DtD] }d|||<q%|t|gD]}|||||<q7itD]\}}||<qMfd d fd d fd d fS)a >>> enc, dec = _buildencodefun() >>> enc(b'nothing/special.txt') 'nothing/special.txt' >>> dec(b'nothing/special.txt') 'nothing/special.txt' >>> enc(b'HELLO') '_h_e_l_l_o' >>> dec(b'_h_e_l_l_o') 'HELLO' >>> enc(b'hello:world?') 'hello~3aworld~3f' >>> dec(b'hello~3aworld~3f') 'hello:world?' >>> enc(b'the\x07quick\xADshot') 'the~07quick~adshot' >>> dec(b'the~07quick~adshot') 'the\x07quick\xadshot' _AZrcSsi|]}||qSrrr)rrr z#_buildencodefun..~%02xc 3srd}|t|kr7tddD]}z||||V||7}Wn ty,Yqwt|t|ks dSdS)Nrr)rr xrangeKeyError)sil)dmaprrdecodes  z_buildencodefun..decodecs$dfddttDS)Ncs g|] }||dqS)rrr*c)cmapr>rrr,s z5_buildencodefun....)joinr r<rr>rFrHrsz!_buildencodefun..csdt|S)NrC)rGlistrH)rBrrrJr9) r bytechrrKmapr1r(r3lower iteritems)exchrasciistrcapitalsr+kvr)rFrBrAr_buildencodefunps      rVcC tt|S)z~ >>> encodefilename(b'foo.i/bar.d/bla.hg/hi:world?/HELLO') 'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o' ) _encodefnamer'rHrrrencodefilename rYcCrW)z~ >>> decodefilename(b'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o') 'foo.i/bar.d/bla.hg/hi:world?/HELLO' )r _decodefnamerHrrrdecodefilenamerZr\csztjfddtdDtD] }d||<qttdtddD] }||<q(fdd }|S) z >>> f = _buildlowerencodefun() >>> f(b'nothing/special.txt') 'nothing/special.txt' >>> f(b'HELLO') 'hello' >>> f(b'hello:world?') 'hello~3aworld~3f' >>> f(b'the\x07quick\xADshot') 'the~07quick~adshot' csi|] }||qSrrr))rQrrr8sz(_buildlowerencodefun..r5r:r6r7rcsdfddt|DS)NrCcsg|]}|qSrrrDrIrrr,r-z=_buildlowerencodefun..lowerencode..)rGr iterbytestrrHrIrr lowerencodesz)_buildlowerencodefun..lowerencode)r rLr<r3r1r(rN)r+r^r)rFrQr_buildlowerencodefuns   r_r^)sauxsconsprnsnul)scomslptcCs(t|D]\}}|s q|r(|ddvr(dt|dd|dd}|||<nQ|d}|dkr5t|}|dkrA|ddtvs]|d kry|dd d kry|dd d kry|ddtvrydt|d d}|dd ||dd}|||<|ddvr|dddt|dd||<q|S) a Encodes filenames containing names reserved by Windows or which end in period or space. Does not touch other single reserved characters c. Specifically, c in '\:*?"<>|' or ord(c) <= 31 are *not* encoded here. Additionally encodes space or period at the beginning, if dotencode is True. Parameter path is assumed to be all lowercase. A segment only needs encoding if a reserved name appears as a basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux" doesn't need encoding. >>> s = b'.foo/aux.txt/txt.aux/con/prn/nul/foo.' >>> _auxencode(s.split(b'/'), True) ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e'] >>> s = b'.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.' >>> _auxencode(s.split(b'/'), False) ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e'] >>> _auxencode([b'foo. '], True) ['foo.~20'] >>> _auxencode([b' .foo'], True) ['~20.foo'] r. r:rN.r;91) enumerater(findr_winres3_winres4)r dotencoder?nr@ecrrr _auxencodes*    $rnxr;cCs.tt|}t|ddd}t||}|d}tj |\}}g}d} |ddD]4} | dt } | ddvrE| ddd} | dkrNt | } n| dt | } | t kr\n| | | } q/d|} t | dkrs| d7} d| ||}tt |}|dkr|d|}d| |||}|S) N/rbrr`r4rsdh/)rrsha1digestr^splitrnosrsplitext _dirprefixlenr_maxshortdirslenappendrG_maxstorepathlen)rrkrtlepartsbasename_rootextsdirssdirslenpdtdirsres spaceleftfillerrrr _hashencodes6         rcCs@t|}t|d}dt||}t|tkrt||}|S)aeencodes path with a length limit Encodes all paths that begin with 'data/', according to the following. Default encoding (reversible): Encodes all uppercase letters 'X' as '_x'. All reserved or illegal characters are encoded as '~xx', where xx is the two digit hex code of the character (see encodefilename). Relevant path components consisting of Windows reserved filenames are masked by encoding the third character ('aux' -> 'au~78', see _auxencode). Hashed encoding (not reversible): If the default-encoded path is longer than _maxstorepathlen, a non-reversible hybrid hashing of the path is done instead. This encoding uses up to _dirprefixlen characters of all directory levels of the lowerencoded path, but not more levels than can fit into _maxshortdirslen. Then follows the filler followed by the sha digest of the full path. The filler is the beginning of the basename of the lowerencoded path (the basename is everything after the last path separator). The filler is as long as possible, filling in characters from the basename until the encoded path has _maxstorepathlen characters (or all chars of the basename have been taken). The extension (e.g. '.i' or '.d') is preserved. The string 'data/' at the beginning is replaced with 'dh/', if the hashed encoding was used. rr)r'rXrurGrnrr{r)rrkefrrrr _hybridencode4s   rcCsVt|}t|tkrt|dSt|d}dt|d}t|tkr)t|dS|S)NTrr)r'rr{rrXrurGrn)rderrrrr _pathencode[s    r pathencodecCs t|dSNF)r)frrr_plainhybridencodeis rcCsHz|j}dtj@d|@krd}W|SW|Sty#d}Y|Sw)Ni)statst_moder umaskOSError)r moderrr _calcmodems  r) bookmarks narrowspecdatameta 00manifest.d 00manifest.i 00changelog.d 00changelog.i phaserootsobsstorerequires)rs i.tmpcensored)s.idxs.ds.dat.n.nds.sdas d.tmpcensored)rrs.*undo\.[^/]+\.(nd?|i)$cCs|tjkrdSt|SN)rS_IFREG revlog_type)rkindstrrr is_revlogs rcCs6|trtS|trt}|tr|tO}|SdSr)endswithREVLOG_FILES_MAIN_EXTFILEFLAGS_REVLOG_MAINREVLOG_FILES_OTHER_EXTFILETYPE_FILELOG_OTHERREVLOG_FILES_VOLATILE_EXTFILEFLAGS_VOLATILE)rrrrrrs   ri iiirfic@s~eZdZdZddZddZddZdd d Zd d Zdd dZ ddZ dddZ ddZ ddZ ddZddZddZdS) basicstorez&base class for local repository storescCsB||}|j|_t||_|j|_||_t|t|_|j|_ dSr) baserr createmoderawvfsvfsmod filtervfsr'r openerselfrvfstyper rrr__init__s  zbasicstore.__init__cC|jdt|SNrr)rr'rrrrrrGzbasicstore.joincCs|j}|r |d|7}t|jd}g}|j|rf|g}|jj}|rf|}||ddD]6\} } } |d| } t| | | } | durWt| |d}| | t || j fq-| t j krc|rc| | q-|s#||S)z%yields (revlog_type, unencoded, size)rrrT)rN)rrrisdirreaddirpoprr pconvertrzrst_sizerS_IFDIRsort)rrelpathrecurserstriplenr@visitrrrrrfprl_typerlrrr_walks,      zbasicstore._walkNcCstj|j||dS)N) trypendingconcurrencychecker)rr )rrrrrrrs zbasicstore.changelogcCs"t|j|j}t|j|||Sr)r manifestrevlog nodeconstantsr manifestlog)rrepostorenarrowmatch rootstorerrrrszbasicstore.manifestlogccs>|dd|dd}|D] \}}}t|B||fVqdS)a4Like walk, but excluding the changelog and root manifest. When [undecodable] is None, revlogs names that can't be decoded cause an exception. When it is provided, it should be a list and the filenames that can't be decoded are added to it instead. This is very rarely needed.rTrN)rFILEFLAGS_FILELOG)rr undecodablefilesrur>rrr datafiless zbasicstore.datafilesccsnt|dd}|D])\}}}|drt|B||fVq |dr,t|B||fVq t|B||fVq dS)NrCFs 00changelogs 00manifest)reversedrrFILEFLAGS_CHANGELOGFILEFLAGS_MANIFESTLOGFILETYPE_OTHER)rrrrr>rrrtopfiless  zbasicstore.topfilesccs0||D]}|Vq|D]}|VqdS)zreturn file related to data storage (ie: revlogs) yields (file_type, unencoded, size) if a matcher is passed, storage files of only those tracked paths are passed with matches the matcher N)rr)rrr+rrrwalks   zbasicstore.walkcCstSr_datarrrrcopylist zbasicstore.copylistcCdSrrrtrrrrwrite#rzbasicstore.writecCrrrrrrrinvalidatecaches&rzbasicstore.invalidatecachescCrrrrfnrrr markremoved)rzbasicstore.markremovedcCs@dd|f}|j|drdS|ds|d}|j|S)!Checks if the store contains pathrrrrT)rGr existsrrrrrr __contains__,s   zbasicstore.__contains__rNN)__name__ __module__ __qualname____doc__rrGrrrrrrrrrrrrrrrrs     rcs6eZdZddZd fdd ZddZdd ZZS) encodedstorecCsF||d}|j|_t||_|j|_||_t|t|_|j|_ dS)N/store) rrrrrrrrYr rrrrrr9s   zencodedstore.__init__Nc #stt|D]5\}}}zt|}Wnty0|dur)td|}t|||Yqwt ||s7q|||fVqdS)Nsundecodable revlog name %s) superrrr\r=rr StorageErrorrzr)rrrrf1sizef2msg __class__rrrGs      zencodedstore.datafilescCrr)rrYrrrrrGVrzencodedstore.joincCsddgddtDS)NrrcSg|]}d|qSsstore/rr*rrrrr,Zr-z)encodedstore.copylist..rrrrrrYszencodedstore.copylistr)rrrrrrGr __classcell__rrrrr8s rc@sXeZdZddZdddZdddZdd Zd d Zd d ZddZ ddZ ddZ dS)fncachecCs||_d|_d|_t|_dSr)r entries_dirtysetaddls)rr rrrr`s zfncache.__init__NcCs|jdur ||dSdS)zread the fncache file if not already read. If the file on disk is corrupted, raise. If warn is provided, warn and keep going instead.N)r_load)rwarnrrr ensureloadedgs zfncache.ensureloadedc Csd|_z |jddd}Wntyt|_YdSwt|_d}tt|jt dD].}||7}z| d}|j t |d|d ||dd}Wq+tyYYq+w|rrtd }|ri||dn tj|td d ||||dS) z&fill the entries from the fncache fileFfncacherb)rNrC rs$fncache does not ends with a newlines3use 'hg debugrebuildfncache' to rebuild the fncache)hint)r r IOErrorr riter functoolspartialreadfncache_chunksizerindexupdater splitlines ValueErrorrrAbort _checkentriesclose)rr rchunkrErrrrrr os<      z fncache._loadcCsjd|jvr1|dtt|D]!\}}|ds0td|d}|r+||dqt|qdSdS)z-make sure there is no empty string in entriesrCrrs!invalid entry in fncache, line %drN) rseekrgr iterfilerstriprrr)rrr rllinerrrrrs    zfncache._checkentriescCs|jr9|jdus J|j|jB|_t|_|d|jdddd}|jr2|td|jd| d|_|jrf|d|jdddd}|jrY|td|jd| d|_t|_dSdS)NrswbT)r atomictemprFsab) r rr r  addbackupr rr'rGr)rrrrrrrs&   z fncache.writecCs0|jdur |||jvr|j|dSdSr)rr r addrrrrr's  z fncache.addcCsZ|jdur |||jvr|j|dSz |j|d|_WdSty,YdSwNT)rr r remover r=rrrrr)s      zfncache.removecCs*||jvrdS|jdur|||jvSr()r rr rrrrrs   zfncache.__contains__cCs"|jdur |t|j|jBSr)rr rr rrrr__iter__s zfncache.__iter__r) rrrrrr rrr'r)rr*rrrrr]s  &  rc@s.eZdZddZd ddZddZdd Zd S) _fncachevfscCstj||||_||_dSr)rproxyvfsrrencode)rr fncr-rrrrs z_fncachevfs.__init__rcOs||}|dvr6|ds|dr6|jjduo|j|}|r.d|vr.|j|js.d}|s6|j||j||g|Ri|S)N)r/rrrsr+F) r-rrrr rrrr')rrrargskwencodednotloadrrr__call__s  z_fncachevfs.__call__cCs"|r |j||S|j|Sr)r rGr-rrrrrGs z_fncachevfs.joincCs(|ds |dr|j|dSdS)z1generic hook point to lets fncache steer its stewrrN)rrr'rrrr register_filesz_fncachevfs.register_fileN)r/)rrrrr4rGr5rrrrr+s   r+c@s^eZdZddZddZddZddd Zd d Zd d ZddZ ddZ ddZ ddZ dS) fncachestorecCst|rt}nt}||_||d}|j|_|jd|_t||_|j|_||_t |}||_ t ||||_ |j |_ dS)Nrrr) rrr-rrpathseprrrrr+r r)rrrrkr-r r.rrrrs    zfncachestore.__init__cCs|j||Sr)r7r-rrrrrG zfncachestore.joincCs|j|jSr)rrrrrrrgetsize szfncachestore.getsizeNc cst|jD]A}t||sq||}zt|}|dus J||tO}||||fVWqtyG}z |jtj kr=WYd}~qd}~wwdSr) sortedrrr-rrr9rerrnoENOENT)rrrrrrerrrrrrs"    zfncachestore.datafilescCsd}ddgdd|DS)N) rrrrsdhrrrrrrrrrrcSrrrrrrrr,.r-z)fncachestore.copylist..r)rrrrrrszfncachestore.copylistcC|j|dSr)rrrrrrr0r8zfncachestore.writecCsd|j_t|j_dSr)rrr r rrrrr3szfncachestore.invalidatecachescCr>r)rr)rrrrr7r8zfncachestore.markremovedc CsP||}z||WdSty'}z|jtjkrWYd}~dSd}~ww)NTF)r-r9rr;r<)rrrr=rrr_exists:s   zfncachestore._existscCsjdd|f}|d}||jvr||rdS|ds |d7}|jD]}||r2||r2dSq#dS)rrrrrTF)rGrr?rr)rrrPrrrrEs  zfncachestore.__contains__r) rrrrrGr9rrrrrr?rrrrrr6s  r6)N __future__rr;rrvreri18nrr rnoderrrr r r r rutilsr importmodrrrr&r'rr3rVrXr[rYr\r_r^rirjrnr{rxryrrrrrrrrrcompileEXCLUDEDrrrrrFILEFLAGS_OTHERrFILEFLAGS_REVLOG_OTHERrFILETYPE_CHANGELOG_MAINFILETYPE_CHANGELOG_OTHERFILETYPE_MANIFESTLOG_MAINFILETYPE_MANIFESTLOG_OTHERFILETYPE_FILELOG_MAINrrobjectrrrr,r+r6rrrrs|    $   <0 '   m%x#