o ]Lb@sddlmZddlZddlZddlmZddlmZmZm Z ddl m Z ddl m Z mZmZm Z mZmZmZmZddlmZd Zd d Zd d ZddZGdddeZddZddZddZddZddZ ddZ!ddZ"d d!Z#d"d#Z$d$d%Z%d&d'Z&d(d)Z'dSd*d+Z(d,d-Z)d.d/Z*e+d0Z,d1d2Z-d3d4Z.d5d6Z/dTd8d9Z0 dUd:d;Z1dSdd?Z3d@dAZ4dBdCZ5dDdEZ6dFdGZ7dVdIdJZ8dWdKdLZ9dMdNZ:dSdOdPZ;dQdRZr?rrractivezszbmstore.activecCs.|dur||jvrtd|||_d|_dS)Nsbookmark %s does not exist!F)r(AssertionErrorr>r+r?markrrrrM~s  cC t|jSr)lenr(rLrrr__len__ zbmstore.__len__cCrQr)iterr(rLrrr__iter__rTzbmstore.__iter__cCs t|jSr)r iteritemsr(rLrrrrWrzbmstore.iteritemscC |jSr)r(itemsrLrrrrYrTz bmstore.itemscCrXr)r(keysrLrrrrZrTz bmstore.keyscCrXr)r(valuesrLrrrr[rTzbmstore.valuescCs ||jvSrr(rOrrr __contains__rTzbmstore.__contains__cCs |j|Srr\rOrrr __getitem__rTzbmstore.__getitem__NcCs|j||Sr)r(r2)r?rPdefaultrrrr2sz bmstore.getcCs^d|_||jvr ||||j|<|j|}|dur$|g|j|<dS|||dS)NF)r*r(_delr)r2r3r4r?rPrGrHrrr_sets      z bmstore._setcCs`||jvrdSd|_|j|}|j|}t|dkr)|d|ks#J|j|=dS||dS)NFrr)r(r*popr)rRremoverarrrr`s     z bmstore._delcCs|j|gS)z@Return a sorted list of bookmarks pointing to the specified node)r)r2)r?rGrrrnamessz bmstore.namesc Cs|jd}|D]1\}}|j|}|dur||n||||dur9||}|dur3|d}||f||<q||dS)z$Apply a list of changes to bookmarksrNr)changesr2r(r`rb _recordchange) r?rtrrf bmchangesnamerGoldpreviousrrr applychangess       zbmstore.applychangescCs6t|jrdnd}|jdd|j|ddd|jd<d S) zrecord that bookmarks have been changed in a transaction The transaction is then responsible for updating the file content.splainr)rT)location post_finalize1sbookmark_movedN)rr'addfilegenerator_writehookargs)r?rhrorrrrgszbmstore._recordchangec Cs|j}|j|jvrd|_|t|r|j}|}n|j}|}|.|ddddd }| |Wdn1s>wYWddSWddS1sVwYdS)zFactored out for extensibilityNrwT atomictemp checkambig) _bookmarksrMr( _writeactiverrlockrwlockrs)r?rrbmrr{frrr _writerepos    "zbmstore._writerepoc Cs|jrdS|j8|jdur4|jjddddd}|t|jWdn1s.wYn|jjdWdn1sEwYd|_dS)Nbookmarks.currentruTrv) r+r'r|r>rwriter fromlocal tryunlink)r?r~rrrrzs   zbmstore._writeactivecCsJtt|jD]\}}|dt|t|fqd|_|j dS)Ns%s %s T) sortedr rWr(rrr rr*r'invalidatevolatilesets)r?r!rjrGrrrrsszbmstore._writecCs&|dkr|jr |jSttd|S)N.sno active bookmark)rMr RepoLookupErrorr)r?bnamerrr expandnames zbmstore.expandnameFc sjd}jvr|srjkr|krgSj}jj|gj}fddjD}|vrP|vrPtjgSfdd|D}tj|} tj|jrjj t dt |f| St t djvsjjkr|st t dtdkr|sz tj} Wn t jyd } Ynw| rˈjjt d gS) acheck repo for a potential clash of mark with an existing bookmark, branch, or hash If target is supplied, then check that we are moving the bookmark forward. If force is supplied, then forcibly move the bookmark to a new commit regardless if it is a move forward. If divergent bookmark are to be deleted, they will be returned as list. rcs6g|]}|ddddddkrj|qS@rr)r0r(.0b)rPr?rr s  z)bmstore.checkconflict..cs*g|]}j|vs|kr|qSr)r'revr)ancr?targetrrr,s$s%moving bookmark '%s' forward from %s s.bookmark '%s' already exists (use -f to force)s5a bookmark cannot have the name of an existing branchFs[bookmark %s matches a changeset hash (did you leave a -r out of an 'hg bookmark' command?) )r'rGr(rr, ancestorsdivergent2delete validdestr7statusrrr Abort branchmapdirstatebranchrRr isrevsymbol LookupErrorr8) r?rPforcercurrbmctxdivs deletefromdelbms shadowhashr)rrPr?rr checkconflict sb    zbmstore.checkconflictr)FN)__name__ __module__ __qualname____doc__rKpropertyrMsetterrSrVrWrYrZr[r]r^r2rbr`rermrgrrzrsrrrrrrr$>s4 .      r$cCs<|jd}t|pdgd}|dks||vrd}|S)z Get the active bookmark. We can have an active bookmark that updates itself as we commit. This function returns the name of that bookmark. It is stored in .hg/bookmarks.current rrnrN)rtryreadr r1 splitlines)rmarkscontentrPrrrr=Qs r=cCs||j_|jdS)z Set the given bookmark to be 'active', meaning that this bookmark will follow new commits that are made. The name is recorded in .hg/bookmarks.current NryrMrzrrPrrractivate`srcCsd|j_|jdS)z7 Unset the active bookmark in this repository. Nrrrrr deactivatejsrcCs6|j}|j}dd|dD}||vo|||vS)a Tell whether the 'active' bookmark (the one that follows new commits) points to one of the parents of the current working directory (wdir). While this is normally the case, it can on occasion be false; for example, immediately after a pull, the active bookmark can be moved to point to a place different than the wdir. This is solved by running `hg update`. cSsg|]}|qSr)rG)rprrrr}z&isactivewdirparent..N)_activebookmarkryparents)rrPrrrrrisactivewdirparentrs rcs^g}|j}fdd|D}|D]}|dksd|vrq|r,|||vr,|kr,||q|S)zZfind divergent versions of bm on nodes in deletefrom. the list of bookmark to delete.cs0g|]}|ddddddkr|qSrr0rbmrrrs*z$divergent2delete..r)ryr3)rrrtodeleter divergentrPrrrrs  rcCs\|jstd|jddd}g}t|jD]\}}|ddd|kr+||q|S)avGiven a repo with an active bookmark, return divergent bookmark nodes. Args: repo: A repository with an active bookmark. Returns: A list of binary node ids that is the full list of other revisions with bookmarks divergent from the active bookmark. If there were no divergent bookmarks, then this list will contain only one entry. s9headsforactive() only makes sense with an active bookmarkrrr)rr6r0r rWryr3)rrjheadsrPnrrrheadsforactives  rcCsLd\}}|j}t|r|d}||fS|r"|td||}||fS)zReturn a tuple (activemark, movemarkfrom) indicating the active bookmark and where to move the active bookmark from, if needed.)NNrsupdating to active bookmark %s )rrrGrr)r7rcheckout movemarkfrom activemarkrrrcalculateupdates rc s8|}jjs dSg}|vrI|fddD}jgfdd|D}trI|ft|D] }||dfqO|r 1 d} ||Wdn1swwYWdt |SWdt |S1swYt |S)NFcs8g|]}|ddddddkr|qSrrr)rMrrrrrs   zupdate..cs(g|]}|vs|kr|qSr)rrGr)rnewrrrs(bookmark) ryrMr,rrrr3rGrr{ transactionrmbool)rrrGrrirrrhr)rMrrrrrupdates4 ( rcCsd|vo |d S)Nr)endswith)rrrr isdivergentrrccsHt|di}|jj}t|D]\}}||r!t|s!||fVqdS)Nry)rr,hasnoder rWr)rrrkvrrrlistbinbookmarkss  rcCs&i}t|D] \}}t|||<q|Sr)rr)rdbookrGrrr listbookmarksrc Cst|rdSt|rt}n|}|||dq}|j}t| |d}||krI||krI WdWdWddS|dkrS|dfg}n"||vrl WdWdWddS||| fg}| ||| WdWdWddS1swYWdn1swYWddSWddS1swYdS)NFrrnT) rrrnullcontextmanagerr|r{rryrr2rGrm) rkeyrkrr|rhrexistingrfrrr pushbookmarks( ( ( rcCs|rt|}n t|}t|}||B}ggggggggf}|dj}|dj} |dj} |dj} |dj} |dj} |dj}|dj}t|D]}||vre||vr]| |d ||fqI||d d fqI||vrs||||d fqI||}||}||kr||||fqI||vr||vr||}||}||krt|||r| |||fqI| |||fqIt|||r| |||fqI| |||fqI| |||fqI|S) aCompare bookmarks between srcmarks and dstmarks This returns tuple "(addsrc, adddst, advsrc, advdst, diverge, differ, invalid)", each are list of bookmarks below: :addsrc: added on src side (removed on dst side, perhaps) :adddst: added on dst side (removed on src side, perhaps) :advsrc: advanced on src side :advdst: advanced on dst side :diverge: diverge :differ: changed, but changeset referred on src is unknown on dst :invalid: unknown on both side :same: same on both side Each elements of lists in result tuple is tuple "(bookmark name, changeset ID on source side, changeset ID on destination side)". Each changeset ID is a binary node or None. Changeset IDs of tuples in "addsrc", "adddst", "differ" or "invalid" list may be unknown for repo. If "targets" is specified, only bookmarks listed in it are examined. rrrN)setr3rrr)rsrcmarksdstmarkstargetsbset srcmarkset dstmarksetresultsaddsrcadddstadvsrcadvdstdivergedifferinvalidsamersciddcidsctxdctxrrrcomparebookmarkssJ            rc Cs|dkrd}|drt|j}t|D]\}}|j}|dr(t|j}||kr4d||fSqtddD]}d||f} | |vsL|| |krP| Sq:dS) zReturn appropriate diverged bookmark for specified ``path`` This returns None, if it is failed to assign any divergent bookmark name. This reuses already existing one with "@number" suffix, if it refers ``remotenode``. rrnsfile:s%s@%srds%s@%dN) startswithrurlpath list_pathsrawlocrange) r7rr localmarks remotenoderjrlocxrrrr_divergeOs"      rcCs&i}|D] \}}t|||<q|Sr)rYr)rbinremotemarksrjrGrrrunhexlifybookmarksnrrs>20sHcCsHg}|D]\}}|s|jj}|t|t|||qd|S)amencode a '(bookmark, node)' iterable into a binary stream the binary format is: :node: is a 20 bytes binary node, :bookmark-length: an unsigned short, :bookmark-name: the name of the bookmark (of length ) wdirid (all bits set) will be used as a special value for "missing" rn) nodeconstantswdiridr3 _binaryentrypackrRjoin)r bookmarks binarydatarrGrrr binaryencodexs   rcCstj}g} ||}t||kr|rttd |St|\}}||}t||kr8|r8ttd||jj kr@d}| ||fq)aodecode a binary stream into an '(bookmark, node)' iterable the binary format is: :node: is a 20 bytes binary node, :bookmark-length: an unsigned short, :bookmark-name: the name of the bookmark (of length )) wdirid (all bits set) will be used as a special value for "missing" Tsbad bookmark streamN) rsizereadrRr rrunpackrrr3)rstream entrysizebooksentryrGlengthbookmarkrrr binarydecodes$       rcCsg}|j}t|D]\}}|||dkr(||vr(||||jtd|fq |D]}||vr?||d|jtd|fq+|S)zMcomputes the bookmark changes that set the local bookmarks to remotemarksNupdating bookmark %s sremoving bookmark %s )ryr rWr2r3debugr)r7r remotemarkschangedrridrrrmirroring_remotesrrc Cs|j}t|||\}}}} } } } } |j}|j}|ddr"|j}}t|}g}|D]1\}}}||vrA||||td|fq*||vr[| ||td|t |ddfq*|D]\}}}||||td|fq^| dd |D| D]>\}}}||vr| |||||td |fq}t |||||}|r||||td ||ffq}|td |q}|| D]\}}}||vr| |||||td |fq| D]\}}}||vr| ||td|t |ddfq|S) zqcomputes the bookmark changes that merge remote bookmarks into the local bookmarks, based on comparebookmarkssuisquietbookmarkmovesadding remote bookmark %s s0remote bookmark %s points to locally missing %s N rcss|]}|dVqdS)rNr)rrrrr sz&merging_from_remote..simporting bookmark %s s#divergent bookmark %s stored as %s sAwarning: failed to assign numbered name to divergent bookmark %s )ryrrr8 configboolrrr3rrdrdifference_updatediscardr)r7rrrexplicitrrrrrrrrrrr8rrrrdbrrrmerging_from_remotes        rcCs|dkrdS|d|dkrt|||}nt|||||}|rK|}g} dd} t|| dD]\} } } }| | | f| |q/|j||| dSdS)Nignoreschecking for updated bookmarks mirrorcSs|d|dpdfS)Nrrrnr)trrrrz"updatefromremote..)r)rrrrr3ryrm)r7rrrtrfuncrmoderrhrfrrrGwritermsgrrrupdatefromremote s  r(cs6|dkr |tddS|td|}t|dddi}Wdn1s/wYg|jr>d d nd d |jrMfd d }nfdd }|dkr|j}t | t | B}t |D]:} | | } | | } | | kr|qk| dur|| t | tdqk| dur|| t |jtdqk|| t | tdqknYt|||j} | \} }}}}}}}| D]\} }}|| t |tdq|D]\} }}|| t |tdq|D]\} }}|| t |tdq|D]\} }}|| t |tdqs |tddSt D]}||qdS)z*Show bookmarks incoming from other to repor s+bookmarks exchange disabled with this path r searching for changed bookmarks listkeys namespacerNcS|Srrrrrrr#3zincoming..cS |ddSNrrr-rrrr#5 cd|||fdSNs %-25s %s %s r3rrstgetid incomingsrradd8zincoming..addcd||fdSNs %-25s %s r4r5r7rrr:=r!addedsremovedchangedadvanceddivergedno changed bookmarks found r)rrcommandexecutorr callcommandresult debugflagverboseryrrZrr2rnullidrr)r7rpeerr%err:rallmarksrrremrrrrrrrrrrrsrr7rincoming sf        rPcs`|tdt|d}t||j|}|\}}}}} } } } g|jr)ddndd|jr8fdd} nfdd} |D]\}}}| |t|td qA|D] \}}}| |d td qS|D]\}}}| |t|td qc| D]\}}}| |t|td qu| D]\}}}| |t|tdqs|tddSt D]}| |qdS)z*Show bookmarks outgoing from repo to otherr)rcSr,rrr-rrrr#sr.zoutgoing..cSr/r0rr-rrrr#ur1cr2r3r4r5r8 outgoingsrrr:xr;zoutgoing..addcr<r=r4r5rQrrr:}r>r?s( sdeletedrArBr@rCrr) rrrlistkeysrryrGrHrrr)r7rotherrrNrrrrrrrrr:rrrrOrrQroutgoingis6   rUc Csr|}t|dddi}Wdn1swYt|||j}|\}}}}} } } } t|t|fS)zCompare bookmarks between repo and other for "hg summary" output This returns "(# of incoming, # of outgoing)" tuple. r*r+rN)rDrrErFrryrR) rrJrKrrNrrrrrrrrrrrsummarys  rVcCsF|}||kr dS|sdS|jr|t||gvS||S)z?Is the new bookmark destination a valid update from the old oneFT) unfilteredobsstorerGr foreground isancestorof)rrkrrrrrs rcCs,|}|s ttdt||d|S)zvreturn a valid version of a potential bookmark name Raises an abort error if the bookmark name is not valid. s4bookmark names cannot consist entirely of whitespacer)r/r InputErrorrr checknewlabelrrrr checkformatsr]cCs`|j}g}|D]}||vrttd|||jkrt|||dfq||||dS)z]remove a mark from the bookmark store Raises an abort error if mark does not exist. bookmark '%s' does not existN)ryr r[rrrr3rm)rrhrerrfrPrrrdeletes r_Fc Cs|j}t||}||vrttd|g}|||D] } || dfq||||f|dfg|||||j |krI|sKt ||dSdSdS)arename a bookmark from old to new If force is specified, then the new name can overwrite an existing bookmark. If inactive is specified, then do not activate the new bookmark. Raises an abort error if old is not in the bookmark store. r^N) ryr]r r[rrr3extendrmrr) rrhrkrrinactiverrPrfrrrrrenames rbcCs|j}|d}d}g} |rt||gd}t||d} | o&| du} | dur1| } | } | s9J|D]1} t|| } |durH| }|rT| |jkrTt |q;| | || D] }| |dfq[| | | fq;| sqdS| r|j td| dd| rt|| dd| }|j d||||| | r|||krt||dS|| kr||jkrt |dSdSdS)a$add a list of bookmarks If force is specified, then the new name can overwrite an existing bookmark. If inactive is specified, then do not activate any bookmark. Otherwise, the first bookmark is activated. Raises an abort error if old is not in the bookmark store. rNsnowarns bookmarking hidden changeset %s rs(%s) )ryrGrunhidehashlikerevs revsinglerp1r]rrrr3hiddenr7r8rrobsoleter _getfilteredreasonrmr)rrhrerrrarrnewactrfctx activatenewtgtrPrr'rrr addbookmarkssF     rmc Cs|j}t|dkr|r|tdtt|D]Q\}\}}}||j |d|j s8|j d||d|j dd||ddd t |} |j|j d | d |j||||d|jt|vd | d qdS)zprivate method to print bookmarks Provides a way for extensions to control how bookmarks are printed (e.g. prepend or postpend names) rsno bookmarks set rs %s )labelrs%sr%srev nodes %d:%s)rM N)hexfuncrRisplainrrrr rW startitemcontextquietplainrr colwidth condwriter,rdataactivebookmarklabel) r7rfmbmarkshexfnbmarkrprefixrnpadrrr_printbookmarks-s*   rc Csx|j}i}|p|D])}||vrttd||j}||kr%dt}} nd\}} |||| f||<q t||||dS)ztprint bookmarks by the given formatter Provides a way for extensions to control how bookmarks are printed. r^*)r%rnN)ryr r[rrrzr) r7rr{rerr|r~rMrrnrrrprintbookmarksIs  rcCs,|durd}|dur d}|t|t|dS)Nrn)rsnodesoldnode)r)rjrkrrrrpreparehookargs]s rr)r)rN)FF)NFF)= __future__rr;structi18nrrGrrrr rr r r r rrrutilsrrzrrr#objectr$r=rrrrrrrrrrrrrrStructrrrrrr(rPrUrVrr]r_rbrmrrrrrrrs`   (      L  M I1  9