
    	^cz                        d dl Z d dlZd dlZd dlmZ d dlmZmZmZ d dl	m
Z
mZmZ d dlmZmZmZmZmZmZmZ d dlmZmZ ddlmZmZ ej        d	             ZddZ d Z!d Z" ej        ej#                  Z$ddZ%d Z&d Z' e'ej(                  Z) G d d          Z* e*            Z( G d d          Z+d Z, G d d          Z-ej.        e(dfd            Z/ddZ0dS )    N)_)getattropensetattr)binhexshort)errorlineloglockmdiffpycompatscmutilutil)hashutil
stringutil   )r
   revmapc                 ,    |                      |          S N)file)repopaths     </usr/lib/python3/dist-packages/hgext/fastannotate/context.py_getflogr   ,   s    99T??    Tc                       j                                           }|s fd|D             }|D ]7}d|j        vr,t           j        |                                          |_        8|S )Nc                 h    g | ].}|                                                                  k    ,|/S  r   ).0pfs     r   
<listcomp>z_parents.<locals>.<listcomp><   s3    444Aqvvxx1668833a333r   _filelog)	_changeidparents__dict__r   _repor   r%   )r#   followplr"   s   `   r   _parentsr,   2   s{    
 KK	
B  54444444  5 5QZ''!!'1668844AJIr   c                                                        }|                    d          }|r|                    d          s|dz  } fdt          |          D             |fS )N   
r   c                     g | ]}|fS r   r   )r!   ifctxs     r   r$   z_decorate.<locals>.<listcomp>N   s    1111dAY111r   )datacountendswithrange)r1   text	linecounts   `  r   	_decorater8   I   sl    99;;D

5!!I DMM%(( Q	1111i 0 0111488r   c                 b    |D ]+\  \  }}}}}|dk    r| d         ||         |d         ||<   ,|S )N   =r   r   )parentchildblocksa1a2b1b2ts           r   _pairrC   T   sN    % / /RR! 99$Qi2.E!HRUOLr   Fc                    |r(t          |t                    s|t          | |          }n| |         }|G|                                	||         }n|                     ||                                          }nc||         }|dk    r|                                }n|                                }||                                k    r||_        | |         |_        |S )a2  (repo, str, str) -> fctx

    get the filectx object from repo, rev, path, in an efficient way.

    if resolverev is True, "rev" is a revision specified by the revset
    language, otherwise "rev" is a nodeid, or a revision number that can
    be consumed by repo.__getitem__.

    if adjustctx is not None, the returned fctx will point to a changeset
    that introduces the change (last modified the file). if adjustctx
    is 'linkrev', trust the linkrev and do not adjust it. this is noticeably
    faster for big repos but is incorrect for some cases.
    N)changeid   linkrev)	
isinstanceint
_revsinglerevfilectxlinkrevintrorevr&   
_changectx)r   rJ   r   
resolverev	adjustctxctxr1   rM   s           r   resolvefctxrR   b   s      *S#.. 3?s##3i  7799t9DD<<swwyy<99DD4y
""||~~HH}}Hswwyy  %DN"8nDOKr   c                     |                      dd                               dd                               dd                               dd          S )	Ns   .hg/s   .hg.hg/s   .l/s   .l.hg/s   .m/s   .m.hg/s   .lock/s	   .lock.hg/)replacer    s    r   	encodedirrU      sE    Wj))		#	#		#	#	L	)	)	r   c                      t          j        t           fdt          j        j        D                                 }t          t          j        |          	                                          d d         S )Nc              3   <   K   | ]}|t          |          fV  d S r   )r   )r!   kdiffoptss     r   	<genexpr>zhashdiffopts.<locals>.<genexpr>   s2      JJQ78Q''(JJJJJJr      )
r   pprintsortedr   rY   defaultsr   r   sha1digest)rY   
diffoptstrs   ` r   hashdiffoptsrb      si    "JJJJ%.2IJJJJJ J x}Z((//11222A266r   c                   D    e Zd ZdZddddZd Zej        d             ZdS )annotateoptszlike mercurial.mdiff.diffopts, but is for annotate

    followrename: follow renames, like "hg annotate -f"
    followmerge: follow p2 of a merge changeset, otherwise p2 is ignored
    NT)s   diffoptss   followrenames   followmergec           	          t          j        |          }| j                                        D ]*\  }}t	          | ||                    ||                     +d S r   )r   byteskwargsr^   itemsr   get)selfoptsrX   vs       r   __init__zannotateopts.__init__   s^    #D))M'')) 	- 	-DAqD!TXXa^^,,,,	- 	-r   c                     d}| j         s|dz  }| j        s|dz  }| j        Ht          | j        t          j                  sJ t          | j                  }|t          k    r|d|z   z  }|pdS )z?represent opts in a short string, suitable for a directory namer   s   r0s   m0N   is   default)followrenamefollowmergerY   rG   r   rb   _defaultdiffopthash)ri   resultdiffopthashs      r   shortstrzannotateopts.shortstr   s       	eOF 	eOF=$dmU^<<<<<&t}55K111$,,##r   )	__name__
__module____qualname____doc__r^   rl   r   propertycachert   r   r   r   rd   rd      sc           H- - -
 
$ $ $ $ $r   rd   c                      e Zd ZdZd Zed             Zed             Zd ZeZ	d Z
ed             Zdd	ZddZd ZddZd Zd Zd ZddZd Zedd            ZddZd Zej        d             Zej        d             ZddZd
S )_annotatecontextz{do not use this class directly as it does not use lock to protect
    writes. use "with annotatecontext(...)" instead.
    c                     || _         |j        | _        || _        || _        || _        || _        d | _        d | _        i | _        d S r   )	r   uir   rj   linelogpath
revmappath_linelog_revmap
_node2path)ri   r   r   r~   r   rj   s         r   rl   z_annotatecontext.__init__   sH    	'		&$r   c                    | j         t          j                            | j                  rt          | j        d          5 }	 t          j                            |	                                          | _         n-# t          j
        $ r t          j                    | _         Y nw xY wd d d            n# 1 swxY w Y   nt          j                    | _         | j         S )Ns   rb)r   osr   existsr~   r   
linelogmodr   fromdatareadLineLogErrorri   r#   s     r   r   z_annotatecontext.linelog   s    = w~~d.// 5$*E22 =a=(2(:(C(CAFFHH(M(M%2 = = =(2(:(<(<== = = = = = = = = = = = = = = !+ 2 4 4}s6   B36A:9B3:'B$!B3#B$$B33B7:B7c                 Z    | j         t          j        | j                  | _         | j         S r   )r   	revmapmodr   r   ri   s    r   r   z_annotatecontext.revmap   s&    <$+DO<<DL|r   c                 &   | j          | j                                          d | _         | j        bt          | j        d          5 }|                    | j                                                   d d d            n# 1 swxY w Y   d | _        d S d S )Ns   wb)r   flushr   r   r~   writeencoder   s     r   closez_annotatecontext.close   s    <#L   DL=$d&.. 0!,,..///0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 DMMM %$s   -A==BBc                     |                                   | j                                         t          | j        | j        g           dS )z0delete linelog and revmap, useful for rebuildingN)r   r   clear_unlinkpathsr   r~   r   s    r   rebuildz_annotatecontext.rebuild   sA    

dot'7899999r   c                     | j         t          j        | j                  S | j                             | j         j                  S )z6return last node in revmap, or None if revmap is empty)r   r   getlastnoder   rev2hshmaxrevr   s    r   lastnodez_annotatecontext.lastnode   s:     <(999<''(;<<<r   Tc                    | j         }	 |                     |d          }| j        j                            |                                          }|s$|r"||k    r| j                            |          duS ||k    S # t          $ r Y dS w xY w)a   return True if the revmap / linelog is up-to-date, or the file
        does not exist in the master revision. False otherwise.

        it tries to be fast and could return false negatives, because of the
        use of linkrev instead of introrev.

        useful for both server and client to decide whether to update
        fastannotate cache or not.

        if strict is True, even if fctx exists in the revmap, but is not the
        last node, isuptodate will return False. it's good for performance - no
        expensive check was done.

        if strict is False, if fctx exists in the revmap, this function may
        return True. this is useful for the client to skip downloading the
        cache if the client's master is behind the server's.
        T)rO   N)	r   _resolvefctxr   	changelognoderL   r   hsh2revLookupError)ri   masterstrictr   r#   linknodes         r   
isuptodatez_annotatecontext.isuptodate  s    $ =	!!&T!::A y*//		<<H Ah A8x+?+? {**844D@@ x'' 	 	 	44	s   A-A= 7A= =
B
BNFc           
           t          |t                    r,t           j        j                            |                    }                     |          \  }}|rl j        j        rI j        	                    d j
        t          j        t          j        |d                    fz                                  |||          S d}|r5	                      |dd          }| j        v rd}n# t$          $ r Y nw xY w|g}|rY|                                0t)          j        t-          d          t-          d                    |                    |           |dd         }	i }
|d	i}i }|	r|	                                }||
v s||v r| j        v rl j                            |                                          } j                            |            j        j        }||                                f||<                        |          }||
|<   |D ]7}|                    |d
          d	z   ||<   ||
vr|	                    |           8|	tA                      }|}|r?| j        vr6|!                    |           |
|         }|r	|d
         }nd}n|r	| j        v6| "                    |            j        j        rX|r2 j        	                    d j
        tG          |          fz             n$|s" j        	                    d j
        z              j                             j        j$                   |dd         }	 j        %                    dtG          |                    }|	r|	d         }||v r|	                                 $d}|
|         }|D ]}||vrd}|	                    |           |sQ|	                                 d}||v }||vsJ tM          |          }tO          |          D ]~\  }}tQ           )                    ||         d	         |d	                             }|d
k    r|r|}tU          ||         ||          }||         d	k    r||= ||= n||xx         d	z  cc<   |||<   |
|= |r|+                                 d}tG          |          dk    r j,        j-        r|d
         }|)tQ           )                    d|d	                             } .                    |||           n0|r.|
                                 j/        |                                <   |	|0                                  fd||         d
         D             } 1                    ||||          S )a  incrementally update the cache so it includes revisions in the main
        branch till 'master'. and run annotate on 'rev', which may or may not be
        included in the main branch.

        if master is None, do not update linelog.

        the first value returned is the annotate result, it is [(node, linenum)]
        by default. [(node, linenum, path)] if showpath is True.

        if showlines is True, a second value will be returned, it is a list of
        corresponding line contents.
        s6   fastannotate: %s: using fast path (resolved fctx: %s)
s   nodeNTrO   rP   s   cannot update linelog to wdir()s   set fastannotate.mainbranch)hintr   r   s7   fastannotate: %s: %d new changesets in the main branch
sB   fastannotate: %s: linelog cannot help in annotating this revision
s   building cache)totalF   r   c                     g | ]J\  }}t          |t                    rj                            |          n|                                |fKS r   )rG   rH   r   r   r   )r!   frlri   s      r   r$   z-_annotatecontext.annotate.<locals>.<listcomp>  s^     
 
 
A *4B)<)<Kdk!!"%%%"''))aP
 
 
r   )2rG   rH   r   r   r   r   canannotatedirectlyr}   	debugflagdebugr   r   r\   r   safehasattrannotatedirectlyr   r   r   rJ   r
   Abortr   appendpopr   r   annotateannotateresultr2   _parentfuncrh   setadd_checklastmasterheadlenr   makeprogressr8   	enumeratelist_diffblocksrC   	incrementrj   rp   
_appendrevr   complete_refineannotateresult)ri   rJ   r   showpath	showlinesdirectlyrevfctx
masterfctx	initvisitvisitpcacheneededhistr#   llrevrr   r+   r"   newmainbranchprogressreadyr=   ismainbranchcurrr0   bs
bannotateds   `                          r   r   z_annotatecontext.annotate'  s|   $ c3 	5di)..s3344C !44S99' 
	Gw  - 	")$*:7G*L*LMM   (((IFFF 
 		&&!..tt /  
 ,,!%J	    8 I	 	)~~'k8999::    Z(((!!!1 	$		AF{{a4iiDK++AFFHH55%%e,,,4!16688,Q!!!$$BF1I $ $"JJq!,,q0q	F??LLOOO  	$&  	AT[((a   B qE  	AT[(( !%%a(((7 
	 	!$(Is=/A/A#BC     248I>   	dl1222 !!!7''S%7%7 ( 
 
  .	5b	ADyy		EB $ $D==!ELLOOO IIKKKF-L D====Q<<D!" 	# 	#1$**471:tAw??@@66l6FT!WdB//!9>>Qq		1IIINIIIIDGq	 	5""$$$!
r77a<<DI$9<!%aJ>!$"2"23Q"@"@AAF6:6666 5,-FFHH)]  .	5` 	
 
 
 
gq)
 
 
 ))&'8YOOOs   C2 2
C?>C?c                 x   d}d}t          |t                    sO|Mt          t          d                    t          |          d           |          }||| j        f| j        v r|}|M| j        rdnd}| 	                    ||d          }|| j        v }|s| j        r| 	                    |dd          }||fS )z(str) -> bool, fctx or node.
        return (True, f) if we can annotate without updating the linelog, pass
        f to annotatedirectly.
        return (False, f) if we need extra calculation. f is the fctx resolved
        from rev.
        TN)   (   c                     d S r   r   )xs    r   <lambda>z6_annotatecontext.canannotatedirectly.<locals>.<lambda>  s    t r   rF   )rP   rO   )
rG   rH   bytesr   rh   r   r   r   	_perfhackr   )ri   rJ   rr   r#   hshrP   s         r   r   z$_annotatecontext.canannotatedirectly  s     #s## 	#&&**3s88^^DDSIICC#3t{#B#B9&*n>

$I!!#t!LLA$+%F Ldn L %%cTd%KKqyr   c                    |                      |dd          }|| j        vrD|g}d}	 |d         }|                     |          }|snF|d         | j        v r|d                                         }n|                    |d                    ft          j                    }	|	                    | j                   |	                    |	j	                   t          j                                        | j                   t          |          D ]S}|                                }
t          |                     ||
                    }|                     |	||           |
}Tn| j        }	| j        |	                                }|                                }                    |          fd|D             }|r|                     |          }|r|                     ||	          }||f}|S )a  (rev : str) -> [(node : str, linenum : int, path : str)]

        the result has the same format with annotate, but include all (including
        deleted) lines up to rev. call this after calling annotate(rev, ...) for
        better performance and accuracy.
        Tr   r   r   r   c                 P    g | ]"\  }}|k                         |          |f#S r   )r   )r!   rr   r   r   s      r   r$   z5_annotatecontext.annotatealllines.<locals>.<listcomp>.  s3    IIITQa5jj6>>!$$a(jjjr   )r   r   r   r2   r   r   r   copyfromr   r   r   reversedr   r   _doappendrevgetalllinesr   r   _addpathtoresult_resolvelines)ri   rJ   r   r   r   chainar#   r+   r   br=   linesr   rr   linecontentsr   r   s                   @@r   annotatealllinesz!_annotatecontext.annotatealllines   s    ##CDD#II $+%%IEA$"I%%a(( a5DK''1

ARU###$ !(**GT\***W^,,,%''FOODK(((e__  FFHHd..q!4455!!'61f===	 lG[F##%%llnns##IIIIIUIII  	;**66::F 	,--ffgFFLl+Fr   c                    fd|D             }dgt          |          z  }t          j        t                    }t	          t          |                    D ]1}|||         ||         d         f                             |           2|rcd}	 |                                D ]?\  \  }	}
}                    |	          t          j	        z  r+||d                  d         } n# t          $ r |cY S w xY w|i }|                                D ]\  \  }	}}|	|vr||d                  d         }| j        j        r-| j                            dt          |          ||fz             |                     |                    |	                    }t#          j        |                                          }|||	<   |D ]}||	         |         ||<   t)          d |D                       sJ |S | j                            dt          |          z             |                    |	           |                     |                    |	                    }|j        }t#          j        |                                          }t          |          t          |          k    rt/          j        d          t3          |          D ]$\  }}||         }||v r||         D ]}|||<   ||= %|c|S )	ah  (annotateresult) -> [line]. designed for annotatealllines.
        this is probably the most inefficient code in the whole fastannotate
        directory. but we have made a decision that the linelog does not
        store line contents. so getting them requires random accesses to
        the revlog data, since they can be many, it can be very slow.
        c                 F    g | ]}                     |d                    S )r   )r   )r!   r   r   s     r   r$   z2_annotatecontext._resolvelines.<locals>.<listcomp>@  s)    ===qt$$===r   Nr   r   s6   fastannotate: reading %s line #%d to resolve lines %r
c              3      K   | ]}|d uV  	d S r   r   )r!   r   s     r   rZ   z1_annotatecontext._resolvelines.<locals>.<genexpr>c  s&      99Q1D=999999r   s+   fastannotate: annotate %s to resolve lines
s   unexpected annotated lines)r   collectionsdefaultdictr   r5   r   rg   rev2flagr   sidebranchflagStopIterationr}   r   r   r	   r   rev2pathr   splitnewlinesr2   allr   r   faerrorCorruptedFileErrorr   )ri   r   r   r   revsrr   key2idxsr0   r   rJ   _linenumidxsrevlineslinenumr1   r   idx	annotatedlinerX   s     `                 r   r   z_annotatecontext._resolvelines8  sK    >===n===#n---*400s6{{## 	@ 	@Ad1g~a0345<<Q???? 0	$C-5^^-=-=  )OS(Ts++i.FF ! (a1!4C    { ,4NN,<,< = =(NS'D(**,T!W5a87,  GMM!9#(::w"=!>  
  $00fooc6J6JKK % 3DIIKK @ @(-# = =&.smG&<s=99&99999999 GMM?%**L   S!!!$$S&//#*>*>??D.I'		44E5zzS^^++01NOOO$U++ $ $4aL=='{ + +&*s a  0	$b s   AC% %C43C4c                     t          |t                    r|}n|                                } j                            |          }|s$t          j        dt          |          z             j                            |          t          j
        z  dk    r$t          j        dt          |          z             j                            |            fd j        j        D             }                     ||||          S )a  like annotate, but when we know that f is in linelog.
        f can be either a 20-char str (node) or a fctx. this is for perf - in
        the best case, the user provides a node and we don't need to read the
        filelog or construct any filecontext.
        s   %s is not in revmapr   s   %s is not in revmap mainbranchc                 N    g | ]!\  }}j                             |          |f"S r   )r   r   )r!   r   r   ri   s      r   r$   z5_annotatecontext.annotatedirectly.<locals>.<listcomp>  s?     
 
 
,0AqT[  ##Q'
 
 
r   )rG   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )ri   r#   r   r   r   r   rr   s   `      r   r   z!_annotatecontext.annotatedirectlyy  s    a 	CC&&((C##C(( 	P,-Cc#hh-NOOOK  '')*BBqHH,1CHH<   	e$$$
 
 
 
48L4O
 
 
 ))&!XyIIIr   c                    |r|                      |          }|rt          |t                    rI| j                            |          }|                     || j                            |                    }n|}t          j        |	                                          }t          |          t          |          k    rt          j                    ||f}|S )znadd the missing path or line contents, they can be expensive.
        f could be either node or fctx.
        )r   rG   r   r   r   r   r   r   r   r2   r   r   r   )ri   rr   r#   r   r   r   r1   r   s           r   r   z&_annotatecontext._refineannotateresult  s      	3**622F 		%!U## ++A..((DK,@,@,G,GHH'		44E5zzS[[((0222e_Fr   c                 L    |                      | j        | j        |||           d S r   )r   r   r   )ri   r1   r=   r   s       r   r   z_annotatecontext._appendrev  s(    $,T6:NNNNNr   c                 B    t          j        ||| j        j                  S r   )r   	allblocksrj   rY   )ri   r   r   s      r   r   z_annotatecontext._diffblocks  s    q!TY%7888r   c                 @   fd}g }i |*|D ]'\  \  }}}	}
}|dk    r|d ||	|
         D             z  }(t          |          }||v r|                    |           |D ]} ||          |<                       |                                |                                          }||<   t          |          D ][\  \  }}}	}
}|dk    r||                     ||||	|
           -fd||	|
         D             }|                     ||||           \dS )z'append a revision to linelog and revmapc                    t          | t                    rt          j        d          |                                 }                    |          }|*                    |d|                                           }|S )z(fctx) -> ints   f should not be an intNT)
sidebranchr   )rG   rH   r
   ProgrammingErrorr   r   r   r   )r#   r   rJ   r   s      r   getllrevz/_annotatecontext._doappendrev.<locals>.getllrev  sq     !S!! H,-FGGG&&((C..%%C{mmCDqvvxxmHHJr   Nr:   c                 B    g | ]\  }}t          |t                    |S r   rG   rH   )r!   r#   r   s      r   r$   z1_annotatecontext._doappendrev.<locals>.<listcomp>  s<     ! ! ! Aq)!S11!! ! !r   r    c                 X    g | ]&\  }}t          |t                    r|n|         |f'S r   r  )r!   r   r   
siderevmaps      r   r$   z1_annotatecontext._doappendrev.<locals>.<listcomp>  sI       1 &a--@aa:a=1E  r   )r   remover   r   r   r   replacelinesreplacelines_vec)r   r   r1   r=   r   r  siderevsr>   r?   r@   rA   opr#   r   blinesr  s    `             @r   r   z_annotatecontext._doappendrev  s   
	 
	 
	 
	 
	 
!(.  $ RR":: ! !$.r"u$5! ! ! H
 x==8OOD!!! 	( 	(A$HQKKJqMM diikk		<< 
4$,V$4$4 
	@ 
	@ RRbTzz!$$UBB;;;;    *2b5 1   ((B????
	@ 
	@r   c                 B      j          fdfd|D             S )z6(revmap, [(node, linenum)]) -> [(node, linenum, path)]Nc                     j                             |           }|2                                        |                     }|j         | <   |S r   )r   rh   r   r   )nodeidr   r   ri   s     r   _getpathz3_annotatecontext._addpathtoresult.<locals>._getpath  sK    ?&&v..D|v~~f'='=>>*.'Kr   c                 2    g | ]\  }}|| |          fS r   r   )r!   nr   r  s      r   r$   z5_annotatecontext._addpathtoresult.<locals>.<listcomp>  s,    ???1Axx{{#???r   )r   )ri   r   r   r  s   ` `@r   r   z!_annotatecontext._addpathtoresult  sL    >[F	 	 	 	 	 	 @???????r   c                     |d}nA| j                             |                                          }|st          j                    | j        j        |k    rt          j                    dS )z:check if fctx is the master's head last time, raise if notNr   )r   r   r   r   CannotReuseErrorr   r   )ri   r1   r   s      r   r   z%_annotatecontext._checklastmasterhead  si    <EEK''		44E 1.000<%''*,,, ('r   c                 F    | j         j        | j         j        fd}|S )z-> (fctx) -> [fctx]c                 B    t          |           }s
|d d         }|S )N)r*   r   )r,   )r#   r+   rp   ro   s     r   r'   z-_annotatecontext._parentfunc.<locals>.parents  s/    !L111B VIr   )rj   ro   rp   )ri   r'   rp   ro   s     @@r   r   z_annotatecontext._parentfunc  s?     y-i+	 	 	 	 	 	 r   c                 8    | j                             dd          S )N   fastannotates   perfhack)r}   
configboolr   s    r   r   z_annotatecontext._perfhack  s    w!!/;???r   c                 8    t          | j        ||p| j        fi |S r   )rR   r   r   )ri   rJ   r   kwdss       r   r   z_annotatecontext._resolvefctx  s%    49cD,=DIGG$GGGr   T)NFF)FFr   )ru   rv   rw   rx   rl   propertyr   r   r   __del__r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r   r   r   ry   r   r   r   r   r   r   r{   r{      s        	 	 	 
 
 X
   X
! ! ! G: : : = = X=! ! ! !F@P @P @P @PD  .6 6 6 6p? ? ?BJ J J.  $O O O O9 9 9 /@ /@ /@ \/@b@ @ @ @	- 	- 	- 
   
@ @ @H H H H H Hr   r{   c                 Z    | D ]'}	 t          j        |           # t          $ r Y $w xY wdS )zsilent, best-effort unlinkN)r   unlinkOSError)pathsr   s     r   r   r   	  sS      	K 	 	 	D	 s   
((c                   d    e Zd ZdZefdZed             Zed             Zd Z	ed             Z
dS )
pathhelperz9helper for getting paths for lockfile, linelog and revmapc                     t           j                            d|j        t	          |                    | _        || _        d S )Nr&  )r   r   joinrt   rU   _vfspathr)   )ri   r   r   rj   s       r   rl   zpathhelper.__init__  s5    T]IdOO
 
 


r   c                     t           j                            | j        j                            | j                            S r   )r   r   dirnamer)   vfsr5  r6  r   s    r   r8  zpathhelper.dirname  s*    wtz~224=AABBBr   c                 P    | j         j                            | j        dz             S )Ns   .lr)   r9  r5  r6  r   s    r   r~   zpathhelper.linelogpath   !    z~""4=5#8999r   c                 P    t          j        | j        j        | j        dz             S )Ns   .lock)lockmodr   r)   r9  r6  r   s    r   r   zpathhelper.lock$  s    |DJNDMH,DEEEr   c                 P    | j         j                            | j        dz             S )Ns   .mr;  r   s    r   r   zpathhelper.revmappath'  r<  r   N)ru   rv   rw   rx   defaultoptsrl   r+  r8  r~   r   r   r   r   r   r3  r3    s        CC(3     C C XC : : X:F F F : : X: : :r   r3  c              #      K   t          | ||          }t          j        |j                   |j        }|j        }d}	 |                                5  t          | ||||          }|r|                                 |V  ddd           n# 1 swxY w Y   nB# t          $ r5 ||                                 | j
                            d|z              w xY w||                                 dS dS # ||                                 w w xY w)a  context needed to perform (fast) annotate on a file

    an annotatecontext of a single file consists of two structures: the
    linelog and the revmap. this function takes care of locking. only 1
    process is allowed to write that file's linelog and revmap at a time.

    when something goes wrong, this function will assume the linelog and the
    revmap are in a bad state, and remove them from disk.

    use this function in the following way:

        with annotatecontext(...) as actx:
            actx. ....
    Ns+   fastannotate: %s: cache broken and deleted
)r3  r   makedirsr8  r   r~   r   r{   r   	Exceptionr}   r   r   )r   r   rj   r   helperr   r~   actxs           r   annotatecontextrF  ,  sg       dD))FM&.!!!"J$KD[[]] 	 	#D$ZNND JJJ		 	 	 	 	 	 	 	 	 	 	 	 	 	 	
    LLNNNELMMM	 JJLLLLL 4JJLLLL sA   B .B B BB BB C4 ?CC4 4Dc                     | j         }| j        }|j                            ddd          rd}t	          ||          }t          ||||          S )zdlike annotatecontext but get the context from a fctx. convenient when
    used in fctx.annotate
    r&  s   forcefollowT)rY   ro   )r)   _pathr}   r'  rd   rF  )r1   r*   rY   r   r   r   aoptss          r   fctxannotatecontextrJ  Q  sY     :D:Dw/>4@@ (@@@E4ug666r   r*  )FN)TNF)1r   
contextlibr   mercurial.i18nr   mercurial.pycompatr   r   r   mercurial.noder   r   r	   	mercurialr
   r   r   r   r>  r   r   r   r   mercurial.utilsr   r    r   r   r   lrucachefuncr   r,   r8   rC   	revsinglerI   rR   rU   rb   r@  rq   rd   r{   r   r3  contextmanagerrF  rJ  r   r   r   <module>rU     s           				               
         
                        
          
   .9 9 9   Tw011
) ) ) )Z  7 7 7 #l5#455 $ $ $ $ $ $ $ $D lnnH H H H H H H HD  : : : : : : : :4 %0% ! ! ! !H	7 	7 	7 	7 	7 	7r   