o ]Lb@sddlmZmZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z ddl mZmZmZddlmZddlmZmZmZmZmZmZmZmZmZmZmZmZmZ ddl!m"Z"m#Z#m$Z$m%Z%ej&Z&e'd Z(e'd Z)e'd Z*ej+Z+ej,Z,ej-Z-d d Z.gdZ/ej0ddZ1ddZ2Gddde3Z4ddZ5Gddde3Z6Gddde3Z7Gddde7Z8Gddde8Z9Gdd d e3Z:Gd!d"d"e7Z;e'd#ZGd&d'd'e3Z?Gd(d)d)e3Z@Gd*d+d+e3ZAd,d-ZBd}d.d/ZCGd0d1d1e3ZDGd2d3d3e3ZEd4d5ZFd6d7ZGd}d8d9ZHd:d;ZIdd?ZKd@dAZLdBdCZMdDdEZNd~dHdIZOdJdKZP Gd~dLdMZQdNdOZR GddPdQZS F  G ddRdSZT GddTdUZU  F  G ddVdWZVddXdYZWGdZd[d[eXZYejZZ[ejZZZej\Z\          dd\d]Z]       dd^d_Z^d`daZ_dbdcZ`dddeZadfdgZbdhdiZcdjdkZddldmdndoZedpdqZfdrdsZgdtduZhdvdwZiddydzZjd{d|ZkdS))absolute_importprint_functionN_)hexsha1nodeconstantsshort)open) copies diffhelperdiffutilencodingerrormailmdiffpathutilpycompatscmutilsimilarutilvfs)dateutilhashutilprocutil stringutilsdiff --git a/(.*) b/(.*)s (\t+|[^\t]+)s9(\t+| +|[a-zA-Z0-9_\x80-\xff]+|[^ \ta-zA-Z0-9_\x80-\xff])c sddddfdd}fdd}fd d }fd d }fd d}Gdddt}d}g}dg} t|ds@||}|D]H} || | drU|||S| dra|||S| |r|d}| ddd| vr{|||SqB| dr|r|||SqB||S)z6return an iterator of individual patches from a streamcSsD|r |dr dS|drdS|dd}t|dko!d|d vS) N)  T)r-+F: rrr) startswithsplitlen)lineinheaderlr(1/usr/lib/python3/dist-packages/mercurial/patch.pyisheaderCs   zsplit..isheadercSstd|SN)stringiojoin)linesr(r(r)chunkMszsplit..chunkc3s\d}|D]}|s d}|s|dr|Vg}d}||q|r,|VdSdS)NTF# HG changeset patch)stripr"appendstreamcurr&r%r0r(r)hgsplitPs  zsplit..hgsplitc3sp|D]}|drt|ddD]}|Vqg}||q|r4t|ddD]}|Vq.dSdS)NFrom r)r"r#r3)r5r6r%cr7r(r) mboxsplit`s  zsplit..mboxsplitc 3sxdd}|D]}||q|}t|}|s#||VdSd}|D]}|}||vr4q)||Vq)dS)NcSs,t}tj|dd}|||d|S)NF) mangle_from_r)r-r Generatorflattenseek)mfpgr(r(r)msgfpns   z'split..mimesplit..msgfp text/plains text/x-diffs text/x-patch)r3rparse is_multipartwalkget_content_type) r5r6rCr%r:r@ok_typespartctr7r(r) mimesplitms    zsplit..mimesplitc3sbd}|D] }|s||r|Vg}d}|r ||s d}||q|r/|VdSdSNFTr3r4r0r*r(r) headersplits  zsplit..headersplitc3s|VdSNr()r6r7r(r) remainderszsplit..remainderc@s(eZdZddZddZddZeZdS)zsplit..fitercS ||_dSrR)rAselfrAr(r(r)__init__ zsplit..fiter.__init__cS|SrRr(rVr(r(r)__iter__zsplit..fiter.__iter__cSs|j}|s t|SrR)rAreadline StopIterationrVr'r(r(r)nexts zsplit..fiter.nextN)__name__ __module__ __qualname__rWr[r`__next__r(r(r(r)fiters reFs content-typesnextr1r9T:rr--- )objectr safehasattrr3r"r#lower) r5r8r;rMrQrSrer&r6 mimeheadersr%r(rPr)r#@s8         r#))sDatesdate)sBranchsbranch)sNode IDnodeidc cs\tjdd\}}t|d}zt||||VW|t|dS|t|w)aextract patch from data read from fileobj. patch can be a normal patch or contained in an email message. return a dictionary. Standard keys are: - filename, - message, - user, - date, - branch, - node, - p1, - p2. Any item can be missing from the dictionary. If filename is missing, fileobj did not contain a patch. Caller must unlink filename when done. hg-patch-prefixwbN)rmkstemposfdopen_extractcloseunlink)uifileobjfdtmpnametmpfpr(r(r)extracts  r|c CstdtjtjB}i}t|}|dot|d}|do&t|d|d<|s=|ds=ddd|Dd}g}|d} | rUt| |d <} | d | |r}| d ro| d } | d kro|| dd }t dd|}| d||dr| d|dd } d} d} |D]}t|}| d||| vrq|jdd}||}|rd}d}d}| d|d | d7} t}|d|d D]}| dr|s| dd}d}|d |d}ne|rV| dr|dd|d<| d|dnJ| dr%||dd n8| d rStD]$\}}d!|}| |rP|t|d||<| d"|||fq-n d}n|d#kr]d}|sm|sm|||dq|} |r|||ds|dq| s| r|d$kr| d|7} q|r| |sd%|| f} | |d&<||r| d |d'<|r| d |d(<| r||d)<|S)*Ns}^(?:Index:[ \t]|diff[ \t]-|RCS file: |retrieving revision [0-9]+(\.[0-9]+)*$|---[ \t].*?^\+\+\+[ \t]|\*\*\*[ \t].*?^---[ \t])SubjectFromsuser css"|] }dttj|VqdS)r N)r.mapr strtolocal.0hr(r(r) s z_extract..zX-Mercurial-Noderls Node ID: %s s[PATCH]rrs\n[ \t]+rs Subject: %s s From: %s rDr,sContent-Type: %s T)decodeFsfound patch at byte %d r1spatch generated by hg export s# User s # Parent # s# %s s%s: %s ---rEs%s %ssmessagesp1sp2sfilename)!recompile MULTILINEDOTALLrrF headdecoder.itemsdebugr"findlstripsubrHrbytestrrI get_payloadsearchstartr- splitlinesr?truncater3patchheadermapr$writegetvalueendswithrupop)rwrxrzr{diffredatamsgsubjectparentsnodeidpend diffs_seenrJmessagerK content_typepayloadr@hgpatch hgpatchheader ignoretextcfpr%headerkeyror(r(r)rts                        rtc@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS) patchmetaaPatched file metadata 'op' is the performed operation within ADD, DELETE, RENAME, MODIFY or COPY. 'path' is patched file path. 'oldpath' is set to the origin file when 'op' is either COPY or RENAME, None otherwise. If file mode is changed, 'mode' is a tuple (islink, isexec) where 'islink' is True if the file is a symlink and 'isexec' is True if the file is executable. Otherwise, 'mode' is None. cCs"||_d|_d|_d|_d|_dS)NsMODIFYF)patholdpathmodeopbinary)rVrr(r(r)rWes  zpatchmeta.__init__cCs|d@}|d@}||f|_dS)Ni @)r)rVrislinkisexecr(r(r)setmodelszpatchmeta.setmodecCs.t|j}|j|_|j|_|j|_|j|_|SrR)rrrrrr)rVotherr(r(r)copyqs zpatchmeta.copycCs&|dkr |jdkS|d|jp|jkS)N /dev/nullADDa/)rrr)rVafiler(r(r) _ispatchingays zpatchmeta._ispatchingacCs |dkr |jdkS|d|jkS)NrDELETEb/rr)rVbfiler(r(r) _ispatchingb~s zpatchmeta._ispatchingbcCs||o ||SrR)rr)rVrrr(r(r) ispatchingzpatchmeta.ispatchingcCsd|j|jfS)NzrrZr(r(r)__repr__szpatchmeta.__repr__N) rarbrc__doc__rWrrrrrrr(r(r(r)rZs  rcCsjd}g}|D]}|d}|dr*t|}|r)|r |||d}t|}q|r|dr9||d}q|drId|_|dd|_q|d rV|d d|_ q|d rfd |_|d d|_q|d rs|dd|_ q|dr|d|_q|drd|_| t |dddq|dr| t |dddq|drd|_ q|r|||S)z9extract git-style metadata about patches from N diff --git a/r!rgs rename from RENAME s rename to s copy from COPYscopy to s deleted filersnew file mode ris new mode GIT binary patchT) rstripr"gitrematchr3grouprrrrrintr)lrgp gitpatchesr%r@dstr(r(r) readgitpatchsP                rc@s,eZdZddZddZddZddZd S) linereadercC||_g|_dSrR)rAbufrUr(r(r)rW zlinereader.__init__cCs|dur |j|dSdSrR)rr3rVr%r(r(r)pushszlinereader.pushcCs&|jr|jd}|jd=|S|jSNr)rrAr]r_r(r(r)r]s   zlinereader.readlinecCs t|jdSr+)iterr]rZr(r(r)r[ zlinereader.__iter__N)rarbrcrWrr]r[r(r(r(r)rs  rc@sDeZdZddZddZddZddZd d Zd d Zd dZ dS)abstractbackendcCrTrR)rw)rVrwr(r(r)rWrXzabstractbackend.__init__cCt)zReturn target file data and flags as a (data, (islink, isexec)) tuple. Data is None if file is missing/deleted. NotImplementedErrorrVfnamer(r(r)getfileszabstractbackend.getfilecCr)a Write data to target file fname and set its mode. mode is a (islink, isexec) tuple. If data is None, the file content should be left unchanged. If the file is modified after being copied, copysource is set to the original file name. rrVrrr copysourcer(r(r)setfileszabstractbackend.setfilecCr)zUnlink target file.rrr(r(r)rvszabstractbackend.unlinkcCsdS)zWrite rejected lines for fname. total is the number of hunks which failed to apply and total the total number of hunks for this files. Nr()rVrfailedtotalr/r(r(r)writerejzabstractbackend.writerejcCrrRrrr(r(r)existsr\zabstractbackend.existscCrrRrrZr(r(r)rur\zabstractbackend.closeN) rarbrcrWrrrvrrrur(r(r(r)rs rcsDeZdZfddZddZddZddZd d Zd d ZZ S) fsbackendcs tt||t||_dSrR)superrrWvfsmodropener)rVrwbasedir __class__r(r)rWszfsbackend.__init__c Cs|j|r|j|dfSd}z |j|jd@dk}Wnty6}z |jtjkr,WYd}~nd}~wwz |j|d|ffWSt y\}z|jtjkrQWYd}~dSd}~ww)NTFFrrNN) rrreadlinklstatst_modeOSErrorerrnoENOENTreadIOError)rVrrer(r(r)rs&    zfsbackend.getfilecCsd|\}}|dur|j|||dS|r|j||dS|j|||r0|j|dddSdSrN)rsetflagssymlinkr)rVrrrrrrr(r(r)rszfsbackend.setfilecCs$|jdd}|jj|d|ddS)Ns experimentalsremoveemptydirsT) ignoremissingrmdir)rw configboolr unlinkpath)rVrr r(r(r)rvszfsbackend.unlinkcCsD|d}|jtd|||f||d}|||dS)Ns.rejs7%d out of %d hunks FAILED -- saving rejects to file %s w)rwwarnrr writelinesru)rVrrrr/rAr(r(r)rs   zfsbackend.writerejcCs |j|SrR)rlexistsrr(r(r)rrzfsbackend.exists) rarbrcrWrrrvrr __classcell__r(r(rr)rs   rcsDeZdZfddZddZfddZfddZd d ZZS) workingbackendcs:tt|||j||_||_t|_t|_g|_ dSrR) rrrWrootrepo similaritysetremovedchangedcopied)rVrwrrrr(r)rW$s  zworkingbackend.__init__cCs2|jj|js||rttd|dSdSNs$cannot patch %s: file is not tracked)rdirstate get_entry any_trackedrPatchApplicationErrorrrr(r(r) _checkknown,s zworkingbackend._checkknowncsH||tt||||||dur|j||f|j|dSrR)r rrrrr3raddrrr(r)r4s zworkingbackend.setfilecs6||tt|||j||j|dSrR)r rrrvrr!rrrr(r)rv;s  zworkingbackend.unlinkcCs|jd}t|j}|jD]\}}t|j|j|||q |jr9|t |j|jD] }||jj vr8| |q+|rDt |j||j t |jSrR)rrrrr dirstatecopyrwrforgetsortedrdiscard marktouchedr)rVwctxrsrcrfr(r(r)ruAs      zworkingbackend.close) rarbrcrWr rrvrurr(r(rr)r#s    rc@s0eZdZd ddZd ddZddZdd ZdS) filestoreNcCs8d|_i|_d|_||_|jdurd|_d|_i|_dS)Nri@)rfilescreatedmaxsizesizer)rVr-r(r(r)rWUs  zfilestore.__init__cCs|jdkst||j|jkr"|||f|j|<|jt|7_dS|jdur3tjdd}t||_d|j }|j |||j d7_ |||f|j |<dS)Nrrmrn%dr) r-r$r.rrrmkdtemprrr,rr+)rVrrrrrfnr(r(r)r_s    zfilestore.setfilecCsJ||jvr |j|S|jr||jvrdS|j|\}}}|j|||fS)N)NNN)rrr+r)rVrr1rrr(r(r)rms  zfilestore.getfilecCs|jr t|jjdSdSrR)rshutilrmtreebaserZr(r(r)ruuszfilestore.closerR)rarbrcrWrrrur(r(r(r)r*Ts    r*csLeZdZfddZddZddZddZd d Zd d Zd dZ Z S) repobackendcs<tt||||_||_||_t|_t|_i|_ dSrR) rr5rWrctxstorerrrr)rVrwrr6r7rr(r)rW{s zrepobackend.__init__cCs||jvr ttd|dSr)r6rrrr(r(r)r s  zrepobackend._checkknowncCsFz|j|}Wn tjyYdSw|}|d|vd|vffS)Nrlx)r6r LookupErrorflagsr)rVrfctxr;r(r(r)rszrepobackend.getfilecCsX|r|||dur|j|}|j|||||j||r*||j|<dSdSrR)r r6rr7rrr!rrr(r(r)rs  zrepobackend.setfilecCs|||j|dSrR)r rr!rr(r(r)rvs zrepobackend.unlinkcCs ||jvSrR)r6rr(r(r)rrXzrepobackend.existscCs |j|jBSrR)rrrZr(r(r)rurzrepobackend.close) rarbrcrWr rrrvrrurr(r(rr)r5zs   r5s*@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@s.(?:---|\*\*\*) (\d+)(?:,(\d+))? (?:---|\*\*\*))strictcrlflfautoc@sFeZdZdddZddZddZdd Zd d Zd d ZddZ dS) patchfiler=c Cs|j|_||_d|_||_||_g|_d|_d|_|j |_ |j |_ |j dv|_ |j dk|_|j dur;||j\}}n ||j dd\}}|dur|j dupU||j|_d|_|rbt||_|j durj||_ |jr|jddryd|_n |jddrd|_|d krg}|jD]} | dr| dd d} || q||_n|j rd|_|j durd |_ |jr|jtd |j|jtd i|_d|_d|_d|_g|_d|_|dd|_dS)NFT)rrrrr!rrrr=)FFs!unable to find '%s' for patching sB(use '--prefix' to apply patch relative to the current directory) )rreolmodeeolbackendrwr/rmissingrrrrcreateremoverr splitnewlinesrr3rrhashdirtyoffsetskewrej fileprinted printfilehunks) rVrwrrEr7rCrrnlinesr'r(r(r)rWsl           zpatchfile.__init__cCs|jdkr |j}n |jdkrd}nd}|jdkr;|r;|dkr;g}|D]}|r3|dr3|dd|}||q"|}|j|d|||jdS)Nr@r>rrr=r,)rCrDrr3rErr.r)rVrr/rrDrawlinesr'r(r(r)rs   zpatchfile.writelinescCsN|jrdS|s |jjrd|_td|j}|r|j|dS|j|dS)NTspatching file %s )rOrwverboserrrnote)rVrsr(r(r)rPs zpatchfile.printfilecs2|j|g}t|dkr|jfddd|S)Nrcs t|SrR)abs)xlinenumr(r)s z%patchfile.findlines..)r)rJgetr$sort)rVr'r[candr(rZr) findliness zpatchfile.findlinescCs|jsdStj|j}d||fg}|jD]}|jD]}|||dddkr2|dtjqq|j |jt |j|j |dS)Ns--- %s +++ %s rSr) rNrrrbasenamerhunkr3r MISSING_NEWLINE_MARKERrErr$rQ)rVr4r/rYr'r(r(r) write_rejs    zpatchfile.write_rejc Csz|sttd|j|jt|j|jt|j|j f|j d7_ |j r.|j |dS|jrV|jrV|jrC|jtd|jn |jtd|j|j |dSt|tr|jrg|j|jdS||j}||jdd<|jt|7_d|_dS|}|jdvs|jd kr|jr|}| dd \}}}}||j7}|}|j!dkrt"#||j|r|jr|j|jdS||j||t|<|jt|t|7_d|_dSi|_$t%|jD]\} } |j$&| g | qt'(|j)d d dD]} d D]} | | | \}}}}||j|j!}t*|t|j}|r/|+|ddd|} n|g} | D]k}|rBt"#||j|r||j||t|<|jt|t|7_|||_!d|_||| }| rtd}|,d|j||j|d| |fntd}|j-||j|d|f| Sq4qq|,d|jtd|j|f|j |dS)Nsbad hunk #%d %s (%d %d %d %d)rrSs-cannot create %s: destination already exists sfile %s already exists Tr)r>r?r@Fpatchsfuzzrs9Hunk #%d succeeded at %d with fuzz %d (offset %d lines). s,Hunk #%d succeeded at %d (offset %d lines). sHunk #%d FAILED at %d ).completePatchParseErrorrnumberdescr$alenablenbrQrFrNr3rrGrrwrr isinstancebinhunkrHrErvnewr/rLrKrCrD getnormalizedfuzzitrMr testhunkrJ enumerate setdefaultrxrange configintminr`rPrV)rVrr'horigoldoldstartrpnewstart orig_startrYrWfuzzlentoponlyr_rLrr(r(r)apply"s"            # zpatchfile.applycCs,|jr ||j|j|j|t|jSrR)rKrrr/rrdr$rNrZr(r(r)rus zpatchfile.closeN)r=) rarbrcrWrrPr`rdrrur(r(r(r)rAs <   mrAc@seZdZdZedZedZedZedZ edZ edZ dd Z d d Z d d ZddZddZddZddZddZddZddZdS)rz patch headersdiff --git a/(.*) b/(.*)$sdiff -r .* (.*)$s(?:index|deleted file) s(?:new file|deleted file) s'(?:index|deleted|copy|rename|new mode) s(?:new file|copy to|rename to)cCrrR)rrQ)rVrr(r(r)rWrzheader.__init__cCstdd|jDS)Ncss|]}|dVqdS)index Nr"rr(r(r)rz header.binary..anyrrZr(r(r)rrz header.binarycCs|jD]M}|dr|tddS|j|r-|||r*|tddS|drK|tdt|jt dd|jDfdS||qdS)Nrs-this modifies a binary file (all or nothing) sthis is a binary file rs%d hunks, %d lines changed cSsg|] }t|j|jqSr()maxaddedrrr(r(r) z!header.pretty..) rr"rr pretty_rerrr$rQsum)rVrArr(r(r)prettys(      z header.prettycCs|d|jdSr+)rr.rrUr(r(r)rsz header.writectfddjDS)Nc3|] }j|VqdSrR) allhunks_rerrrZr(r)rz"header.allhunks..rrZr(rZr)allhunkszheader.allhunkscCsN|j|jd}|r|\}}||kr|gS||gS|j|jdSr) diffgit_rerrgroupsdiff_re)rVrfromfiletofiler(r(r)r+s z header.filescCs |dS)NrS)r+rZr(r(r)filenamerzheader.filenamecCsddttj|S)Nz
 )r.rrapplyfsdecoder+rZr(r(r)rszheader.__repr__cr)Nc3rrR) newfile_rerrrZr(r)rrz#header.isnewfile..rrZr(rZr) isnewfilerzheader.isnewfilecs6tjdk}o |}|ptfddjDS)Nr!c3rrR) special_rerrrZr(r)rs  z!header.special..)r$rrr)rV nocontent emptynewfiler(rZr)specials  zheader.specialN)rarbrcrrrrrrrrrrWrrrrr+rrrrr(r(r(r)rs$        rc@s^eZdZdZ dddZddZddZd d Zd d Zd dZ e Z ddZ e j ddZdS) recordhunkzKpatch hunk XXX shouldn't we merge this with the other hunk class? Nc sldfdd } ||_| |d\} |_|| |_|| |_| |d\} |_||_||_||j\|_|_ dS)NFcsHdur t|}|dkr |r|||dfS||dfSd|fSrr$)r/reversedelta maxcontextr(r) trimcontexts z(recordhunk.__init__..trimcontextT)F) rbeforefromlinetolineafterprocrb countchangesrr) rVrrrrrrbrrr trimedbefore _trimedafterr(rr)rWs    zrecordhunk.__init__cCsFt|tsdS|j|jko"|j|jko"|j|jko"|j|jkS)NF)rnrrbrrrr+)rVvr(r(r)__eq__ s    zrecordhunk.__eq__cCs$tt|jt|j|j|jfSrR)rJtuplerbrr+rrrZr(r(r)__hash__s zrecordhunk.__hash__cCs,tdd|D}tdd|D}||fS)zhunk -> (n+,n-)cSg|] }|dr|qS)rrrr(r(r)r!rz+recordhunk.countchanges..cSr)rrrr(r(r)r"rr)rVrbr!remr(r(r)rszrecordhunk.countchangescs@ddddfdd|jD}t|j|j|j|j|j||jS)zreturn another recordhunk which is the reverse of the hunk If this hunk is diff(A, B), the returned hunk is diff(B, A). To do that, swap fromline/toline and +/- signs while keep other things unchanged. rr\)rrrcs,g|]}d|dd|ddfqS)s%s%srrNr()rr'r@r(r)r-s,z*recordhunk.reversehunk..)rbrrrrrrrrVrbr(rr) reversehunk%s zrecordhunk.reversehunkc Cst|jt|j}|jr|jdtjkr|d8}||j}||j}|d|j||j ||j o3d|j f|d |j|j |jdS)NrSrs@@ -%d,%d +%d,%d @@%s rr,) r$rrr rcrrrrrrr.rb)rVrArfromlentolenr(r(r)r8s   " zrecordhunk.writecCs |jSrR)rrrZr(r(r)rLrXzrecordhunk.filenamecCsd||jfS)Ns )rrrZr(r(r)rOszrecordhunk.__repr__rR)rarbrcrrWrrrrrrrr strmethodrr(r(r(r)rs   rcCsZtdtdtdtddtdtdtdtd dtd td td td ddS)Nsapply change %d/%d to '%s'?sdiscard change %d/%d to '%s'?skeep change %d/%d to '%s'?srecord change %d/%d to '%s'?)sapplysdiscardskeeprecordsapply this change to '%s'?sdiscard this change to '%s'?skeep this change to '%s'?srecord this change to '%s'?s0[Ynesfdaq?]$$ &Yes, apply this change$$ &No, skip this change$$ &Edit this change manually$$ &Skip remaining changes to this file$$ Apply remaining changes to this &file$$ &Done, skip remaining changes and files$$ Apply &all changes to all remaining files$$ &Quit, applying no changes$$ &? (display help)s8[Ynesfdaq?]$$ &Yes, discard this change$$ &No, skip this change$$ &Edit this change manually$$ &Skip remaining changes to this file$$ Discard remaining changes to this &file$$ &Done, skip remaining changes and files$$ Discard &all changes to all remaining files$$ &Quit, discarding no changes$$ &? (display help)s-[Ynesfdaq?]$$ &Yes, keep this change$$ &No, skip this change$$ &Edit this change manually$$ &Skip remaining changes to this file$$ Keep remaining changes to this &file$$ &Done, skip remaining changes and files$$ Keep &all changes to all remaining files$$ &Quit, keeping all changes$$ &? (display help)s4[Ynesfdaq?]$$ &Yes, record this change$$ &No, skip this change$$ &Edit this change manually$$ &Skip remaining changes to this file$$ Record remaining changes to this &file$$ &Done, skip remaining changes and files$$ Record &all changes to all remaining files$$ &Quit, recording no changes$$ &? (display help))multiplesinglehelprr(r(r(r) getmessagesTs0   rcsltdur dfdd}t}i}d\}}dtdd|D} } |D]} | t| j7} d}d } d | j} | |vr@q(|| |durN| | }t d t d d d|D}t fdd|Drsd\}}}n ||||d\}}}}|sq(| g|| <| r|| | j7<q(t| jD]\}}|dur|dur|| dkrd| }n| t| j|}d|| | f}|||||\}}}}|r| rt|}|j| 7_|| |q|dur|D]}|jD]}| r|j| 7_|| |qqq| |j|j7} qq(tddt|DgifS)z:Interactively filter patch chunks into applied-only chunksNrc sd}|dur ||||fS|dur||||fS d}d||f}d|dkrH|dD]\}}d|t|fq6q|d krPd} n|dkrWd } n|d kr|durmtd dq|jrtd dqdtd} tj ddd\} } d} zt t | d}|j||||ddd| D|}jd|| fdidd} | d krtd| Wt | ~ qt| d}t} t |D]}t |}|ds| |q|| d t| }Wt | ~ nt | ~ wd } n4|dkr)d } }n*|dkr3d} }n |d kr=d } }n|d!krGd} }n |d"krSttd#| |||fS)$zprompt query, and process base inputs - y/n for the rest of file - y/n for the rest - ? (help) - q (quit) Return True/False and possibly updated skipfile and skipall. NTrs%s (enter ? for help) %srrrs%s - %s rFr!s cannot edit patch for whole files!cannot edit patch for binary filers To remove '-' lines, make them ' ' lines (context). To remove '+' lines, delete them. Lines starting with # will be removed from the patch. If the patch applies cleanly, the edited hunk will immediately be added to the record list. If it does not apply cleanly, a rejects file will be generated: you can use that when you try again. If all lines of the hunk are removed, then the edit is aborted and the hunk is left unchanged. s hg-editor-s.diff)rosuffixrpr,cSsg|]}d|dqS)rrr()rir(r(r)rz/filterpatch..prompt..s%s "%s"sHGUSERs filterpatch)environ blockedtags editor exited with exit code %d rb#rs user quit) promptchoicerextractchoicesrrjrrrrrqrnativeeolwriterrrrsr.rru geteditorsystemusernamerrvr r-iterfile fromnativeeolr"r? parsepatchr CanceledError)skipfileskipallqueryr0 newpatchesrespsrr:tretphelppatchfdpatchfn ncpatchfpr)editorpatchfpr%)messages operationrwr(r)prompts                                  zfilterpatch..promptrrcss|]}t|jVqdSrR)r$rQrr(r(r)r rzfilterpatch..rr,sexamine changes to %s?s and css|]}d|VqdS)s'%s'Nr(rr)r(r(r)rs c3s|]}|VqdSrR)exactrrr(r)rr)TNNrrcSs(g|]}|dst|dkr|qS)rr)rr$rr(r(r)rBs  zfilterpatch..)rrrr$rQr.rr!rr+rallrrrtrrr3rrr itervalues)rwheadersrrrseenappliedrrposrr fixoffsethdrr+rrnprr0idxrnewpatchnewhunkr()rrrrwr) filterpatchsj           rc@sLeZdZddZddZddZddZd d Zd d Zd dZ ddZ dS)rbcCsd||_||_|g|_g|_g|_d|_|_d|_|_|dur0|r)| |dS| |dSdSrR) rhrirbrjrlstartarkstartbrmread_context_hunkread_unified_hunk)rVrinumrcontextr(r(r)rWNs  z hunk.__init__cCsndd}t|j|jdd}|j|_|j|_|j|_||j|_||j|_|j|_|j|_|j|_|j|_|S)z1Return a copy with line endings normalized to LF.cSs6g}|D]}|dr|ddd}||q|S)NrrBr)rr3)r/rRr%r(r(r) normalize_s   z%hunk.getnormalized..normalizeN) rbrirhrjrlrrrkrm)rVrnhr(r(r)rq\s   zhunk.getnormalizedc CsHt|j}|sttd|j|\|_|_|_ |_ |jdur&d|_nt |j|_|j dur5d|_ nt |j |_ t |j|_t |j |_ zt ||j|j|j |j|jWntjyp}z ttd|j|fd}~wwt|jddkr|jd=|jd=|jd=|jd8_|j d8_ t|jddksz||dS)N bad hunk #%drsbad hunk #%d: %srSr)unidescrrirgrrhrrrkrrmrr addlinesrbrjrlr ParseErrorr$ _fixnewline)rVrr@rr(r(r)rts8       zhunk.read_unified_hunkc Cs||_t|j}|sttd|j|\|_}t |j|_|dur*|j}t ||j|_ |jr<|j d7_ t |j D]H}|}| drT||n7|dd}| dsd| drid|}n| drsd |}n ttd |j|f|j||j|qB|}| d r|jd dd }||jd <||jd <|}t|}|sttd|j|\|_}t |j|_|dur|j}t ||j|_|jr|jd7_d} t |jD]}|}| d r |jd dd }||jd <||j| d<q|s||np|dd}| d s'| dr,d|}n%| dr7d |}nt|jdkrF||n?ttd |j|f|j| | t|jkrcd} n|j| } | d7} | |krrn| drzqW|j| d| q|js|jD]}| ds| d r|j|q|js|jD]}| ds| d r|j|ddqd|j|j |j|jf|_|j|jd<||dS)Nrrrr!s- s! rs rsbad hunk #%d old text line %d\ rSs+ rrTr,s@@ -%d,%d +%d,%d @@ )r]ri contextdescrrgrrhrrrrkrrvr"rrjr3rbrrmrlr$insertr) rVrr@aendrYr'rWubendhunkirr(r(r)rs                               zhunk.read_context_hunkcCs8|}|drt|j|j|jdS||dS)Nr)r]r"r fixnewlinerbrjrlr)rVrr'r(r(r)rs zhunk._fixnewlinecCs t|j|jkot|j|jkSrR)r$rjrkrlrmrZr(r(r)rfs z hunk.completec Cst|t|}|rgd}d}t|j}t|dD]}|j|ddr*|d7}q|sHt|dD]}|j||ddrG|d7}q4t||}t||}||t||||t|||fS||dfS)Nrrr)rxr$rbrrvr") rVrzrpfuzzrtopbothlenrYr(r(r)_fuzzit s$     * z hunk._fuzzitcCsf||j|j||\}}}|j|}|j|}|jr"|dkr"|d8}|jr-|dkr-|d8}||||fS)Nrr)rrjrlrrrkrm)rVrrrzrprr{r|r(r(r)rr%s   z hunk.fuzzitN) rarbrcrWrqrrrrfrrrr(r(r(r)rbMsm rbc@s0eZdZdZddZddZddZdd Zd S) rozA binary patch file.cCs(d|_d|_dg|_||_||dS)NFsGIT binary patch )textrrb_fname_read)rVrrr(r(r)rW4s zbinhunk.__init__cCs |jduSrR)rrZr(r(r)rf;rXzbinhunk.completecCs"|jr t|jd|gS|jgSr+)r applybindeltarr.)rVr/r(r(r)rp>sz binhunk.newc Csdd} |||j}|sttd|j|dr&t|dd}n|dr9t|dd}d|_nqg}|||j}t|d kr|d d }|d kra|d krat |t d d }n t |t d d}z| t |d dd|Wnt y}zttd|jt|fd}~ww|||j}t|d ksHtd|}t||krttd|jt||f||_dS)NcSs|}|||dS)Nr)r]r3r)rrbr'r(r(r)getlineDs  zbinhunk._read..getlineTs"could not extract "%s" binary datasliteral rsdelta rrrZAas&could not decode "%s" binary patch: %sr,s%"%s" length is %d bytes, should be %d)rbrgrrr"rrrr$ordr3r b85decode ValueErrorr forcebytestrzlib decompressr.r) rVrrr%r.decr'rrr(r(r)rCsT       $    z binhunk._readN)rarbrcrrWrfrprr(r(r(r)ro1s  rocCsF|ddd}|d}|dkr|d}|dkr|S|d|S)Nrrrrr)rr)strrWrr(r(r) parsefilenameos   r$cCs0g}|D]}t|dr|}||q|S)areverse the signs in the hunks given as argument This function operates on hunks coming out of patch.filterpatch, that is a list of the form: [header1, hunk1, hunk2, header2...]. Example usage: >>> rawpatch = b"""diff --git a/folder1/g b/folder1/g ... --- a/folder1/g ... +++ b/folder1/g ... @@ -1,7 +1,7 @@ ... +firstline ... c ... 1 ... 2 ... + 3 ... -4 ... 5 ... d ... +lastline""" >>> hunks = parsepatch([rawpatch]) >>> hunkscomingfromfilterpatch = [] >>> for h in hunks: ... hunkscomingfromfilterpatch.append(h) ... hunkscomingfromfilterpatch.extend(h.hunks) >>> reversedhunks = reversehunks(hunkscomingfromfilterpatch) >>> from . import util >>> fp = util.stringio() >>> for c in reversedhunks: ... c.write(fp) >>> fp.seek(0) or None >>> reversedpatch = fp.read() >>> print(pycompat.sysstr(reversedpatch)) diff --git a/folder1/g b/folder1/g --- a/folder1/g +++ b/folder1/g @@ -1,4 +1,3 @@ -firstline c 1 2 @@ -2,6 +1,6 @@ c 1 2 - 3 +4 5 d @@ -6,3 +5,2 @@ 5 d -lastline s reversehunk)rrirr3)rQnewhunksr:r(r(r) reversehunkszs 8  r&c sGfdddt}|}t}|d||dd}t|D]"\}}z |j||||WntyBtd||fw|}q#~| S)aDpatch -> [] of headers -> [] of hunks If maxcontext is not None, trim context lines if necessary. >>> rawpatch = b'''diff --git a/folder1/g b/folder1/g ... --- a/folder1/g ... +++ b/folder1/g ... @@ -1,8 +1,10 @@ ... 1 ... 2 ... -3 ... 4 ... 5 ... 6 ... +6.1 ... +6.2 ... 7 ... 8 ... +9''' >>> out = util.stringio() >>> headers = parsepatch([rawpatch], maxcontext=1) >>> for header in headers: ... header.write(out) ... for hunk in header.hunks: ... hunk.write(out) >>> print(pycompat.sysstr(out.getvalue())) diff --git a/folder1/g b/folder1/g --- a/folder1/g +++ b/folder1/g @@ -2,3 +2,2 @@ 2 -3 4 @@ -6,2 +5,4 @@ 6 +6.1 +6.2 7 @@ -8,1 +9,2 @@ 8 +9 cseZdZdZddZddZfddZdd Zd d Zd d Z ddZ eeeedeeee deeedeedde idZ dS)zparsepatch..parserzpatch parsing state machinecSs4d|_d|_d|_d|_g|_g|_g|_g|_dS)Nrr,)rrrrrrrbrrZr(r(r)rWs z#parsepatch..parser.__init__cSs6|g|\}}}}}t||_t||_||_dSrR) addcontextrrrr)rVlimits fromstartfromendtostarttoendrr(r(r)addranges    z#parsepatch..parser.addrangec s|jr;t|j|j|j|j|j|j|}|jj||jt |j|j 7_|jt |j|j 7_g|_g|_||_ dSrR) rbrrrrrrrQr3r$rrr)rVrrrr(r)r's"  z%parsepatch..parser.addcontextcSs.|jr |j|_g|_|jr|g||_dSrR)rrrbr'rr(r(r)addhunk s   z"parsepatch..parser.addhunkcSs(|gt|}|j|||_dSrR)r'rrr3)rVrrr(r(r)newfiles   z"parsepatch..parser.newfilecSsdSrRr(rr(r(r)addotherr\z#parsepatch..parser.addothercSs|g|jSrR)r'rrZr(r(r)finisheds z#parsepatch..parser.finished)contextfilehunkrange)r3r4r5other)r2r3r5)r2r4r6)r3r2r4r5r6N) rarbrcrrWr-r'r.r/r0r1 transitionsr(rr(r)parsers4  r8r,rr2sunhandled transition: %s -> %s) rhr-rr.r? scanpatchr7KeyErrorrgr1)originalchunksrr8prAstatenewstaterr(rr)rs",R   rcCst|}d}|dkrd||fS|}|dkr]|d|}|dkr-ttd|||f|d7}||dkrU|||ddkrU|d7}||dkrU|||ddksA|d8}|dks|d||||dfS)aturn a path from a patch into a path suitable for the repository prefix, if not empty, is expected to be normalized with a / at the end. Returns (stripped components, path in repository). >>> pathtransform(b'a/b/c', 0, b'') ('', 'a/b/c') >>> pathtransform(b' a/b/c ', 0, b'') ('', ' a/b/c') >>> pathtransform(b' a/b/c ', 2, b'') ('a/b/', 'c') >>> pathtransform(b'a/b/c', 0, b'd/e/') ('', 'd/e/a/b/c') >>> pathtransform(b' a//b/c ', 2, b'd/e/') ('a//b/', 'd/e/c') >>> pathtransform(b'a/b/c', 3, b'') Traceback (most recent call last): PatchApplicationError: unable to strip away 1 of 3 dirs from a/b/c rr,/rSs*unable to strip away %d of %d dirs from %srN)r$rrrrr)rr2ropathlenrcountr(r(r) pathtransformJs(   $ rBcCs|dk}|dk}|o|jdko|jdk}|o|jdko|jdk} t|||\} } | o/|| } t|||\} }| |kr?| }n| oF||}| oO| oO| }| d| dd}|d|dd}|r||kr| |r|jdkr|jdkrd}d}| | ko|| }d}|s| r|r|r| }n|}n| r| }|s|s|r| }n|}n |s| }ntt dt |}|rd|_ |S| rd |_ |S) Nrrr?rTFs&undefined source and destination filesrr) rrkrrmrBrrfindr"rgrrr)rE afile_orig bfile_origrbr2ronullanullbrGrHabasergoodabbasergoodbrFabasedirbbasedirisbackuprrr(r(r) makepatchmetass\   rOc #std}t|fdd}tjdD]p}|ds"|drJdd}|||}}|d r?}|||g7}n|d |fVq|d r^d d ||fddfVq|drrdd||fddfVq||}|rd|fVqd|fVqdS)zlike patch.iterhunks, but yield different events - ('file', [header_lines + fromfile + tofile]) - ('context', [context_lines]) - ('hunk', [hunk_lines]) - ('range', (-start,len, +start,len, proc)) s'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)cs>|g}tjdD]}||r||q ||S|S)zscan lr while predicate holdsr,)rr]r3r)firstr<r/r%)rr(r) scanwhiles  zscanpatch..scanwhiler,rsdiff -r cSs|dd}| p|ddvS)Nrr)rdiff)r#)r%rWr(r(r) notheaders zscanpatch..notheaderrr3r)rrr2c |SrRrr'csr(r)r\ zscanpatch..)rr)rrrr4crTrRrrUrVr(r)r\rXr5r6N) rrrrr]r"rrr) rAlines_rerQr%rSrrrr@r()rWrr)r9s2           r9cCsbd}z |j}|j}Wntyt|j}Ynwt|}||t|}|||S)a Git patches can emit: - rename a to b - change b - copy a to c - change c We cannot apply this sequence as-is, the renamed 'a' could not be found for it would have been renamed already. And we cannot copy from 'b' instead because 'b' would have been changed already. So we scan the git patch for copy and rename commands so we can perform the copies ahead of time. r) rAtellrr-rrrrr?)r firstlinerrAgitlrrr(r(r) scangitpatchs     r]ccsd}d}d}d}d}}d}d}d} t|} t| jdD]<} ||kr| s+| ds9| dur4| ds9| drd} |rI|d ||rI|} | drUt| | j} n| dur`| dr`d } t| |d| | } |d7}|rd}d ||| | r{| p|dffVd | fVn| d rt | d}|sq|durt | | }ddd|DfV|d|d}d|d}|r|d ||s|} d d| jd| jd| ffV|r|d ||r|sttd|ddd }nZ| dr| }|ds | |qd }d} t| }t|}n7| drO| }|ds.| |q| }| ||dsC| |qd }d } t| }t|}|rZd}d }|}d}q|rx|} d d| jd| jd| ffV|s^dSdS)aDRead a patch and yield the following events: - ("file", afile, bfile, firsthunk): select a new target file. - ("hunk", hunk): a new hunk is ready to be applied, follows a "file" event. - ("git", gitchanges): current diff is in git format, gitchanges maps filenames to gitpatch records. Unique event. r,NrFr@s***************rrSTr3r4rrgitcSsg|] }|jdvr|qS))rr)rr)rrBr(r(r)r-sziterhunks..rrr!s'failed to synchronize metadata for "%s"r+++s***)rrr]r"rrrorrbrrrrr]rrrgrrr$)rArrr=hunknumemitfiler/rBFILErrrYrrr@l2l3r(r(r) iterhunkss               "rfc Csdd}d}||}||d}||}||d}d}|t|krt|||d}|d7}|d@rd}d}|d@rJt|||d}|d7}|d@r`|t|||dd >O}|d7}|d @rv|t|||dd >O}|d7}|d @r|t|||dd >O}|d7}|d @rt|||d}|d7}|d @r|t|||dd >O}|d7}|d@r|t|||dd >O}|d7}|dkrd}||} |||| 7}n|dkr||} |||| 7}||7}nttd|t|ks"|S)z_Apply a binary delta hunk The algorithm used is the algorithm from git's patch-delta.c cSs4d}t|D]}|d7}t|d@s|Sq|S)Nrr)rrr)binchunkrr:r(r(r) deltaheadjs z applybindelta..deltaheadr,Nrrrgr!rr risunexpected delta opcode 0)r$rrr) rhrrioutrWrcmdrLr. offset_endr(r(r)resZ      %rr,r=c Cst||t|||||dS)aNReads a patch from fp and tries to apply it. Returns 0 for a clean patch, -1 if any rejects were found and 1 if there was any fuzz. If 'eolmode' is 'strict', the patch content and patched file are read in binary mode. Otherwise, line endings are ignored when patching then normalized according to 'eolmode'. r2rorC) _applydiffrA)rwrArEr7r2rorCr(r(r) applydiffs rrcCs,|rt|j||}|dkr|d7}|S)Nr,r?)r canonpathrgetcwd)rror(r(r) _canonprefixs ruc sht|jfdd}d} d} d} t|D] \} } | dkr/| s#q| | }|dkr.d} q| dkr| r=| | 7} d} | \}}}}|rU||j|_|jrT||j|_n t||||}|jdkri| |j|s|jdkrw| |jqd \}}|jd vr| |jdd \}}|durt t d |j|j r|j }|jd krd}|s|r|jdvr||jrt t d|j||j|||jqz ||||||d} Wqty}z|t|dd} | d7} WYd}~qd}~ww| dkr| D]}||j}| |\}}|durq||||qqtt d| | r-| | 7} | r2dS| S)Ncst|ddS)Nr)rB)r<ror2r(r)pstriprz_applydiff..pstriprr4rr3rrr)rrr!ssource file '%s' does not existrr,)rrrs,cannot create %s: destination already exists)rCrr_unsupported parser state: %srS)rurrfrrurrrOrrvrrrrrr PatchErrorrrrrAbort)rwrApatcherrEr7r2rorCrwrejectserr current_filer=valuesrrr first_hunkrrrinstrr(rvr)rqs                    rqc Csd}g}|j} | r|dt| d|d||t|f} |d| t| d} ztt| D]c} | } | | d| drSt | } d}| | q4| d d krod }|sg|| dd }|| dq4| d d kr~|| dq4| d d kr|s|| dd }|| dq4W|rt|||n |rt|||ww| }|rttdt||S)ztuse to apply to the working directory. returns whether patch was applied with fuzz factor.Fs-d %ss%s %s -p%d < %srsUsing external patch tool: %s rbrspatching file s with fuzzrTssaving rejects to filesFAILEDspatch command failed: %s)rr3r shellquoter.rpopenrrrrVr"parsepatchoutputr!rrrr&rurr explainexit)rwrr{ patchnamer2r+rrargscwdrnrAr%pf printed_filecoder(r(r)_externalpatch s`    rc Cs|durt}|dur|dd}|tvr ttd||}t}zt|d}Wn t y9|}Ynwz t |||||||d} W||krO| | | | n||krc| | | | w| dkryt td| dkS)Nreseols!unsupported line endings type: %srrprspatch failed to apply)rconfigrjeolmodesrrzrr*r TypeErrorrrruupdater) rwrEpatchobjr2ror+rCr7rArr(r(r) patchbackendN s8      rc Cs t|||}t|||||||S)zwuse builtin patch to apply to the working directory. returns whether patch was applied with fuzz factor.)rr) rwrrr2ror+rCrrEr(r(r) internalpatchl s rc Cs"t||||} t|| |||||SrR)r5r) rwrr6r7rr2ror+rCrEr(r(r) patchrepo| src CsH|dd}|dur t}|rt|||||||St||||||||S)aApply to the working directory. 'eolmode' specifies how end of lines should be handled. It can be: - 'strict': inputs are read in binary mode, EOLs are preserved - 'crlf': EOLs are ignored when patching and reset to CRLF - 'lf': EOLs are ignored when patching and reset to LF - None: get it from user settings, default to 'strict' 'eolmode' is ignored when using an external patcher program. Returns whether patch was applied with fuzz factor. suireN)rrrr) rwrrr2ror+rCrr{r(r(r)patch s rc Cst||j}t||}t|df}t}t|D]T\}} |dkr_| \} } } } | rDt| j|d|d| _| jrCt| j|d|d| _n t || | | ||} | | j| j dkr^| | jq|dvrlt td|q|WdS1sywYdS)Nrr3rr)r4r_rx)rrrur rrfrBrrrOr!rrrzr)rwr patchpathr2rorErArr=rrrrrr(r(r) changedfiles s8         $rc@s eZdZdS)GitDiffRequiredN)rarbrcr(r(r(r)r src  cs|s |s |j}||} ||} t|| | ||||||| d D]8\} }}}| dur7|dus2Jd| ||}ddd|D}|rS|sKt|dkrSd|dV|rX|Vq dS) ayields diff of changes to files between two nodes, or node and working directory. if node1 is None, use first dirstate parent instead. if node2 is None, compare node1 with working directory. losedatafn(**kwarg) is a callable run when opts.upgrade=True and every time some change cannot be represented with the current patch format. Return False to upgrade to git patch format, True to accept the loss or raise an exception to abort the diff. It is called with the name of current file being diffed as 'fn'. If set to None, patches will always be upgraded to git format when necessary. prefix is a filename prefix that is prepended to all filenames on display (used for subrepos). relroot, if not empty, must be normalized with a trailing /. Any match patterns that fall outside it will be ignored. copy, if not empty, should contain mappings {dst@y: src@x} of copy information. if copysourcematch is not None, then copy sources will be filtered by this matcher hunksfilterfn, if not None, should be a function taking a filectx and hunks generator that may yield filtered hunks. ) ctx1ctx2rchangesopts losedatafnpathfnrcopysourcematchNs-fctx2 unexpectly None in diff hunks filteringr,css|] \}}d|VqdS)r,Nr.)rhrangehlinesr(r(r)r szdiff..rr)rp1 diffhunksr.r$)rnode1node2rrrrrrr hunksfilterfnrrfctx1fctx2rrQrr(r(r)diff s:*   rc  s<|durtj}dd} | |sj|d}t|tr&|dd\ n |j|j|j s9s9 s9gS jj r@t nt fdd  fD durei|j s]|jretj|drsfdd tDt} t} t } D]}|vr| || |q D] }|vr| |qt| t| t|  tD] \}}|vr|=qt t| | B| B}|f|fg}t | f d d }|jr|j szfd d }t||jdd|WSty||jdddYSw||dS)zYield diff of changes to files in the form of (`header`, `hunks`) tuples where `header` is a list of diff headers and `hunks` is an iterable of (`hunkrange`, `hunklines`) tuples. See diff() for the meaning of parameters. Ncsitfdd}|S)NcsX|j||d}|vr tdkr=||<n|||S)N)filelog)filectxr]r$popleftrrHr3)r)r6r<cacheorderr(r) getfilectx, s    z4diffhunks..lrugetfilectx..getfilectx) collectionsdeque)rr(rr) lrugetfilectx( s z diffhunks..lrugetfilectxrrcsg|]}|r|qSr(r()rnode)hexfuncr(r)rM rzdiffhunks..csi|] \}}|r||qSr(r()rrr()rr(r) W s zdiffhunks..c st || SrR)trydiff)rlosedata) rrrrrmodifiedrrrrevsr(r)difffn} szdiffhunks..difffncsr|ds tdS)Nr1)rr)rr(r)r szdiffhunks..losedataF)gitT)r defaultoptsstatusrnlistrrrrw debugflagrr rrupgrader pathcopiesr iteritemsrrHr!r$rr matchfilesrev prefetchfilesrr)rrrrrrrrrrr modifiedsetaddedset removedsetr)rr( prefetchmatch revmatchesrrr() rrrrrrrrrrrrrr)r sz            rccs|D]X}|d}|}|drd}n|drd}ntd|t|D]}|dr7|dfVq*||fVq*||krL|t|d d fV||kr[|t|d d fVqd S) z1yield tokens for a list of lines in a single hunkrr diff.deletedr diff.insertedunexpected hunk line: %srdiff.tabNdiff.trailingwhitespacer,)rr"rProgrammingError tabsplitterfindallr$) hunklinesr% chompline striplinelabeltokenr(r(r)diffsinglehunk s&      rccstt}t}|D]*}|dddkr||dd7}q |dddkr-||dd7}q td||r8|sDt|D]}|Vq.cSrrr(rr(r(r)r rr,)lines1lines2!rrTFrrS rrs.changeds .unchangedr) bytearrayrrr wordsplitterrbytesr.r allblocksrIr3rr$rr)rrjrlr%ralblalnblnanbnatokensbtokensblocksa1a2b1b2btyperrrortokens nextisnewline isendoflinechomp endofline endspacesmaybetab currentlabelr(r(r)diffsinglehunkinline sx            rc/s|dr|djrtntgd}dg}d}gfdd}||i|D]}|d}t|} t|D]{\} } |rF| drEd}n | rO| d sOd }d} |s\| r\| d r\d } |} |rb|} | rv| }| d | krp|d7}|q8|D]}|Vqy| }| D]\}}||r||fV| |kr| t|d dfVnq| dfV| d | krdVq8|D]}|Vqq)d S)z@yields 2-tuples of (output, label) based on the output of func()r) )rRs diff.diffline)copy diff.extended)renamer)soldr)snewr)sdeletedr)sindexr)s similarityr)rs diff.file_a)r`s diff.file_b)r^s diff.hunkFc3s.rD]}|Vqgdd<dSdSrRr()r dodiffhunk hunkbufferr(r)consumehunkbuffer s  z$difflabel..consumehunkbufferrr^)rrrr^rT)rrrNrr,rr,) r]worddiffrrr#r$rtr"r3r)funcrkw headprefixes textprefixesheadrr0r/ linecountrr%difflineprefixes bufferedlinerrrorr(rr) difflabel sj           rcOsttg|Ri|S)zBlike diff(), but yields 2-tuples of (output, label) for ui.write())rr)rr r(r(r)diffuiM src cst}dd|D}t|t|}}t|||D]O} d} | | } } | |vrKd} | |vrJ|jrJ|| } | |vrH| |vrHd} || nd} n| |vrgd} |jrg| |vrg|| |vrg||| | krgq| | | fVqdS)agenerates tuples (f1, f2, copyop), where f1 is the name of the file before and f2 is the the name after. For added files, f1 will be None, and for removed files, f2 will be None. copyop may be set to None, 'copy' or 'rename' (the latter two only if opts.git is set).cSsi|]\}}||qSr(r()rkrr(r(r)rY sz_filepairs..Nrr)rrr$rr!) rrrrrgonecopytorrr)copyopf1f2r(r(r) _filepairsR s4   rcCs4|sd}t|}td|}||t|S)Nr,sblob %d)r$rsha1rrdigest)rr'rWr(r(r) _gitindexw s   rs120000s100755s100644)r8r9r,c $cs| jr d} } nd} d} dd}dd}t|}t|}| s)dd } t||||| D]R\}}}d }d }d }d }d }d }|rT|||}| jsO| rT||}|re|||}| js`| re||}| jrkd }n td d ||fD}| r| js|s||vs|s||s||r|r|s|s|r|r||kr| |p|| |p|}| |p|}g}| jr| d| || |f|s| dt |na|s| dt |nUt |t |}} || kr| d|| d| |d ur| j r t ||||d}!| d|!| d||f| d||fn |r)| ||||rY| jr<| jrY| jrY| jsY|d urCd}|d urX|d urV||sVd}nd}n|d urb|}|d urk|}||||||f}"||||||f}#t|"|#||| Vq1d S)zgiven input data, generate a diff and yield it in blocks If generating a diff would lose data like flags or binary data and losedatafn is not None, it will be called. pathfn is applied to every path in the diff output. r,rrcSs ddd|D}d||fS)NrcSsg|]}d|qS)s-r %sr()rrr(r(r)r sz-trydiff..diffline..s diff %s %sr)r)rrevinfor(r(r)r s ztrydiff..difflinecSs|dup |dkSr)r.)r<r(r(r)isempty rztrydiff..isemptycSrYrRr()r)r(r(r)r\ rztrydiff..NFcss |] }|dur|VqdSrR)isbinaryrr(r(r)r sztrydiff..sdiff --git %s%s %s%ssnew file mode %ssdeleted file mode %ss old mode %ss new mode %sdssimilarity index %d%%s %s from %ss%s to %ss)noprefixrdatestrdaterrr;rrr3_gitmodeshowsimilarityrscorenobinaryindexcmpr diffcontent)$rrrrrrrrrrrraprefixbprefixrr date1date2rrrcontent1content2rrflag1flag2rpath1path2rmode1mode2simdata1data2r(r(r)r s                     rc Cs |\}}}}} } |\} } } }}}||vrt| ntj}| | vr#t|ntj}|rF|jrF|jsFt| |}|r?|d||fd|gff}n:|jrl|jdkrl|}|durV|}|d|d|j|d|jt |ftj | | |||| ||d\}}| ||| ||fS)aOdiffs two versions of a file. data1 and data2 are tuples containg: * ctx: changeset for the file * fctx: file context for that file * path1: name of the file * flag: flags of the file * content: full content of the file (can be null in case of binary) * date: date of the changeset header: the patch header binary: whether the any of the version of file is binary or not opts: user passed options It exists as a separate function so that extensions like extdiff can wrap it and use the file content directly. s index %s..%sNrsindex %s..%s %s)rr) rrnullhexrr*rb85diffr3r+r'unidiffextend)r;r<rrrrrr6r4r2r0rrr7r5r3r1index1index2rrQflaguheadersr(r(r)r- sB     r-c Csdd\}}}}}|D]!\}}}} t|t|}t|||}||7}||7}|p)| }q |||||fS)N)rrrrF)rrcolwidth) statsmaxfilemaxtotaladdtotal removetotalrr)rjrrlr(r(r) diffstatsumL s rKcs,td}gd\fdd}d}|D]u}|drH|d}d\|d r:t|d q|d rG||d q|d rPd}q|dr\|s\d 7q|drh|shd 7q|dsr|drudq|dr|ddq|drd|dd7q|S)Ns^diff .*-r [a-z0-9]+\s(.*)$)NrrFcsr fdSdSrRrOr(addsrr!removesresultsr(r) addresult^ szdiffstatdata..addresultFrRT)rrFrr!sdiff -rrs@@rrrs Binary files rename fromrs rename tos => %sr)rrr"rrr)r/rrPr&r%r(rLr) diffstatdataX s@           rQPc sg}t|}t|\}}}}tt}|r|dkrd}|||ddkr+dfdd} |D]1\} } } } | r?d}nd| | }d| | }d | | }|d | d |t| ||||fq4|rv|td t|||fd |S)Nrrrcs&kr|St|tt|SrR)rrbool)r graphwidthrHr(r)scale szdiffstat..scalesBinr/rrs %s%s | %*s %s%s rs5 %d files changed, %d insertions(+), %d deletions(-) r,) rQrKr$r#r3rrErr.)r/widthoutputrFmaxname totaladds totalremoves hasbinary countwidthrVrrMrNr!rAplusesminusesr(rTr)diffstat sD        r`cost|i|D]B}|rD|ddvrD|dd\}}|ddfVtd|}|r3|ddfVtd |}|rC|dd fVn|dfVd Vq d S) zOlike diffstat(), but yields 2-tuples of (output, label) for ui.write() rSs+-rrr,s\++rsdiffstat.inserteds-+sdiffstat.deletedrN)r`rrsplitrrr)rr r%namegraphr@r(r(r) diffstatui s   rdrR)rr,r=)Nr=)r,Nr=r)rr,Nr=r)rr,) NNNNNNNNNN)NNNNNNN)rR)l __future__rrr contextlibrrrrrr2r i18nrrrrr rr r r r rrrrrrrrrrutilsrrrrr-rrrrryrgrr#rcontextmanagerr|rtrhrrrrrrr*r5rrrrArrrrrbror$r&rrBrOr9r]rfrrrrurqrrrrrr Exceptionr diffalloptsdiffoptsdifffeatureoptsrrrrrrrrr'rr-rKrQr`rdr(r(r(r)s  <   q0-#41& . jPn C7e> @)=3g ; _2 #    ! O  HP% 9 - 0