Qc@sdZddlmZmZmZmZddlmZddlZddl Z ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZejZejZejZejZe jZdZdZdZdZeZeZ e eBZ!eeBZ"dZ#d Z$d Z%e j&Z&e j'Z'd Z(d Z)d Z*eeZ+dZ,dZdZ-dZ.de/fdYZ0dZ1dZ2dZ3de/fdYZ4de/fdYZ5dS(sStorage back-end for Mercurial. This provides efficient delta storage with O(1) retrieve and append and O(changes) merge between branches. i(tbinthextnullidtnullrev(t_NiiiiiicCst|d?S(Ni(tint(tq((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt getoffset.scCst|d@S(Ni(R(R((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytgettype1scCstt|d>|BS(Ni(tlong(toffsetttype((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt offset_type4scCsv|tkr(tj}|j|n7||g}|jt|d}|j|d|j||jS(sgenerate a hash from the given text and its parent hashes This hash combines both the current file contents and its history in a manner that makes it easy to distinguish nodes with the same content in the revision graph. ii(Rtnullhashtcopytupdatetsortt_shatdigest(ttexttp1tp2tstl((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pythash9s     cCs|s |S|d}|dkr$|S|dkrvyt|SWqvtjk rr}ttdt|qvXn|dkr|dSttd|dS( s decompress the given input ittxsrevlog decompress error: %stuisunknown compression type %rN(t _decompresstzlibterrort RevlogErrorRtstr(Rttte((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt decompressNs   # s >4l20s20s20si8t revlogoldiocBs#eZdZdZdZRS(cCstjt|_dS(N(tstructtcalcsizet indexformatv0tsize(tself((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt__init__jsc Cs%|j}g}itt6}d}}t|}x|||kr||||!} ||7}tt| } t| dd| dd| d| d|j| dt|j| dt| df} |j| ||| d<|d7}q5W|jdddddddtf||dfS( Niiiiiiii( R(RRtlent_unpackR'R tgettappendtNone( R)tdatatinlineRtindextnodemaptntoffRtcurR"te2((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt parseindexms      (3 %cCs{t|dr%ttdnt|d|d|d|d||d||d|df}tt|S( Nisindex entry flags need RevlogNGiiiiii(RRRRt_packR'(R)tentrytnodetversiontrevR7((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt packentrys "'(t__name__t __module__R*R8R>(((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR$is  s>Qiiiiii20s12xi s>ItrevlogiocBs#eZdZdZdZRS(cCstjt|_dS(N(R%R&t indexformatngR((R)((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR*scCs1tj||\}}|t|dd|fS(NR3(tparserst parse_index2tgetattrR/(R)R0R1R2tcache((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR8scCs9tt|}|dkr5tt||d}n|S(Nii(R9RBt versionformat(R)R:R;R<R=tp((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR>s (R?R@R*R8R>(((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyRAs  trevlogcBs?eZdZdZdZdZdZdd9dZe j dZ dZ d Z d Zd Zd Zd ZdZdZdZdZdZdZdZeZdedZdZd9d9dZd9d9dZd9d9dZd9d9dZ dZ!dZ"d9d9dZ#dZ$dZ%d Z&d!Z'd"Z(d#Z)d$Z*d%Z+d&Z,d'Z-d(Z.d)Z/d*Z0d+Z1d,Z2d-Z3d.Z4d/Z5d9d0Z6d9d1Z7d2Z8d3Z9d9d4Z:d5Z;d6Z<d7Z=d8Z>RS(:sM the underlying revision storage object A revlog consists of two parts, an index and the revision data. The index is a file with a fixed record size containing information on each revision, including its nodeid (hash), the nodeids of its parents, the position and offset of its data within the data file, and the revision it's based on. Finally, each entry contains a linkrev entry that can serve as a pointer to external data. The revision data itself is a linear collection of data chunks. Each chunk represents a revision and is usually represented as a delta against the previous chunk. To bound lookup time, runs of deltas are limited to about 2 times the length of the original version data. This makes retrieval of a version proportional to its size, or O(1) relative to the number of revisions. Both pieces of the revlog are written to in an append-only fashion, which means we never need to rewrite a file to insert or remove data, and can use some simple techniques to avoid the need for locking while reading. c Cs||_|d d|_||_d|_d|_d|_g|_i|_it t 6|_ d|_ t }t|dd}|dk rd|krd|kr|tO}qqd}nd}t|_yd|j|j}|j}|jt|dkr0tjt|d d}t|_nWn+tk r^}|jtjkr_q_nX||_|t@|_|t@|_|d@}|d @} | t kr|rt!t"d |j|d ?fnk| t#kr |t$@r t!t"d |j|d ?fn.| t#kr9t!t"d |j| fnt%|_&|jt krct'|_&ny|j&j(||j} Wn0t)t*fk rt!t"d|jnX| \|_} |_| dk r| |_+|_ n|js|j,ndS(s create a revlog object opener is a function that abstracts the file opening operation and can be used to implement COW semantics or the like. is.dittoptionstrevlogv1t generaldeltaiis*index %s unknown flags %#04x for format v0is)index %s unknown flags %#04x for revlogngsindex %s unknown format %dsindex %s is corruptedN(ii(iRJi(-t indexfiletdatafiletopenerR/t_cachet _basecachet _chunkcacheR2t_pcacheRRt _nodecachet_nodepostREVLOG_DEFAULT_VERSIONREtREVLOGGENERALDELTAtTruet _initemptytreadtcloseR+R%tunpackRGtFalsetIOErrorterrnotENOENTR<tREVLOGNGINLINEDATAt_inlinet _generaldeltatREVLOGV0RRtREVLOGNGtREVLOGNG_FLAGSRAt_ioR$R8t ValueErrort IndexErrorR3t _chunkclear( R)RPRNtvtoptstitftinsttflagstfmttdR3((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR*sn                            cCs|jt|jdS(Ni(R;R+R2(R)((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyttipscCst|jdS(Ni(R+R2(R)((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt__len__scCsttt|S(N(titertxrangeR+(R)((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt__iter__sicCsPd}|dk r4||kr'd}n||7}n t|}t|||S(s8iterate over all rev in this revlog (from start to stop)iiN(R/R+Rw(R)tstarttstoptstep((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytrevs s     cCs|j|jd|jS(Ni(R=R;RU(R)((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR3scCs.y|j|tSWntk r)tSXdS(N(R=RYtKeyErrorR^(R)R;((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pythasnodes   cCsBy|jjWn*tk r=itt6|_d|_nXdS(N(RUt clearcachestAttributeErrorRRR/RV(R)((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR!s  cCsy|j|SWntk r=t||jtdntk r|j}|j}|j}|dkrt |d}nxOt |ddD];}||d}|||<||kr|d|_|SqWt||jtdnXdS(Nsno nodeiiii( RURt LookupErrorRNRR}R2RVR/R+Rw(R)R;R4RnRHtrRl((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR=(s"         cCs|j|dS(Ni(R2(R)R=((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyR;=scCs|j|dS(Ni(R2(R)R=((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytlinkrev?scCs>|j}||j|}||dd||ddfS(Niii(R2R=(R)R;RnRs((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytparentsAs cCs|j|dd!S(Nii(R2(R)R=((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt parentrevsEscCst|j|dd?S(Nii(RR2(R)R=((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyRyGscCs|j||j|S(N(Rytlength(R)R=((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytendIscCs|j|dS(Ni(R2(R)R=((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyRKscCsB|j}||d}x$||kr=|}||d}qW|S(Ni(R2(R)R=R2tbase((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt chainbaseMs  cCs|j|dd@S(Nii(R2(R)R=((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyRqTscCsC|j|d}|dkr!|S|j|j|}t|S(s?return the length of the uncompressed text for a given revisionii(R2trevisionR;R+(R)R=RR!((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytrawsizeVs  cCstj||d|d|S(sGenerate the ancestors of 'revs' in reverse topological order. Does not generate revs lower than stoprev. See the documentation for ancestor.lazyancestors for more details.tstoprevt inclusive(tancestort lazyancestors(R)R|RR((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt ancestors`sccst|}|tkr2x|D] }|VqWdSt|}xf|jd|dD]N}xE|j|D]4}|tkrk||krk|j||VPqkqkWqUWdS(s$Generate the descendants of 'revs' in revision order. Yield a sequence of revision numbers starting with a child of some rev in revs, i.e., each revision is *not* considered a descendant of itself. Results are ordered by revision number (a topological sort).NRyi(tminRtsetR|Rtadd(R)R|tfirstRntseenR((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt descendantsis      csx|dkrtg}n|dkr3|j}ng|D]}|j|^q:}g|D]}|j|^q\}t|j|jtj|t}t j fd|D}xk|r;|j }||krqq|j|x3|j |D]"}|kr|j |qqWqWt|}|jg|D]}|j|^q\fS(sReturn a tuple of the ancestors of common and the ancestors of heads that are not ancestors of common. In revset terminology, we return the tuple: ::common, (::heads) - (::common) The list is sorted by revision number, meaning it is topologically sorted. 'heads' and 'common' are both lists of node IDs. If heads is not supplied, uses all of the revlog's heads. If common is not supplied, uses nullid.c3s!|]}|kr|VqdS(N((t.0R(thas(s4/sys/lib/python2.7/site-packages/mercurial/revlog.pys sN(R/RtheadsR=RRRRRtutiltdequetpopleftRR.tlistRR;(R)tcommonRR4tmissingtvisitRRH((Rs4/sys/lib/python2.7/site-packages/mercurial/revlog.pytfindcommonmissing~s,   ""          cCsI|dkrtg}n|dkr3|j}ntj|||jS(sxReturn the revision numbers of the ancestors of heads that are not ancestors of common. More specifically, return a list of revision numbers corresponding to nodes N such that every N satisfies the following constraints: 1. N is an ancestor of some node in 'heads' 2. N is not an ancestor of any node in 'common' The list is sorted by revision number, meaning it is topologically sorted. 'heads' and 'common' are both lists of revision numbers. If heads is not supplied, uses all of the revlog's heads. If common is not supplied, uses nullid.N(R/RtheadrevsRtmissingancestorsR(R)RR((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytfindmissingrevss    cCs|dkrtg}n|dkr3|j}ng|D]}|j|^q:}g|D]}|j|^q\}gtj|||jD]}|j|^qS(s.Return the ancestors of heads that are not ancestors of common. More specifically, return a list of nodes N such that every N satisfies the following constraints: 1. N is an ancestor of some node in 'heads' 2. N is not an ancestor of any node in 'common' The list is sorted by revision number, meaning it is topologically sorted. 'heads' and 'common' are both lists of node IDs. If heads is not supplied, uses all of the revlog's heads. If common is not supplied, uses nullid.N(R/RRR=RRRR;(R)RRR4R((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt findmissings   ""c Csgggf}|dk r\t|}|s1|Stg|D]}|j|^q;}ntg}t}|tkr|dkrg|D]}|j|^qtgt|jfS|dkrt|d}d}i}nt|}|s|St }t j |t }t |} t g| D]}|j|^q-}x| r| j}|tkrrqNn|j|}||krN||kr|j|| jg|j|D]} | tkr| ^qq||kr|j|qqNqNW|s |S|tkrtg|D]}||kr|^q}|rmtg|D]}|j|^qL}q|Snt}tg}t |} | j}g} x|jdt |dd|dD]z}|j|}t } |tkrt} n|| kr`t} ||krt|j|} | d| ksJ| d| kr]|j|q]qnKt|j|} | d| ks| d| kr| j|t} n| r|dks||kr| j||dk r||krt||R2R;treplaceR(Rk( R)ttrtfpttrinfottrindextdataoffRRRnR"((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytcheckinlinesizes4,      !   ( c Cst|||}||jkr%|Sd}|jsL|j|jd}n|j|jd} z)|j|||||||| | SWd|r|jn| jXdS(sadd a revision to the log text - the revision data to add transaction - the transaction object used for rollback link - the linkrev data to add p1, p2 - the parent nodeids of the revision cachedelta - an optional precomputed delta Rsa+N( RR3R/RcRPRORNt _addrevisionR\( R)Rt transactiontlinkRRt cachedeltaR;tdfhtifh((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt addrevisions   cCs0|sd|fSt|}d }|dkr1n|dkrtj}g}d}x=||kr|d }|j|j|||!|}qXW|j|jttt||krdj |}qn t |}|d kst||kr&|ddkrd|fSd|fSd|fS( s7 generate a possibly-compressed representation of text RJi,i@BiiiRRNi( R+R/Rt compressobjR.tcompressRtsumRtjoint _compress(R)RRRtzRHtpostpos2((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyRs.          c  s[|g fd fd} t } | d} | } } j| d}d} j j j }}| tkr1 jr |dkr| |}q|dkr| |}q| | }n | | }|\}}}} }n|dkrctj j dd}n t|}|dks||dkr} j |}t|dt|d}| } }nt |||| |||f} j j d|| j< jj| j j| } js|j j|j j| t||drj|dnj|djj|ni| jj7|j j| j|j|dj|d j|t|tkrH| |f _n| |f _S(s internal function to add revisions to the log see addrevision for argument descriptions. invariants: - text is optional (can be None); if not set, cachedelta must be set. if both are set, they must correspond to each other. csddk rdSr+jnjjjd}tj|ddR;R<RcRRORNRRR(RR R RQ(R)R;RRRRRRRRRtcurrtprevRRRqRstp1rtp2rRRR0ttextlenR"R:(( RRRRRRR;R RRR)s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyRsh $            !    c #s6t|dkr!|jVdSjr6|tk s<|rytj}tfd|D}|j|}n(tg|D]}j |^q}j |dd}|j d|x\t t|dD]D}||||d} } x"|j | | D] } | VqWqW|jVdS(sCalculate a delta group, yielding a sequence of changegroup chunks (strings). Given a list of changeset revs, return a set of deltas and metadata corresponding to nodes. The first delta is first parent(nodelist[0]) -> nodelist[0], the receiver is guaranteed to have this parent as it has all history before these changesets. In the case firstparent is nullrev the changegroup starts with a full revision. iNc3s|]}j|VqdS(N(R=(RR4(R)(s4/sys/lib/python2.7/site-packages/mercurial/revlog.pys si(R+R\RdR^tdagutilt revlogdagRt linearizetsortedR=RRRwtrevchunk( R)tnodelisttbundlertreordertdagR|R4RHRRRR((R)s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytgroupzs  ( c Csg}d }t|}d}|r:|j|d}n|j|jd}||jj} |jr|j|j|| |d } n>|j|j| ||j|j ||j|j d} zd } xt r\|j | } | sPn| d}| d} | d}| d}| d }| d }|j |||}||j krd|} qnxA| |fD]3}||j krqt||jtd qqqqW||j krt||jtd n|j|}|j|d ||| |||f|| } | r|j r|j|j|j d} |j|jd}qqWWd | rt| jn|jX|S(s add a delta group given a set of deltas, add them to the revision log. the first delta is against its parent, which should be in our log, the rest are against the previous delta. iisa+RR;RRtcst deltabaseRsunknown parentsunknown delta baseN(R/R+RRPRNRhR(RcRRORYt deltachunkR.R3RRR=RR\(R)tbundlet linkmapperRtcontentR;RRRtisizeRRt chunkdataRRR)R*RRRHtbaserev((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytaddgroupsb                   cCst|dkrdSx-|D]!}|j|d|krPqqWdS|j|}|js|j|j|||jj}n|||jj7}|j|j|d|_ |j x0t |t|D]}|j |j|=qW|j|d5dS(s7truncate the revlog on the first revision with a linkrev >= minlink This function is called when we're stripping revision minlink and its descendants from the repository. We have to remove all revisions with linkrev >= minlink, because the equivalent changelog revisions will be renumbered after the strip. So we truncate the revlog on the first of these revisions, and trust that the caller has saved the revisions that shouldn't be removed and that it'll re-add them after this truncation. iNii(R+R2RyRcRRORhR(RNR/RQRkRwR3R;(R)tminlinkRR=RR((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytstrips"    c Csd}t|r7td|jt|d}nyF|j|j}|jdd|j}|j||}Wn1tk r}|j t j krnd}nXy|j|j }|jdd|j}|j|j j }td||}|||}|jrvd} x*|D]"} | td|j| 7} q/Wd}|t||| }nWn1tk r}|j t j krnd}nX||fS(Niii(R+RRRPRORttellR\R_R`RaRNRhR(RcR( R)texpectedRotactualtddRpRRntdit databytesR((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt checksizes@ %          cCs,|jg}|js(|j|jn|S(N(RNRcR.RO(R)tres((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pytfiles8s  N(?R?R@t__doc__R*RtRuRxR/R|Rt propertycacheR3R~RR=R;RRRRyRRRRqRR(R^RRRRRRRRRRRRRRRRRRRRRRRkRRRRRRRRR(R2R4R;R=(((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyRIsr D                  *  "  "            @  '   k & J ) %ii(6R>R;RRRRti18nRRRRCRRRR%RR`tpackR9R]R,RR R#Rtsha1RReRfRbRXtREVLOG_DEFAULT_FLAGStREVLOG_DEFAULT_FORMATRWRgRRRRRRRR R RR't v0shaoffsettobjectR$RBt ngshaoffsetRGRARI(((s4/sys/lib/python2.7/site-packages/mercurial/revlog.pyt sH"H$               +