a +bܣ @sdZddlmZddlZddlmZddlmZmZddl m Z m Z m Z m Z mZmZmZmZmZmZmZmZmZmZmZddlmZdZiZeeZiZeeZed d d d ed d dd ed ddd ddddZ ej!Z!Gddde"Z#Gddde"Z$ddZ%dd d!Z*Gd"d#d#e"Z+Gd$d%d%e"Z,d&d'Z-d(d)Z.d?d*d+Z/ed d,d-ded.fd/d0ded1fd2d3ded4fd5d6ded7fge j0e j1e j2ed8ej3d d9d:d;Z4dS)@a?apply working directory changes to changesets (EXPERIMENTAL) The absorb extension provides a command to use annotate information to amend modified chunks into the corresponding non-public changesets. :: [absorb] # only check 50 recent non-public changesets at most max-stack-size = 50 # whether to add noise to new commits to avoid obsolescence cycle add-noise = 1 # make `amend --correlated` a shortcut to the main command amend-flag = correlated [color] absorb.description = yellow absorb.node = blue bold absorb.path = bold )absolute_importN)_)hexshort)cmdutilcommandscontextcrecorderrorlinelogmdiffobsoletepatchphasespycompat registrar rewriteutilscmutilutil) stringutilsships-with-hg-coreabsorb add-noiseTdefaults amend-flagmax-stack-size2syellows blue boldsbold)absorb.description absorb.node absorb.pathc@s$eZdZdZdZdZdZddZdS)nulluizblank ui object doing nothingFTcCs dd}|S)Nc_sdSN)argskwdsr!r!2/usr/lib64/python3.9/site-packages/hgext/absorb.pynullfunc_sz$nullui.__getitem__..nullfuncr!)namer%r!r!r$ __getitem__^sznullui.__getitem__N)__name__ __module__ __qualname____doc__ debugflagverbosequietr'r!r!r!r$rWs rc@s(eZdZdZddZddZddZdS) emptyfilecontextz.minimal filecontext representing an empty filecCs ||_dSr )_repo)selfrepor!r!r$__init__hszemptyfilecontext.__init__cCsdS)Nr!r1r!r!r$datakszemptyfilecontext.datacCs|jjSr )r0nullidr5r!r!r$nodenszemptyfilecontext.nodeN)r(r)r*r+r3r6r8r!r!r!r$r/esr/cCs4t}g}|D] }||vr||||q|S)z@list -> list. remove duplicated items without changing the order)setaddappend)Zlstseenresultxr!r!r$uniqrs  r?cCs^|}g}|tjkrR|r(t||kr(qR|}t|dkr>qR|||d}q||S)a)(ctx, int?) -> [ctx]. get a linear stack of non-public changesets. changesets are sorted in topo order, oldest first. return at most limit items, if limit is a positive number. merges are considered as non-draft as well. i.e. every commit returned has and only has 1 parent. r)ZphaserZpubliclenparentsr;reverse)headctxlimitctxr=rBr!r!r$ getdraftstack}s    rGc Cs|durt}||dvr"gifSg}i}|d}t|D]b}||vrR|}q||}||||vrtd}q|||<|}|r>|}||vr>|}qq>|dur||vr|||n|t||t||fS)aP([ctx], str, set) -> [fctx], {ctx: fctx} stack is a list of contexts, from old to new. usually they are what "getdraftstack" returns. follows renames, but not copies. seenfctxs is a set of filecontexts that will be considered "immutable". they are usually what this function returned in earlier calls, useful to avoid issues that a file was "moved" to multiple places and was then modified differently, like: "a" was copied to "b", "a" was also copied to "c" and then "a" was deleted, then both "b" and "c" were "moved" from "a" and we enforce only one of them to be able to affect "a"'s content. return an empty list and an empty dict, if the specified path does not exist in stack[-1] (the top of the stack). otherwise, return a list of de-duplicated filecontexts, and the map to convert ctx in the stack to fctx, for possible mutable fctxs. the first item of the list would be outside the stack and should be considered immutable. the remaining items are within the stack. for example, given the following changelog and corresponding filelog revisions: changelog: 3----4----5----6----7 filelog: x 0----1----1----2 (x: no such file yet) - if stack = [5, 6, 7], returns ([0, 1, 2], {5: 1, 6: 1, 7: 2}) - if stack = [3, 4, 5], returns ([e, 0, 1], {4: 0, 5: 1}), where "e" is a dummy empty filecontext. - if stack = [2], returns ([], {}) - if stack = [7], returns ([1, 2], {7: 2}) - if stack = [6, 7], returns ([1, 2], {6: 1, 7: 2}), although {6: 1} can be removed, since 1 is immutable. Nr) r9p1reversedr; copysourcer/r2rCr?) stackpath seenfctxsfctxsfctxmappctxrFfctxcopyr!r!r$ getfilestacks:%    rTc@s eZdZdZddZddZdS) overlaystorezsread-only, hybrid store based on a dict and ctx. memworkingcopy: {path: content}, overrides file contents. cCs||_||_dSr )basectxmemworkingcopy)r1rVrWr!r!r$r3szoverlaystore.__init__cCsX||jvrdS|j|}||jvr.|j|}n|}||f}|}|||fS)z-comply with mercurial.patch.filestore.getfile)NNN)rVrWr6islinkZisexecrK)r1rMrRcontentmoderSr!r!r$getfiles    zoverlaystore.getfileN)r(r)r*r+r3r[r!r!r!r$rUsrUc Cs|dur|j|}|dur,|}|dur<|}|}|}t|  |}t ||}t j |||||||d|d S)zi({path: content}, ctx, (p1node, p2node)?, {}?) -> memctx memworkingcopy overrides file contents. N) r2rBtextfilesZ filectxfnuserdatebranchextra)r2Z changelogrBr8ra descriptionr_r^r9r]unionrUrZmemctx) rWrFrBradescr_r^r]storer!r!r$overlaycontexts* rfc@seZdZdZdddZdddZddZd d Zd d Ze d dZ ddZ ddZ ddZ ddZd ddZddZddZdS)!filefixupstatea state needed to apply fixups to a single file internally, it keeps file contents of several revisions and a linelog. the linelog uses odd revision numbers for original contents (fctxs passed to __init__), and even revision numbers for fixups, like: linelog rev 1: self.fctxs[0] (from an immutable "public" changeset) linelog rev 2: fixups made to self.fctxs[0] linelog rev 3: self.fctxs[1] (a child of fctxs[0]) linelog rev 4: fixups made to self.fctxs[1] ... a typical use is like: 1. call diffwith, to calculate self.fixups 2. (optionally), present self.fixups to the user, or change it 3. call apply, to apply changes 4. read results from "finalcontents", or call getfinalcontent NcCs~||_||_|pt|_|pi|_dd|D|_ttj |j|_ | |_ |jj rVddg|_g|_g|_g|_t|_dS)z([fctx], ui or None) -> None fctxs should be linear, and sorted by topo order - oldest first. fctxs[0] will be considered as "immutable" and will not be changed. cSsg|] }|qSr!)r6.0fr!r!r$ ;r4z+filefixupstate.__init__..rN)rOrMruioptscontentsrZmaplistr splitnewlines contentlines _buildlinelogr r, chunkstats targetlinesfixups finalcontentsr9 ctxaffected)r1rOrMrlrmr!r!r$r3/s    zfilefixupstate.__init__c Cs|jd}|jd}|}t|}||_|j|jj|jj }|rn|dd|dddf}| || ||||D]`} | | |} |j dt| 7<|j dd7<|j| 7_|dur~||||| | q~dS)acalculate fixups needed by examining the differences between self.fctxs[-1] and targetfctx, chunk by chunk. targetfctx is the target state we move towards. we may or may not be able to get there because not all modified chunks can be amended into a non-public fctx unambiguously. call this only once, before apply(). update self.fixups, self.chunkstats, and self.targetlines. rHrr@N)rnrpr6r rorsr annotateZmaxrevannotateresultr;_alldiffchunks_analysediffchunkrrboolrt _showchanges) r1 targetfctxfmaalinesbblines annotatedZ dummyendlinechunk newfixupsr!r!r$diffwithHs"     zfilefixupstate.diffwithc Cst|jD]x\}}}}}|j||}|jjrnt|ddd}|jtdt|j | ||t |f|j |||||q |jddr||_n ||_dS)zapply self.fixups. update self.linelog, self.finalcontents. call this only once, before getfinalcontent(), after diffwith(). r@rs%s: chunk %d:%d -> %d lines edit_linesFN)rJrtrsrlr,maxwriterrrOr8rAr replacelinesrmget_checkoutlinelogwitheditsru_checkoutlinelog)r1reva1a2b1b2ridxr!r!r$applyks zfilefixupstate.applycCs|j|}|j|S)z@(fctx) -> str. get modified file content for a given filecontext)rOindexru)r1rRrr!r!r$getfinalcontents zfilefixupstate.getfinalcontentcs6|\}}}}||}|sDrD|td|dh}fdd|D}tdd|D} g} t| dkr|||ddr| d} | dkr| d} | | ||||fn||||ks||kr,t||D]^} | \} }| dkr||krd}}n|| |}|d}| d} | | | | d||fq|| S)aanalyse a different chunk and return new fixups found return [] if no lines from the chunk can be safely applied. the chunk (or lines) cannot be safely applied, if, for example: - the modified (deleted) lines belong to a public changeset (self.fctxs[0]) - the chunk is a pure insertion and the adjacent lines (at most 2 lines) belong to different non-public changesets, or do not belong to any non-public changesets. - the chunk is modifying lines from different changesets. in this case, if the number of lines deleted equals to the number of lines added, assume it's a simple 1:1 map (could be wrong). otherwise, give up. - the chunk is modifying lines from a single non-public changeset, but other revisions touch the area as well. i.e. the lines are not continuous as seen from the linelog. rr@cs$g|]}|ddkr|qSrr@r!)riirr!r$rksz4filefixupstate._analysediffchunk..cSsh|] \}}|qSr!r!)rirlr!r!r$ r4z3filefixupstate._analysediffchunk..T)rlistrA _iscontinuousr;rxrange_optimizefixups)r1rrrrrrZinvolvedZnearbylinenumsZ involvedrevsrrZfixuprevrlinenumZnb1Znb2r!rr$rzs2      z filefixupstate._analysediffchunkccs4tj||||d}|D]\}}|dkr(q|VqdS)z5like mdiff.allblocks, but only care about differences)Zlines1Zlines2!N)r Z allblocks)rrrrZblocksrZbtyper!r!r$rys  zfilefixupstate._alldiffchunksc Cst}dg}}tt|jD]l}|j||j|}}|dd}|||||}tt|D]\} } } } | || | | | qd||}}q"|S)z~calculate the initial linelog based on self.content{,line}s. this is similar to running a partial "annotate". r4rr@) r rrrArnrpryrJrr) r1llogrrrrrZllrevchunksrrrrr!r!r$rqs   zfilefixupstate._buildlinelogcCsVg}tt|jD]<}|dd}|j|dt|j|jj }| |q|S)z1() -> [str]. check out file contents from linelogr@rr4) rrrArnr rwjoinmap_getlinerxr;)r1rnrrrYr!r!r$rs   zfilefixupstate._checkoutlinelogc s.|j}td|jd}ddt|jD}t|D]P\}\}}|tdd|dt||dt|| d dd f7}q<|td dt|7}t d d |D]8\}}|j |dd|jj D]|qq|D]0|ddfdd|D|f7}q|jj|ddd}|sLttddgt|j}d} | t|d} t|D]drqz| d| ddkrttd| dd} tt| | dD],\}} | dkr|||d | 7<qqz||kr*ddg|_|S)z&() -> [str]. prompt all lines for editsZHG: editing %s HG: "y" means the line to the right exists in the changeset to the top HG: rHcSs"g|]\}}t|ts||fqSr!) isinstancer/)rirrjr!r!r$rks z.sHG: %s/%s %s %s |-r@ rsHG: %s cSstSr )r9r!r!r!r$r4z:filefixupstate._checkoutlinelogwithedits..rs %s : %sr4cs$g|]\}}|vrdndqS)y r!)rirZ_frZlinesetr!r$rksr)actionsempty editor textsHG:s : smalformed line: %sNr)r getalllinesrrOrM enumeraterArr8rbsplit defaultdictrwrxr:rrrlZeditr InputErrorr ro startswithrZbytestrrr) r1ZalllinesZ editortextZ visiblefctxsrjrjZ editedtextrnZ leftpadposZcolonposZ linecontentZchr!rr$rsh               z(filefixupstate._checkoutlinelogwitheditscCs0|\}}|d@r"|j|d|S|j|SdS)z@((rev, linenum)) -> str. convert rev+line number to line contentr@rN)rprs)r1Zlineinforrr!r!r$rszfilefixupstate._getlineFcCsR||kr dS|j}||}||t|}|||}t|||t|kS)a(a1, a2 : int) -> bool check if these lines are continuous. i.e. no other insertions or deletions (from other revisions) among these lines. closedinterval decides whether a2 should be included or not. i.e. is it [a1, a2), or [a1, a2] ? T)r Z getoffsetintrrA)r1rrZclosedintervalrZoffset1Zoffset2Zlinesinbetweenr!r!r$r&s   zfilefixupstate._iscontinuousc sggdgfdd}t|D]\}}|\}}}}} dd} dd} dd} || kr|| kr|| kr|t|dd|r|dd<| dd<q$|t|d<q$|S)zx[(rev, a1, a2, b1, b2)] -> [(rev, a1, a2, b1, b2)]. merge adjacent fixups to make them less fragmented. )rHrHrHrHrHcs&dddkr"tddS)NrrH)r;tupler!Z pcurrentchunkr=r!r$ pushchunk>sz1filefixupstate._optimizefixups..pushchunkrrrr@)rrrr) r1rtrrrrrrrrZlastrevZlasta2Zlastb2r!rr$r7s,     zfilefixupstate._optimizefixupsc sTdd}|\}}} } dg||dg| | } } |D]f\} }}}}t||D]}t| ddd| ||<qPt||D]}t| ddd| || <q|q6jddd|||| | | fd d jjdd fd d }t||D]$}|| ||d|||ddqt| | D]&}|| || d|||ddq(dS)NcSs|dr|dd}|S)NrrH)endswith)liner!r!r$trimWs  z)filefixupstate._showchanges..trimrr@rshunks %s s@@ -%d,%d +%d,%d @@s diff.hunkZlabelrMlinetypecs|d}|r>j|}j|d|}j|jdd|ddjd|d|||djj |d dS) Nr4)rRnode%-7.7s rrs diffchar s%s%s r) startitemrOrrrvr:Z changectxrr6rM)rZdiffcharrrZ linelabelr8rFr~r1r!r$ writelineos   z.filefixupstate._showchanges..writelinersdeleteds diff.deleted+sinserteds diff.inserted)rrrrrr6rM)r1r~rrrrtrrrrrZaidxsZbidxsrZfa1Zfa2Zfb1Zfb2rrr!rr$r|VsB     zfilefixupstate._showchanges)NN)N)F)r(r)r*r+r3rrrrz staticmethodryrqrrrrrr|r!r!r!r$rgs  #3  D rgc@seZdZdZd#ddZd$ddZddZed d Zd d Z d dZ ddZ ddZ ddZ ddZddZed%ddZd&ddZejddZdd Zejd!d"ZdS)' fixupstatea^state needed to run absorb internally, it keeps paths and filefixupstates. a typical use is like filefixupstates: 1. call diffwith, to calculate fixups 2. (optionally), present fixups to the user, or edit fixups 3. call apply, to apply changes to memory 4. call commit, to commit changes to hg database NcCs^|pt|_|pi|_||_|d|_g|_d|_i|_i|_ i|_ d|_ t |_ dS)z([ctx], ui or None) -> None stack: should be linear, and sorted by topo order - oldest first. all commits in stack are considered mutable. rHN)rrlrmrLr2Z unfilteredpathsstatusrPfixupmap replacemap finalnoder9rv)r1rLrlrmr!r!r$r3s  zfixupstate.__init__c CsX|jd|||_g|_|jd}|jjs@|r@|r@|}n|jj}t}t|D]}|j d|||}t |j||\} } t dd|g| DrqV| | d kr|sqV|| dd| |j|<t| ||j |jd} |dur"||d |jd d |d d |j d d| ||| |j|<|j||j| jqVdS)z9diff and prepare fixups. update self.fixupmap, self.pathsrHrscalculating fixups for %s css.|]&}t|ts|p$t|VqdSr )rr/rXrZbinaryr6rhr!r!r$ s z&fixupstate.diffwith..r@Nrlrmsshowing changes for spath%s rrr)rLrrrmrZmodifiedr]r9sortedrldebugrTanyr6updaterPrgrZplainrrrr;rv) r1 targetctxmatchr~ZeditoptZinterestingpathsrNrMr}rOctx2fctxZfstater!r!r$rs:          zfixupstate.diffwithcCs>t|jD],\}}|jjr0|jtd||q dS)z*apply fixups to individual filefixupstatessapplying fixups to %s N)r iteritemsrrlr,rrr)r1rMstater!r!r$rszfixupstate.applycCsddt|jDS)z>-> {path: chunkstats}. collect chunkstats from filefixupstatescSsi|]\}}||jqSr!)rr)rirMrr!r!r$ sz)fixupstate.chunkstats..)rrrr5r!r!r$rrs zfixupstate.chunkstatscCsh|jdF}||||jd|jvr<||Wdn1sX0Y|jS)z6commit changes. update self.finalnode, self.replacemapr.N) r2Z transaction _commitstack_movebookmarksr8r_moveworkingdirectoryparent_cleanupoldcommitsr)r1trr!r!r$commits &zfixupstate.commitcs|j}|j}|jrPt|D]0\}}|dr|td||d|dfqn:|js|fdddD\}}|td||fdS) z+print things like '1 of 2 chunk(s) applied'rs%s: %d of %d chunk(s) applied r@c3s$|]tfddDVqdS)c3s|]}|VqdSr r!risrr!r$rr4z7fixupstate.printchunkstats...N)sum)riZstatsrr$rr4z-fixupstate.printchunkstats..rs%d of %d chunk(s) applied N) rlrrr-rrrrr.values)r1rlrrrMstatZappliedtotalr!rr$printchunkstatsszfixupstate.printchunkstatscCsd}d}|jD]}||}|s*|s*|}q|o>||||}|jrb|rbd|j|<td}nt|j|||d}|j |}|}||j|<|r|rtd}ntd}|t || |f}ntd| |}|j j r|r|j td| ||fq|o||_dS)zmake new commits. update self.finalnode, self.replacemap. it is splitted from "commit" to avoid too much indentation. Nsbecame empty and was dropped)rIs&%d file(s) changed, became empty as %ss%d file(s) changed, became %ss became %ss%s: %s )rL_getnewfilecontentsr]_willbecomenoopskip_empty_successorrr8r _commitsingler2rA_ctx2strrlr-rr)r1Z lastcommittedZnextp1rFrWZwillbecomenoopmsgZnodestrr!r!r$r s:         zfixupstate._commitstackcCs8|jjrd||fSd|t|fSdS)Ns%d:%s)rlr,rrrr8)r1rFr!r!r$r5szfixupstate._ctx2strcCs\i}|jD]L}|j|}||vr"q ||}|}|j||}||kr |||<q |S)z(ctx) -> {path: str} fetch file contents from filefixupstates. return the working copy overrides - files different from ctx. )rrPr6rrrM)r1rFr=rMrrRrYZ newcontentr!r!r$r;s  zfixupstate._getnewfilecontentscsj}fddt|jD}g}|D]j\}}|rh|||fjjrjtd|t |fq(||dfjjr(jtd|q(|j |||dS)Ncs(g|] \}}|jvr|j|fqSr!)r)rir&hshr5r!r$rkOs z-fixupstate._movebookmarks..smoving bookmark %s to %s sdeleting bookmark %s ) r2rrZ _bookmarksr;rlr-rrrZ applychanges)r1rr2Z needupdateZchangesr&rr!r5r$rMs    zfixupstate._movebookmarkscs|js4|jd|j}|j|}||_n |j|j}|jjdd}|}t dr~j j fdd}|j _ zJ ( |||jWdn1s0YW|n|0dS)Nsmax(::. - %ln)cSsdS)Nrr!r!r!r!r$rnr4z8fixupstate._moveworkingdirectoryparent.._fsmonitorstatecs j_dSr )r invalidater!Zbakdirstater!r$restoressz7fixupstate._moveworkingdirectoryparent..restore)rr2revsrkeysfirstr8rrZ safehasattrrrZ parentchangeZrebuildZmanifestr)r1rrFZnooprr!rr$rbs     8z&fixupstate._moveworkingdirectoryparentcCs|s$|}t|dkrdS|d}||kr8dS|drJdSt|t|sddSt |D]V\}}||vs||vrdS||}||}| | krdS| |krndSqndS)z({path: content}, ctx, ctx) -> bool. test if a commit will be noop if it will become an empty commit (does not change anything, after the memworkingcopy overrides), return True. otherwise return False. r@FrscloseT) rBrAr`rarr9r]issubsetrrflagsr6)rWrFrQrBrMrYrRZpfctxr!r!r$r}s*  zfixupstate._willbecomenoopcCsx|o||jjf}|}|jr8|jddr8||d<t|| dd|j D}t |||||d}| S)z(ctx, {path: content}, node) -> node. make a single commit the commit is a clone from ctx, with a (optionally) different p1, and different file contents replaced by memworkingcopy. rrs absorb_sourcecSsi|]\}}||gqSr!r!)riZoldnodeZnewnoder!r!r$rsz,fixupstate._commitsingle..)rard)r2r7ra _useobsoleterlZ configboolrrZupdate_hash_refsrbritemsrfr)r1rWrFrIrBrardZmctxr!r!r$rs  zfixupstate._commitsinglecCst|jtjS)z () -> bool)r isenabledr2Zcreatemarkersoptr5r!r!r$rszfixupstate._useobsoletecCs2ddt|jD}|r.tj|j|ddddS)NcSs$i|]\}}||dur|gngqSr r!)rikvr!r!r$rsz1fixupstate._cleanupoldcommits..rT)Z operationZfixphase)rrrrZ cleanupnodesr2)r1Z replacementsr!r!r$rs  zfixupstate._cleanupoldcommitscCst|jdS)Nr)rrrlr5r!r!r$rszfixupstate.skip_empty_successor)NN)NN)N)N)r(r)r*r+r3rrpropertyrrrrrrrrrrrrrZ propertycacherrrr!r!r!r$rs*  *  +    rcCst|tjtjfvrdS|j}|jt|j d}g|_ |_ t }| |t|}||j}dd|ddD}||||ffS)zA(crecord.uihunk or patch.recordhunk) -> (path, (a1, a2, [bline])))NNr@cSs"g|]}|ds|ddqS)rr@N)r)rirr!r!r$rkr4z_parsechunk..N)typer ZuihunkrZ recordhunkheaderfilenameZfromlinerAbeforeZafterrZstringiorr rogetvalueZremoved)ZhunkrMrbufZ patchlinesrrr!r!r$ _parsechunks    r c Csi}tdd}tt|D] \}}|r|s,q|||qt|D]^\}}||vsF|s\qF|jddt|| }|D]\}} } | ||| <q~d |||<qFt ||S)z(ctx, [crecord.uihunk]) -> memctx return a memctx with some [1] patches (chunks) applied to ctx. [1]: modifications are handled. renames, mode changes, etc. are ignored. cSsgSr r!r!r!r!r$rr4z$overlaydiffcontext..T)rCr4) rrr r;rrsortr ror6rrf) rFrrWZpatchmaprMinfoZpatcheslinesrrrr!r!r$overlaydiffcontexts   rcCsj|durf|dd}|d}t|dkr:ttdt||}|rft||krf|td||sxttd|dur|d}|durd }|duri}t|||d }t |||} | d rt ||d || } t | } t|| | d } t|d | }d} | ds*| ds6|d|} ||| | | dur| | ddt|j| jddt|D]n}||jvrq~| | j|d| jdd| jdd|dd|d }| jdd|ddq~| | dsf| ds4|jr4|jdddr4t td |!|"rP|#n|j$sf|td!|S)"zpick fixup chunks from targetctx, apply them to stack. if targetctx is None, the working copy context will be used. if stack is None, the current draft stack will be used. return fixupstate. Nrrrr@scannot absorb into a merges7absorb: only the recent %d changesets will be analysed sno mutable changeset to changer!r interactiverHrs print_changess apply_changesscounts %d changesets affected ssummaryr)rFs changesetrrrrs descfirstlinerrdry_runs#apply changes (y/N)? $$ &Yes $$ &Norsabsorb cancelled snothing applied )%Z configintrArBr rrrGwarnrrrrrdiffr8Z parsepatchrZ recordfilterr formatterrrrrvr6rJrrrb splitlinesendZ promptchoiceZ CanceledErrorrrrr.)rlr2rLrpatsrmrErDrZmatcherrZ origchunksrr~rFZ descfirstliner!r!r$absorbs                ras apply-changess0apply changes without prompting for confirmationps print-changess;always print which changesets are modified by which changesirs*interactively select which chunks to applyes edit-linessGedit what lines belong to which changesets before commit (EXPERIMENTAL)shg absorb [OPTION] [FILE]...)Z helpcategoryZ helpbasicc Ost|}||j|ds0t|t||||d}tdd|j DdkrxWdWddSWdn1s0YWdn1s0YdS)aincorporate corrections into the stack of draft changesets absorb analyzes each change in your working directory and attempts to amend the changed lines into the changesets in your stack that first introduced those lines. If absorb cannot find an unambiguous changeset to amend for a change, that change will be left in the working directory, untouched. They can be observed by :hg:`status` or :hg:`diff` afterwards. In other words, absorb does not write to the working directory. Changesets outside the revset `::. and not public() and not merge()` will not be changed. Changesets that become empty after applying the changes will be deleted. By default, absorb will show what it plans to do and prompt for confirmation. If you are confident that the changes will be absorbed to the correct place, run :hg:`absorb -a` to apply the changes immediately. Returns 0 on success, 1 if all chunks were ignored and nothing amended. r)rrmcss|]}|dVqdS)rNr!rr!r!r$rr4zabsorbcmd..rNr@) rZ byteskwargsZwlocklockrZcheckunfinishedrrrrr)rlr2rrmrr!r!r$ absorbcmdGs>  r)N)N)NNN)NNNN)5r+Z __future__r collectionsZmercurial.i18nrZmercurial.noderrZ mercurialrrrr r r r r rrrrrrrZmercurial.utilsrZ testedwithZcmdtableZcommandZ configtableZ configitemZ colortablerobjectrr/r?rGrTZ filestorerUrfrgrr rrZ dryrunoptsZ templateoptsZwalkoptsZCATEGORY_COMMITTINGrr!r!r!r$s  D      R |6 O &