
    6hC                   	   S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
SSKrSSKrSSKrSSKJrJr  SSKJr  SSKJr  \R*                  (       a  SSKrSSKJrJrJrJrJrJrJrJrJ r J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(J)r)J*r*J+r+J,r,J-r-J.r.J/r0J1r1  SSK2J3r3J4r4J5r5  S	S
K6J7r7  Sr8\R8                  " 5       r9\9Rt                  r:\9Rv                  r;\9Rx                  r<\9Rz                  r=\9R|                  r?\9R                  SSSS9  \9R                  SSSS9  \9R                  SSSS9  \9R                  SSSS9  \9R                  SSSS9  \9R                  SSSS9  \9R                  SSS	S9  \9R                  SSSS9  \9R                  SSSS9  \9R                  SSSS9  \9R                  SSSS9  SSSSS S!SS"S#S#S$.
rAS%S&S%\" S'5      4/rB\9R                  \ S(5      S) 5       rDSS* jrES+ rFS, rGS- rHS. rI\E" S// \" S05      S1S29S3 5       rJS4 rK\R                  " S55      rM\R                  " S6\R                  5      rOS7 rPS8 rQS9 rR " S: S;5      rS " S< S=5      rT\R                   " S> S?\V5      5       rW\R                   " S@ SA5      5       rX\R                   " SB SC5      5       rYSD rZSE r[SF r\SG r]SH r^SISJSKSL.r_SM r`SN raSO rbSP rcSQ rdSR re       SSS jrfST rgSU rhSV ri\E" SSWSX/ \" SY5      \" SZ5      4S%S[S1\" S\5      4S%S]/ \" S^5      4S%S_/ \" S`5      4SaSbS%\" Sc5      4S%SS\" Sd5      4S%SeS\" Sf5      4/\" Sg5      \;R                  Sh9Si 5       rk\1R                  " / SjQ5      rmSk rn1 SlkroSm rpSnSoSpSqSrSsStSsSu.rqSv rrSw rsSx rtSy ruSz rvS{ rwS| rxS} ryS~ rzS r{S r|\E" SS%SS\" S5      4/\" S5      \;R                  S1S9S 5       r}\E" SS%SS\" S5      4/\" S5      \;R                  Sh9S 5       r~\E" SS%SS\" S5      4S%SS\" S5      4S%SS\" S5      4S%SS\" S5      4S%SS\" S5      4S%SS\" S5      4S%SS\" S5      4S%SS\" S5      4S%SS\" S5      4S%SS\" S5      4SaSbS%\" S5      4SWSXS%\" S5      \" SZ5      4/\" S5      \;R                  S1S9S 5       r\9R{                  SS1S9S 5       r\9R{                  S1 SkS9S 5       r\7GR                  " SSS9S 5       rg)a  simple Phabricator integration (EXPERIMENTAL)

This extension provides a ``phabsend`` command which sends a stack of
changesets to Phabricator, and a ``phabread`` command which prints a stack of
revisions in a format suitable for :hg:`import`, and a ``phabupdate`` command
to update statuses in batch.

A "phabstatus" view for :hg:`show` is also provided; it displays status
information of Phabricator differentials associated with unfinished
changesets.

By default, Phabricator requires ``Test Plan`` which might prevent some
changeset from being sent. The requirement could be disabled by changing
``differential.require-test-plan-field`` config server side.

Config::

    [phabricator]
    # Phabricator URL
    url = https://phab.example.com/

    # Repo callsign. If a repo has a URL https://$HOST/diffusion/FOO, then its
    # callsign is "FOO".
    callsign = FOO

    # curl command to use. If not set (default), use builtin HTTP library to
    # communicate. If set, use the specified curl command. This could be useful
    # if you need to specify advanced options that is not easily supported by
    # the internal library.
    curlcmd = curl --connect-timeout 2 --retry 3 --silent

    # retry failed command N time (default 0). Useful when using the extension
    # over flakly connection.
    #
    # We wait `retry.interval` between each retry, in seconds.
    # (default 1 second).
    retry = 3
    retry.interval = 10

    # the retry option can combine well with the http.timeout one.
    #
    # For example to give up on http request after 20 seconds:
    [http]
    timeout=20

    [auth]
    example.schemes = https
    example.prefix = phab.example.com

    # API token. Get it from https://$HOST/conduit/login/
    example.phabtoken = cli-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    )annotationsN)binshort)_)attr)cmdutilcontextcopiesencodingerror	exthelpergraphmodhttpconnection	localrepo
logcmdutilmatchmdiffobsutilparserpatchphasespycompatrewriteutilscmutilsmartsettagstemplatefilterstemplateutilurlutil)procutil
stringutilurlutil   )shows   ships-with-hg-core   phabricator	   batchsize   default   callsign   curlcmd   debugF   repophid   retry   retry.interval   url   phabsend   confirm
   phabimport   secret   obsoletes   greens   magentas   bolds   magenta dims
   green bolds   yellows   red)
s   phabricator.action.createds   phabricator.action.skippeds   phabricator.action.updated   phabricator.drevs   phabricator.status.abandoneds   phabricator.status.accepteds   phabricator.status.closeds   phabricator.status.needsreviews    phabricator.status.needsrevisions!   phabricator.status.changesplanned    s   test-vcrs   Path to a vcr file. If nonexistent, will record a new vcr transcript, otherwise will mock all http requests using the specified vcr file. (ADVANCED)loadhgrcc                   Sn0 n [         R                  " UR                  S5      5      n	[        R                  " S [        R
                  " U	5      5      nSn[        R                  " 5       n
SU;   a  US   U
S'   SU;   a  US   U
S	'   U
(       a  UR                  XR                  S5      S
9  U " XX4/UQ70 UD6=(       d    U$ ! [         a/    UR                  [        S5      UR                  S5      -  5         N[         a     Nf = f)zBLoad ``.arcconfig`` content into a ui instance on repository open.Fs
   .arcconfigc                \    [        U [        5      (       a  [        R                  " U 5      $ U $ N
isinstancestrr   
unitolocalxs    3/usr/lib/python3/dist-packages/hgext/phabricator.py<lambda>_loadhgrc.<locals>.<lambda>   s#    
1c0B0Bh))!,IIr8   Ts   invalid JSON in %s
s   repository.callsign)r&   r+   s   phabricator.urir&   r1   )source)r   unifromlocalreadr   rapply
json_loads
ValueErrorwarnr   joinOSErrorr    sortdictapplyconfig)origuiwdirvfshgvfsrequirementsargsoptsresult	arcconfig	rawparamscfgs              rC   	_loadhgrcr]      s    FI))',,}*EF	OOI	*
	
  --/C*-67M-N)*Y&(12D(E$%

s<<#>? 	R%===G!  J
)*W\\--HHI s   AC 6D	=	D	D	c                T   ^ ^^^^^^^	 U[         -   mS mS mS m	UUUU UUU	U4S jnU$ )Nc                &   U R                   UR                   :w  d  U R                  UR                  :w  a  g[        R                  R	                  U R
                  5      n[        R                  R	                  UR
                  5      nU H  nXC;  a    gX$   S   nUR                  S5      (       aP  UR                  S5      (       a:  [        R                  " U5      n[        R                  " X4   S   5      nXg:w  a    gMw  X4   S   U:w  d  M    g   g)NFr      {   }T)
urimethodr    urlreqparseqsbody
startswithendswithr   rK   )r1r2r1paramsr2paramskeyvaluer1jsonr2jsons           rC   	hgmatchervcrcommand.<locals>.hgmatcher  s    66RVVryyBII5;;&&rww/;;&&rww/C"M!$E%%%..*>*>!,,U3!,,X]1-=>#  $q!U*  r8   c                T    [         R                  " SSU R                  5      U l        U $ )Ns   cli-[a-z0-9]+s   cli-hahayouwish)resubrf   )requests    rC   sanitiserequest#vcrcommand.<locals>.sanitiserequest  s%    vv2GLL
 r8   c                $    SU S   ;   a  U S   S	 U $ )Nz
set-cookieheaders )responses    rC   sanitiseresponse$vcrcommand.<locals>.sanitiseresponse  s!    8I..#L1r8   c                   >^  U UUU	4S jn[         R                  " USS9nT R                  Ul        T R                  Ul        [	        TTT
TTS9" U5      $ )Nc            
       > UR                  S5      nU(       a  [        R                  " U5      nSS KnUR	                  5          SS KnSS KJn  UR                  ST	T
[        SUR                  4[        SUR                  4/S9nUR                  ST5        UR                  US/S9   T" U 0 UD6sS S S 5        sS S S 5        $ T" U 0 UD6$ ! , (       d  f       O= f S S S 5        M$  ! , (       d  f       N2= f)	Ntest_vcrr   jsonr   httpsconnection)
serializerbefore_record_requestbefore_record_responsecustom_patchesrq   )match_on)popr   fsdecodehgdemandimportdeactivatedvcr	vcr.stubsstubsVCRurlmodVCRHTTPConnectionVCRHTTPSConnectionregister_matcheruse_cassette)rW   kwargsr   cassetter   vcrmodr   fnrq   rw   r}   s          rC   inner+vcrcommand.<locals>.decorate.<locals>.inner!  s    **Z(C#,,S1%#//1(- !**#).=/? !' 0 % 7 7 !' 1 % 8 8(	 % C" ((i@))(k])K!4262 LK3 216 t&v&& LKK3 211s%   A$C'(C0	C'
C	C''
C5   )depthhelpcategoryoptionalrepo)r    checksignature__name____doc__command)r   r   cmd	fullflagsr   rq   namer   rw   r}   specs   `  rC   decoratevcrcommand.<locals>.decorate   s^    !	' !	'F !!%q1{{jj%%
  	r8   )
_VCR_FLAGS)
r   flagsr   r   r   r   r   rq   rw   r}   s
   ` ``` @@@@rC   
vcrcommandr      s.    
"I&
. .` Or8   c                    U R                  SS5      (       a-  U R                  n SU l        U R                  " U0 UD6  X0l        gg! X0l        f = f)zwrite debug output for Phabricator if ``phabricator.debug`` is set

Specifically, this avoids dumping Conduit and HTTP auth chatter that is
printed with the --debug argument.
r&   r-   TN)
configbool	debugflagwrite)rS   msgrX   flags       rC   _debugr   S  sN     
}}^X..||	 BLHHc"T"L /  Ls   A Ac                   ^^ [         R                  " 5       mSUU4S jjmT" SU 5        [        R                  R	                  T5      $ )a  like urlencode, but works with nested parameters.

For example, if params is {'a': ['b', 'c'], 'd': {'e': 'f'}}, it will be
flattened to {'a[0]': 'b', 'a[1]': 'c', 'd[e]': 'f'} and then passed to
urlencode. Note: the encoding is consistent with PHP's http_build_query.
c                  > [        U[        5      (       a  SSS.U   nS n[        U[        S 0R	                  [        U5      5      nUc  UTU '   g U" U5       H#  u  pEU (       a  T" SX4-  U5        M  T" XE5        M%     g )Ns   trues   false)TFc                X    [        U 5       VVs/ s H  u  pSU-  U4PM     snn$ s  snnf )N   %d)	enumerate)lkvs      rC   rD   2urlencodenested.<locals>.process.<locals>.<lambda>n  s$    y|D|tqUQYN|DDs   &c                "    U R                  5       $ r<   )itemsrA   s    rC   rD   r   q  s
    qwwyr8   s   %s[%s])r>   boollistdictgettype)prefixobjlisterr   r   r   
flatparamsprocesss         rC   r    urlencodenested.<locals>.processk  s~    c4   237CD vt%89==d3iH=!$Jvc
I3Q7AM	 #r8   r8   )r   bytes)r    rP   r#   rd   	urlencode)paramsr   r   s    @@rC   urlencodenestedr   b  s;     J" "" C>>##J//r8   c                   U R                  SS5      nU(       d"  [        R                  " [        S5      S-  5      e[        R
                  " X[        R                  " U5      R                  5      nSnU(       a)  Uu  pEU R                  SU-  5        UR                  S5      nU(       d#  [        R                  " [        S5      U4-  5      eX4$ )	zreturn conduit url, token and make sure they exist

Currently read from [auth] config section. In the future, it might
make sense to read from .arcconfig and .arcrc as well.
r&   r1   s   config %s.%s is requiredrF   Ns#   using auth.%s.* for authentication
s	   phabtokens)   Can't find conduit token associated to %s)configr   Abortr   httpconnectionmodreadauthforurir#   r   userdebugr   )rS   r   restokengroupauths         rC   readurltokenr     s     ))NF
+Ckk)*-EE
 	
 
*
*2GKK4D4I4I
JCE

85@A&kk;<vE
 	
 :r8   c                "   [        U 5      u  p4[        R                  " SR                  USU/5      5      R	                  5       u  pVU R                  SU[        R                  " U5      4-  5        UR                  5       nSU0US'   [        R                  " U5      SSS.n[        U5      nU R                  S	S
5      n	U	(       ac  [        R                  " SU	[        R                  " U5      4-  5      u  pU
R!                  U5        U
R#                  5         UR%                  5       nO[&        R(                  " X5      n[*        R,                  R/                  [        R0                  " U5      US9nU R3                  S	S5      S-   nU R5                  [6        SS5      n[9        U5       HA  n [:        R<                  " UR?                  UUS95       nUR%                  5       nSSS5          O   U R                  SW-  5        [        RH                  " S [        RJ                  " [L        RN                  " U5      5      5      nURQ                  S5      (       a,  [S        S5      US   US   4-  n[T        RV                  " U5      eUS   $ ! , (       d  f       N= f! [*        R@                  RB                   aX  nUUS-
  :X  a  e U R                  SUS-   UU4-  5        U R3                  S	S5      n[D        RF                  " U5         SnAGMb  SnAff = f)zEcall Conduit API, params is a dict. return json.loads result, or None   /s   apis   Conduit Call: %s %s
s   token   __conduit__s   jsonr$   )s   paramss   outputr   r&   r,   s   %s -d @- %s)datar/   s   https   timeout)timeoutNs'   Conduit Request failed (try %d/%d): %r
r0   s   Conduit Response: %s
c                \    [        U [        5      (       a  [        R                  " U 5      $ U $ r<   r=   rA   s    rC   rD   callconduit.<locals>.<lambda>  #    Jq#,>,>(%%a(EAEr8   s
   error_codes   Conduit Error (%s): %ss
   error_infos   result),r   r#   r   rN   authinfor   r   bytereprcopyr   r   r   r   r!   popen2
shellquoter   closerI   r   openerr    rd   rv   strurl	configint
configwithfloatrange
contextlibclosingopenurlerrurlerrortimesleeprJ   rK   r   rH   r   r   r   r   )rS   r   r   hostr   r   r   rawdatar   curlcmdsinsoutrf   	urlopenerrv   max_tryr   	try_countrsperrretry_intervalparsedr   s                          rC   callconduitr    s   r"KDKK		4*> ?@IIKMCHH%h.?.?.G(HHI[[]F%F> #''/G
 7#Dii
3GOOgx':':3'?@@
	 			$		yy{MM"/	++%%hooc&:%F,,~x81<--w
;wI+''NN7GN<88:D  (" HH&-.__EH11$78F
 zz-  )*=!=!.
 
 kk#)7 
 ;;'' 	+!+? 1}gs34
 "$n>O!P

>**	+s1   +$JJ J
J	JL6AL		Ls   debugcallconduits   METHODT)r   c                z   [         R                  " U R                  R                  5       5      n[        R
                  " S [        R                  " U5      5      n[        R
                  " S [        XU5      5      n[        R                  " USSSS9nU R                  S[         R                  " U5      -  5        g)	zwcall Conduit API

Call parameters are read from stdin as a JSON blob. Result will be written
to stdout as a JSON blob.
c                \    [        U [        5      (       a  [        R                  " U 5      $ U $ r<   r=   rA   s    rC   rD   "debugcallconduit.<locals>.<lambda>  r   r8   c                \    [        U [        5      (       a  [        R                  " U 5      $ U $ r<   )r>   r   r   rH   rA   s    rC   rD   r    s#    jE.B.B(''*IIr8   Tr   ),z: )	sort_keysindent
separatorss   %s
N)r   rH   finrI   r   rJ   rK   r  r   dumpsr   r@   )rS   repor   r[   r   rY   ss          rC   debugcallconduitr    s     %%bffkkm4I__EI&F
 __IBf%F 	

6T!LAHHWx**1--.r8   c                F   U R                   R                  SS5      nU(       a  U$ U R                   R                  SS5      nU(       d  g[        U R                   SSSU/005      n[        US   5      S	:X  a  gUS   S	   S
   nU R                   R	                  SSU5        U$ )z.given callsign, return repository PHID or Noner&   r.   r+   Ns   diffusion.repository.search   constraintss	   callsigns   datar      phid)rS   r   r  len	setconfig)r  repophidcallsignquerys       rC   getrepophidr    s     ww~~nk:Hww~~nk:H&	,
34E
 5>aW~a )HGGnk8<Or8   s   \AD([1-9][0-9]*)\Zs>   ^Differential Revision:\s*(?P<url>(?:.*)D(?P<id>[1-9][0-9]*))$c                l   U R                  5       nUR                  R                  R                  n0 n[        R
                  " 5       nU GH   nX&   n[        [        R                  " UR                  U/5      5      nU Hs  n	U" U	5      (       d  M  UR                  U	5       HI  n
[        R                  U
5      nU(       d  M!  S[        U5      [        UR                  S5      5      4XV'     O   Mr    M     [         R#                  UR%                  5       5      nU(       d  M  S[        U5      [        UR                  S5      5      4XV'   GM     U(       Ga  UR'                  5        VVVs/ s H  u  poPM	     nnnn[)        UR*                  SSU05      nS nUR-                  5        GHo  u  nu  nnnUR'                  5        Vs/ s H  n[        US   5      U:X  d  M  UPM     nnU VV	s1 s H  nU" UU5        H  oiM     M     nnn	U(       dY  U(       dR  SU-  n[.        R0                  " U UU R2                  S	S	S	S
S9  UR*                  R5                  [7        S5      U-  5        M  S	=nnU(       a  [9        US S9nU" UU5      n[;        UR*                  S[=        U5      [>        R@                  " [C        U5       V	s/ s H  n	[=        U	5      PM     sn	5      4-  5        [E        U5      S:X  a  US   nU(       a  U" U5      (       d  S	nUUU4UU'   GMr     U$ s  snnnf s  snf s  sn	nf s  sn	f )a  find previous nodes that has been sent to Phabricator

return {node: (oldnode, Differential diff, Differential Revision ID)}
for node in nodelist with known previous sent versions, or associated
Differential Revision IDs. ``oldnode`` and ``Differential diff`` could
be ``None``.

Examines commit messages like "Differential Revision:" to get the
association information.

If such commit message line is not found, examines all precursors and their
tags. Tags with format like "D1234" are considered a match and the node
with that tag, and the number after "D" (ex. 1234) will be returned.

The ``old node``, if not None, is guaranteed to be the last diff of
corresponding Differential Revision, and exist in the repo.
r   r$   id   differential.querydiffss   revisionIDsc                R    [        U 5       Vs/ s H  o"U;   d  M
  UPM     sn$ s  snf r<   )getlocalcommits)dprecsetns      rC   getnodes#getoldnodedrevmap.<locals>.getnodes@  s'      /q1B1!'\A1BBBs   	$$s
   revisionID   D%dNTmessager   datelocals=   D%d: local tag removed - does not match Differential history
c                    [        U S   5      $ )N   idint)r  s    rC   rD   #getoldnodedrevmap.<locals>.<lambda>g  s    C%Mr8   )rm   s   %s mapped to old nodes %s
)#
unfiltered	changelogindexhas_noder    rP   r   r   allpredecessorsobsstorenodetags_differentialrevisiontagrer   setr,  r   _differentialrevisiondescresearchdescriptionvaluesr  rS   r   r   tagnullidrM   r   maxr   r   r"   pprintsortedr  )r  nodelistunfir1  rY   	toconfirmnodectx	precnodesr!  r;  mforceprecsdrevdrevsalldiffsr"  newnoder   r  diffs	phprecsettagnameoldnodelastdiffoldnodess                              rC   getoldnodedrevmaprS    s   $ ??D~~##,,HFIj00GH	A{{==+C288=Aq+,c)nc!''!*o*N		 ,   ,223??3DEAq#$c)nc!''$-6H"I	% , 090@0@0BC0B,%0BCGG/.%1H
	C
 09/@+G+eWd#??,,aAm4D0E0M,  
 %*HEq8Aw3Ga3GEIH  4-KK  2 	  "&%Ghu*AB#Hg6GG2g"))VH=M*N=M58=M*NO. x=A%&qkG8G#4#4"G&$7F7OC 0AF M[ D
 IH +Os   +LL& L&-L+L1c                ~   0 nU H  nSX#'   X   n[         R                  UR                  5       5      nU(       a  [        UR	                  S5      5      X#'   MS  U R                  UR                  5       5       H>  n[        R                  U5      nU(       d  M!  [        UR	                  S5      5      X#'     M     M     U$ )zTReturn a dict mapping each rev in `revs` to their Differential Revision
ID or None.
Nr  r$   )	r7  r8  r9  r,  r   r4  rC  r5  r   )r  revsrY   revrD  rF  r;  s          rC   
getdrevmaprW    s     Fi'..s/@Aaggdm,FK==,C*005Aq!!''!*o	 -  Mr8   c                    [         R                  " 5       n[        R                  " UR	                  5       U R                  5       R                  5       UR                  5       SUS9 H  u  pEUR                  U5        M     UR                  5       $ )z:plain-text diff without header (user, commit message, etc)NrX   )	r    stringior   diffuir  p1rC  r   getvalue)basectxrD  diffoptsoutputchunk_labels         rC   getdiffrc    se    ]]_F
GJJL%%'T 	U ??r8   c                  4    \ rS rSrSrSrSrSrSrSr	Sr
S	rS
rg)DiffChangeTypei  r$   r                     r{   N)r   
__module____qualname____firstlineno__ADDCHANGEDELETE	MOVE_AWAY	COPY_AWAY	MOVE_HERE	COPY_HERE	MULTICOPY__static_attributes__r{   r8   rC   re  re    s*    
CFFIIIIIr8   re  c                       \ rS rSrSrSrSrSrg)DiffFileTypei  r$   r   rf  r{   N)r   rl  rm  rn  TEXTIMAGEBINARYrw  r{   r8   rC   ry  ry    s    DEFr8   ry  c                      \ rS rSrSr\R                  " SS9r\R                  " SS9r\R                  " SS9r	\R                  " SS9r
\R                  " SS9r\R                  " SS9r\R                  " SS9rSrg)phabhunki  zGRepresents a Differential hunk, which is owned by a Differential changer   r)   r8   r{   N)r   rl  rm  rn  r   r   ib	oldOffset	oldLength	newOffset	newLengthcorpusaddLinesdelLinesrw  r{   r8   rC   r~  r~    sg    Q"I"I"I"IWWS!Fwwq!Hwwq!Hr8   r~  c                  x   \ rS rSrSr\R                  " SS9r\R                  " SS9r\R                  " \R                  " \
5      S9r\R                  " \R                  " \5      S9r\R                  " \R                  " \5      S9r\R                  " \R                  " \5      S9r\R                  " \R"                  S9r\R                  " \R(                  S9r\R                  " SS9r\R                  " SS9r\R                  " SS9r\R                  " \R                  " \
5      S9rS rS rS rS	 rS
rg)
phabchangei  zRepresents a Differential change, owns Differential hunks and owned by a
Differential diff.  Each one represents one file in a diff.
Nr)   r   c                    [        U R                  R                  5       5       H1  nUR                  SS5      nU R                  U   U R                  U'   M3     g )Ns   new:s   old:)r   metadatakeysreplace)selfrm   newkeys      rC   copynewmetadatatooldphabchange.copynewmetadatatoold  sE    **,-C[['2F$(MM#$6DMM&! .r8   c                     XR                   S'   g Ns   unix:filemode)oldPropertiesr  rn   s     rC   
addoldmodephabchange.addoldmode      /4+,r8   c                     XR                   S'   g r  )newPropertiesr  s     rC   
addnewmodephabchange.addnewmode  r  r8   c                \   [        U[        5      (       d  [        R                  " S5      eU R                  R                  [        R                  " [        R                  " U5      5      5        U =R                  UR                  -  sl
        U =R                  UR                  -  sl        g )Ns'   phabchange.addhunk only takes phabhunks)r>   r~  r   r   hunksappendr   byteskwargsr   asdictr  r  )r  hunks     rC   addhunkphabchange.addhunk  sk    $))++HII

(..t{{4/@AB 	&&r8   r{   )r   rl  rm  rn  r   r   r  currentPatholdPathFactoryr   	awayPathsr   r  r  r  re  rp  r   ry  rz  fileType
commitHashr  r  r  r  r  r  r  rw  r{   r8   rC   r  r    s     ''$'Kggd#GT 23Iwwt||D12HGGDLL$67MGGDLL$67M77>001Dww|001H&Jwwq!Hwwq!HGGDLL./E7
55'r8   r  c                     \ rS rSrSr\R                  " SS9r\R                  " SS9r\R                  " SS9r	\R                  " SS9r
\R                  " SS9r\R                  " SS9r\R                  " S	S9r\R                  " S
S9r\R                  " SS9r\R                  " SS9r\R                  " \R"                  " \5      S9r\R                  " S	S9rS rSrg	)phabdiffi  zURepresents a Differential diff, owns Differential changes.  Corresponds
to a commit.
r8   r)   r   s(   0000000000000000000000000000000000000000s   hgs   defaultNr2   s   nonec                    [        U[        5      (       d  [        R                  " S5      e[        R
                  " [        R                  " U5      5      U R                  UR                  '   g )Ns)   phabdiff.addchange only takes phabchanges)
r>   r  r   r   r   r  r   r  changesr  )r  changes     rC   	addchangephabdiff.addchange  sJ    &*--++JKK+3+?+?KK,
V''(r8   r{   )r   rl  rm  rn  r   r   r  sourceMachine
sourcePathsourceControlBaseRevisionsourceControlPathsourceControlSystembranchbookmarkcreationMethod
lintStatus
unitStatusr  r   r  repositoryPHIDr  rw  r{   r8   rC   r  r    s    
 GGC(M&J $	 :-''%0WWZ(Fwwt$HWW[1N)J)Jggdll401GWWT*N
r8   r  c                &   UR                  5       n[        R                  " U/5      n[        R                  " SSS9n[        [        R                  " XAR                  5       X%US95      u  pxpU
 H  nUu  u  ppnSR                  USS 5      n[        U	5      nUR                  U5        [        R                  " [        R                  " [        R                  " U5      5      5      u  nnnnnU R!                  [#        UUUUUUU5      5        M     g)z'populate the phabchange for a text fileT  gitr	   rY  r8   r$   N)r  r   exactr   r_  nextr   	diffhunksr\  rN   r   extenddiffstatsumdiffstatdatar    	iterlinesr  r~  )pchanger^  rD  fnamer  fmatcherr_  _pfctx_fctxheaderfhunksfhunkr  r  r  r  linesr  shunk_mf_mtr  r  _hbs                           rC   maketextr    s    88:D{{E7#H~~$6H$(jjlCI%!F6 >C;4ye%)$VU,1,=,=t~~e45-
)S(Hc 	
	
 r8   c                   U R                  5       R                  n[        USSU05      nUR                  [	        S5      [	        S5      [        U5      S9 nU Hq  nUR                  5         US   (       a  M  [        US   5      n[        US   5      n[        US	UU[        R                  " U R                  5       Xg 5      S
S.5        Ms     SSS5        g! , (       d  f       g= f)zlupload large binary files as separate chunks.
Phab requests chunking over 8MiB, and splits into 4MiB chunks
s   file.querychunks   filePHIDs   uploading file chunkss   chunks)unittotals   complete	   byteStarts   byteEnds   file.uploadchunks   base64)r  r  r  s   dataEncodingN)r  rS   r  makeprogressr   r  	incrementr,  base64	b64encoder   )fctxfphidrS   chunksprogressra  bstartbends           rC   uploadchunksr  .  s     
B0;2FGF		
"#!I,c&k 
 
	E [!|,-FuZ()D#!&"(#--diik&.FG%.		 
 
 
s   A8C
C%c                   U R                  5       nUR                  nU R                  5       nU R                  5       n[        R
                  " [        R                  " U R                  5       5      R                  5       5      nUUUS.n[        USU5      nUS   nUS   (       an  UR                  [        S5      [        U 5      -  5        U(       d5  U[        R                  " U R                  5       5      S.n	[        USU	5      nO)[!        X5        OUR#                  S[        U 5      -  5        U(       d"  [$        R&                  " S	[        U 5      -  5      eU$ )
z"upload binary files to Phabricator)   names   contentLengths   contentHashs   file.allocater  s   uploads   uploading %s
)r  s   data_base64s   file.uploads   server already has %s
s   Upload of %s failed.)r  rS   pathsizer   bytestrhashlibsha256r   	hexdigestr  r   r   r   r  r  r  r   r   r   )
r  r  rS   r  r  fhashallocateparams	fileallocr  uploadparamss
             rC   
uploadfiler  I  s   99;D	BIIKE99;DW^^DIIK8BBDEE
 N
 B 0.AIk"E
$%d34 & 0 0 =L  NLAE%
+eDk9:kk1E$K?@@Lr8   c                   U(       a  UR                  U5      (       a  UR                  5       U R                  S'   [        R                  " [
        R                  " UR                  5       5      5      u  p4U(       a#  [        R                  " U5      U R                  S'   [        U5      nXPR                  S'   g[        R                  U l        U R                  5         g)zadd the metadata for the previous version of a binary file to the
phabchange for the new version

``oldfctx`` is the previous version of the file; ``fctx`` is the new
version of the file, or None if the file is being removed.
s   old:file:sizes   old:file:mime-types   old:binary-phidN)cmpr  r  	mimetypes
guess_typer   rH   r  r   r  r  ry  rz  r  r  )r  oldfctxr  	mimeguess_encr  s         rC   addoldbinaryr  n  s     488G$$-4\\^)*#..!!',,.1
	 6>6F6F7G23 7#/4+, (,,$$&r8   c                   [         R                  U l        [        U5      nX R                  S'   UR                  5       U R                  S'   [        R                  " [        R                  " UR                  5       5      5      u  p4U(       aQ  [        R                  " U5      nX0R                  S'   UR                  S5      (       a  [         R                  U l        ggg)z)populate the phabchange for a binary files   new:binary-phids   new:file:sizes   new:file:mime-types   image/N)ry  r|  r  r  r  r  r  r  r   rH   r  r   r  rg   r{  )r  r  r  r  r  s        rC   
makebinaryr    s    #**GtE+0'()-G%&**8+@+@+MNOI$$Y/	2;./	**+11G + r8   s   120000s   100755s   100644)   l   xr8   c                     U R                  5       R                  S5        g! [         aF    U R                  5       R                  R                  [        S5      U R                  5       -  5         gf = f)zSdetect non-UTF-8 text files since Phabricator requires them to be marked
as binary
zutf-8Fs0   file %s detected as non-UTF-8, marked as binary
T)r   decodeUnicodeDecodeErrorr  rS   r   r   r  )r  s    rC   notutf8r    sa    		7# 		BCiik	
 s   " AA21A2c                <   U H  n[        XD[        R                  S9nUR                  5       U   nUR	                  [
        UR                  5          5        UR                  5       (       d  [        U5      (       d  [        XQX$5        U R                  U5        M     g)z:add removed files to the phabdiff. Shouldn't include moves)r  r  r   N)r  re  rq  r\  r  gitmoder   isbinaryr  r  r  )pdiffr^  rD  removedr  r  r  s          rC   
addremovedr    s{    >3H3H
 **,u%77==?34  ""gg&6&6Ws2  r8   c                   U H  nX$   nUR                  5       U   n[        XDS9n[        UR                  5          n[        UR                  5          n	X:w  a"  UR	                  U	5        UR                  U5        UR                  5       (       d5  [        U5      (       d%  UR                  5       (       d  [        U5      (       a  [        Xu5        [        XvU5        O[        XqX$5        U R                  U5        M     g)z"add modified files to the phabdiff)r  r  N)r\  r  r  r   r  r  r  r  r  r  r  r  )
r  r^  rD  modifiedr  r  r  r  filemodeoriginalmodes
             rC   addmodifiedr    s    z**,u%>4::<(w}}/#|,x( MMOOt}}!!ww%40Ws2 + r8   c                0   0 n0 n0 nX:w  a%  [         R                  " UR                  5       U5      nU GH  nX(   n	Sn
[        US9n[        U	R                  5          nU(       a  UR                  X5      nO*UnU	R                  5       (       a  U	R                  5       S   nX:g  nU(       GaH  UR                  5       U   n
[        U
R                  5          nXl        X;   aF  [        UU[        R                  U/S9nUXm'   UR                  U5        [        R                  Ul        OX;   aJ  [        R                  Xm   l        Xm   R                  R!                  U5        [        R"                  Ul        OVX;  a  [        U[        R$                  S9nUX]'   OX]   nUR                  R!                  U5        [        R"                  Ul        X:w  a"  UR'                  U5        UR)                  U5        O;UR)                  [        U	R                  5          5        [        R*                  Ul        U	R-                  5       (       d<  [/        U	5      (       d,  U
(       aD  U
R-                  5       (       d  [/        U
5      (       a  [1        X5        U(       a  [3        XU	5        O[5        XX(5        U R7                  U5        GM     UR9                  5        H  u  nnU R7                  U5        M     UR9                  5        H  u  nnU R7                  U5        M     g)z>add file adds to the phabdiff, both new files and copies/movesN)r  r   )r  r  r   r  )r  r   )r
   
pathcopiesr\  r  r  r   r   renamedr  re  rr  removert  r   rv  r  r  ru  rs  r  r  ro  r  r  r  r  r  r  r   )r  r^  rD  addedr  copiedchangesmovedchangesr   r  r  r  r  r
  originalfnamer  r  origpchange_pathcopiedchangemovedchanges                       rC   addaddedr    s    MLD~  s3z/4::<( HHU2M!M||~~ $q 1(jjl=1G"7==?3L+O'( -)'11$g	 /:+}--77.3A3K3K+0+55<<UC-77 5",$18P8P#K 4?M0"/">K%%,,U3-77'""<0""8,wtzz|45)--GL MMOOt}}W--//773C3Cw%Wt4Ws2 A D  -224|%  5*002{$ 3r8   c           	     Z   UR                  5       n[        U5      n[        SU R                  5       R	                  5       -  SUR                  5       -  S9nU R                  5       R                  U5      u  pVpxpn[        X@XU5        [        X@X5        [        X@X5        U(       a  X4l
        [        UR                  S[        R                  " [        R                   " U5      5      5      nU(       d9  X:w  a  [#        S5      X4-  nO[#        S5      U-  n[$        R&                  " U5      eU$ )zcreate a Differential Diffs   %s)r  r  s   differential.creatediffs   cannot create diff for %s::%ss   cannot create diff for %s)r  r  r  r\  hexr  statusr  r  r  r  r  rS   r   r  r   r  r   r   r   )r^  rD  r  r  r  r	  r  r  _d_u_i_cdiffr   s                 rC   
creatediffr"  #  s    88:D4 H"''**,*:*:*<"<szz|#E 07zz|/B/B3/G,HW"" US1.us,'"T[[/0D
 >45FC01C7Ckk#Kr8   c           
        UR                  SUR                  S5      5      nU S   nU S   nUS[        R                  " UR                  5       SUR	                  5       -  UR                  5       UR                  5       UR                  5       R                  5       S.5      S.n[        UR                  5       R                  S	U5        0 nU  H  n[        R                  " UR                  5       5      [        R                  " UR                  5       5      [        UR	                  5       S   5      UR                  5       UR                  5       R                  5       /UR                  5       S
.XgR                  5       '   M     US[        R                  " U5      S.n[        UR                  5       R                  S	U5        g)zwrite metadata to diff so patches could be applied losslessly

``ctxs`` is the list of commits that created the diff, in ascending order.
The list is generally a single commit, but may be several when using
``phabsend --fold``.
s   diffidr*  r      hg:metas   %d %d)   user   date   branch   node   parent)s   diff_idr  r  s   differential.setdiffproperty)   author   authorEmail   time   commit   parentsr(     local:commitsN)r   r   r   r   r'  r  r  r\  r  r  rS   r"   personemailr,  )ctxsr!  diffidr^  tipctxr   commitsrD  s           rC   writediffpropertiesr7  B  s[    XXi%1F1gG"XF  %%!FKKM1!==?"::<++-
F !!#BFKG!((4&,,SXXZ8A'wwy(zz|
	  ! %%g.F
 !!#BFKr8   c           
        U S   nU S   n	UR                  5       n
U(       aG  [        R                  " SSS9nU
R                  5       nX   nX   n[	        XU5      [	        XU5      :g  nOSn/ nU(       a>  [        X5      nUR                  SUS   S.5        U(       a  UR                  S	US.5        OU(       d   eUn[        U U5        U(       a  UR                  S
U/S.5        U(       a  UU-  n[        R                  " 5       n[        U 5       H  u  nnUR                  5       n[        U
R                  SSU05      nS H  nUS   R                  U5      nU(       d  M   US:X  a  UR                  5       UU'   M;  US:X  a  SnSR!                  [#        SUR                  U5      UR                  5       /5      5      UU'   M     M     UR%                  5        H  u  nnUR                  UUS.5        M     SU0nUb  UUS'   [        U
R                  SU5      nU(       dC  ['        U 5      S:X  a  [)        S5      U-  nO[)        S5      X4-  n[*        R,                  " U5      eUU4$ )a  create or update a Differential Revision

If revid is None, create a new Differential Revision, otherwise update
revid. If parentrevphid is not None, set it as a dependency.

If there is a single commit for the new Differential Revision, ``ctxs`` will
be a list of that single context.  Otherwise, it is a list that covers the
range of changes for the differential, where ``ctxs[0]`` is the first change
to include and ``ctxs[-1]`` is the last.

If oldnode is not None, check if the patch content (without commit message
and metadata) has changed before creating another diff.  For a Revision with
a single commit, ``oldbasenode`` and ``oldnode`` have the same value.  For a
Revision covering multiple commits, ``oldbasenode`` corresponds to
``ctxs[0]`` the previous time this Revision was posted, and ``oldnode``
corresponds to ``ctxs[-1]``.

If actions is not None, they will be appended to the transaction.
r$  r   Tr  r  s   updater  s   types   value   comments   parents.sets   differential.parsecommitmessages   corpus)   title   summary   testPlan   fieldsr;  r<     

N   transactions   objectIdentifier   differential.revision.editr$   s   cannot create revision for %ss!   cannot create revision for %s::%s)r  r   r_  r.  rc  r"  r  r7  r    rP   r   r9  r  rS   r   rstriprN   filterr   r  r   r   r   )r3  revidparentrevphidoldbasenoderP  olddiffactionscommentrD  r^  r  r_  rA  oldctx
oldbasectxneednewdifftransactionsr!  fieldsi_ctxdescinfor   r   r   revisionr   s                               rC   createdifferentialrevisionrU  o  s^   : r(C1gG88:D>>dE: &
gH5:
 
 L''i4=IJ* HI
 wd# $@	
  ]]_FT?4!GG7)T9J
 5AY##A&AAv HHJq	h   VD6::a=!((*2M%NOF1I! 5 #2 1a156  |,F&+"#477$A6JHt9>45;C89WNJCkk#T>r8   c                   U Vs/ s H  o"R                  5       PM     nnSSU00n[        U SU5      nUS   nU Vs1 s H  ofS   S   R                  5       iM     nn[        U5      U-
  nU(       a:  [        R                  " [        S5      SR                  [        U5      5      -  5      eU Vs/ s H  ofS	   PM	     sn$ s  snf s  snf s  snf )
zconvert user names to PHIDsr  s	   usernamess   user.searchr  r>  s   usernames   unknown username: %s    r  )lowerr  r6  r   r   r   rN   r?  )	rS   namesr   r  rY   r   entryresolved
unresolveds	            rC   	userphidsr]    s    &+,edZZ\eE,lE23E^U3F '?DCGH4%i -3354HHUh&Jkk%&6*3E)FF
 	
 )--u'N-- - I .s   CC0Cc                   U R                  [        S5      [        S5      [        S5      S.U   SU-  5      nU R                  SU-  S5      n[        R                  " XS5      nU R	                  [        S	5      XTU4-  5        g
)zprint the ``action`` that occurred when posting ``ctx`` for review

This is a utility function for the sending phase of ``phabsend``, which
makes it easier to show a status for all local commits with `--fold``.
   created   skipped   updated)r_  r`  ra  s   phabricator.action.%sr$  r7   r2   s   %s - %s - %s
N)labelr   r   format_changeset_summaryr   )rS   rD  newrevidaction
actiondescdrevdescsummarys          rC   _print_phabsend_actionri    s     ***	
 		
 	!6)J xx)+>?H..rDGHHQ !X7$CCDr8   c                j   [        U R                  S[        R                  " U Vs/ s H  n[	        U5      PM     sn5      -  5         [        U Vs/ s H  oPU   PM	     snU5        gs  snf s  snf ! [        R                  R                   a!    U R                  R                  SU-  5         gf = f)zupdate the local commit list for the ``diff`` associated with ``drevid``

This is a utility function for the amend phase of ``phabsend``, which
converts failures to warning messages.
s   new commits: %s
s"   Failed to update metadata for D%d
N)
r   rS   r"   r>  r   r7  r    r   r   
warnnoi18n)rA  drevidnewnodesr!  r!  rL  s         rC   _amend_diff_propertiesrn    s     z00H1MHq%(H1MNN
L(C(w'](CTJ	 2N D;; L 	AFJKLs)   A)		A3 A. A3 .A3 3<B21B2   r   revs   revisions to sends   REV   amends   update commit messages   reviewers   specify reviewers   blockers   specify blocking reviewers   mr:  s1   add a comment to Revisions with new/updated Diffss#   ask for confirmation before sending   folds%   combine the revisions into one reviews   REV [OPTIONS])r   c                @  ^ [         R                  " U5      n[        U5      UR                  S/ 5      -   n[        R
                  " TU5      nUR                  5         U(       d  [        R                  " [        S5      5      eUR                  S5      (       a  [        R                  " T5        U Vs/ s H  nTU   PM
     nn[        S U 5       5      (       a  [        R                  " [        S5      5      eU4S jnTR                  SU5      n[        U5      S:  a	  U" US	5        TR                  S
U5      n[        U5      S:  a	  U" US5        UR                  S5      n	U	(       a  [        U5      S:X  a  [        R                  " [        S5      5      eUR                  S5      (       d  [        R                  " [        S5      5      eU V
s/ s H&  n
[        R!                  U
R#                  5       5      PM(     nn
[        U Vs1 s H  o(       d  M  UR%                  S5      iM     sn5      S:  a  [        R                  " [        S5      5      e['        TU Vs/ s H  nTU   R)                  5       PM     sn5      nU R+                  SS5      nU[-        UR                  S5      5      -  nU(       a2  [/        TX.5      nU(       d  [        R                  " [        S5      5      e/ nUR                  S/ 5      nUR                  S/ 5      n/ nU(       a%  UR1                  [3        TR4                  U5      5        U(       a0  UR1                  [7        S [3        TR4                  U5      5      5        U(       a  UR9                  SUS.5        / n0 nSnU GH}  n
U	(       a6  U R;                  SU
R=                  5       US   R=                  5       4-  5        O"U R;                  SU
R=                  5       -  5        UR                  U
R)                  5       S5      u  nnnUUUnnnU	(       a'  UR                  US   R)                  5       S5      u  nnnUU
R)                  5       :w  d  UR                  S5      (       Ga  [?        U	(       a  UOU
/UUUUUUUR                  S5      5      u  nnU	(       a  U H  n
UUU
R)                  5       '   M     OUUU
R)                  5       '   [A        US   S    5      n US   S!   n!U(       a  S"n"OS#n"U	(       du  [        R!                  U
R#                  5       5      nU(       a  [A        UR%                  S$5      5      U :w  a-  S%U -  n#[B        RD                  " TU#U
R)                  5       SSSS&S'9  O#[G        TR4                  S(U-  5      S)   S!   n!Un S*n"UR9                  U 5        U!nU	(       aF  U H>  n$UR                  U$R)                  5       S5      S+   (       a  S"n"OS#n"[I        U U$U U"5        M@       O[I        X
U U"5        GM     UR                  S5      (       Ga  TRK                  5       n%[M        U S,S-U05      n&TRO                  5          TRQ                  5          TRS                  S5         TRU                  S.UU5       V$s/ s H  n$U$PM     n'n$U%S/   R)                  5       n(0 n)/ n*US)   n+[W        U5       GH  u  n,nU%U   n-U	(       d  UU,   n+U& V.s/ s H  n.[A        U.S    5      U+:X  d  M  U.PM     sn.S)   n/[Y        U/U-U	5      n0U-R#                  5       U0:w  dE  U-R[                  5       R)                  5       U);   d#  U-R]                  5       R)                  5       U);   Ga  U-R_                  5       [`        Rb                  :X  a3  U Re                  [        S05      [f        Rh                  " U-5      -  5        M  U)R                  U-R[                  5       R)                  5       U-R[                  5       45      S)   U)R                  U-R]                  5       R)                  5       U-R]                  5       45      S)   /n1[j        Rl                  " TU0U)5      n0[n        Rp                  " TU-U1U0U-Rs                  5       U-Ru                  5       U-Rw                  5       S19n2U2Ry                  5       n3U3/U)U-R)                  5       '   U	(       a  U*R9                  U35        GM  [{        U%U+U3/UU-R)                  5          5        S%U+-  n#U#TRC                  5       ;   a'  [B        RD                  " TU#TR|                  SSSS&S'9  GMx  GM{  U	(       d  GM  U*R9                  U-R)                  5       5        GM     U	(       ag  U*(       a`  UW-R)                  5          nW(       a  [U        U*5      [        U5      :w  a  [        U S2U+-  5        [{        U%U+U*U5        O#[        U S3U+-  5        OU	(       a  [        U S45        U' GH~  n-U)R                  U-R[                  5       R)                  5       U-R[                  5       45      S)   U)R                  U-R]                  5       R)                  5       U-R]                  5       45      S)   /n1[n        Rp                  " TU-U1[j        Rl                  " TU-R#                  5       U)5      U-Rs                  5       U-Ru                  5       U-Rw                  5       S19n2U2Ry                  5       n3U3U-R)                  5       :w  aH  U3/U)U-R)                  5       '   [        U S5[        U-R)                  5       5      [        U35      4-  5        GMX  [        U S6[        U-R)                  5       5      -  5        GM     [f        R                  " TU)SS&S79  U(U);   a  U%R                  U)U(   S)   5        SSS5        SSS5        SSS5        ggs  snf s  sn
f s  snf s  snf s  sn$f s  sn.f ! , (       d  f       N>= f! , (       d  f       NG= f! , (       d  f       g= f)8a  upload changesets to Phabricator

If there are multiple revisions specified, they will be send as a stack
with a linear dependencies relationship using the order specified by the
revset.

For the first time uploading changesets, local tags will be created to
maintain the association. After the first time, phabsend will check
obsstore and tags information so it can figure out whether to update an
existing Differential Revision, or create a new one.

If --amend is set, update commit messages so they have the
``Differential Revision`` URL, remove related tags. This is similar to what
arcanist will do, and is more desired in author-push workflows. Otherwise,
use local tags to record the ``Differential Revision`` association.

The --confirm option lets you confirm changesets before sending them. You
can also add following to your configuration file to make it default
behaviour::

    [phabsend]
    confirm = true

By default, a separate review will be created for each commit that is
selected, and will have the same parent/child relationship in Phabricator.
If ``--fold`` is set, multiple commits are rolled up into a single review
as if diffed from the parent of the first revision to the last.  The commit
messages are concatenated in the summary field on Phabricator.

phabsend will check obsstore and the above association to decide whether to
update an existing Differential Revision, or create a new one.
rp  s(   phabsend requires at least one changesetrq  c              3  R   #    U  H  oR                  5       (       d  M  Uv   M     g 7fr<   )obsolete).0cs     rC   	<genexpr>phabsend.<locals>.<genexpr>^  s     
+djjl11ds   '	's,   obsolete commits cannot be posted for reviewc                   > U  Vs/ s H  nTU   R                  5       PM     nn[        R                  " [        S5      U[        R
                  " TU5      4-  [        S5      S9es  snf )Ns)   cannot phabsend multiple %s revisions: %ss&   the revisions must form a linear chain)hint)rC  r   r   r   r   nodesummaries)rU  revtyperbadnodesr  s       rC   _fail_nonlinear_revs&phabsend.<locals>._fail_nonlinear_revse  sc    ,01DqDGLLND1kk:;--dH=>?<=
 	
 2s   A&s
   heads(%ld)r$   s   heads
   roots(%ld)s   rootru  s   cannot fold a single revisions   cannot fold with --no-amendr   s0   cannot fold revisions with different DREV valuesr2   r3   s   phabsend cancelledrr  rs  c                    SU -  $ )Ns   blocking(%s)r{   )phids    rC   rD   phabsend.<locals>.<lambda>  s	    _t3r8   s   reviewers.addr9  Ns   sending rev %d::%d
r$  s   sending rev %d
NNNr:  s   objectr*  r  ra  r_  r  r$  Tr%  r   r   r`  r      differential.query   idss4   (%ld::) - (%ld) - unstable() - obsolete() - public()   .s'   warning: not updating public commit %s
)parentstextr   r'  extras#   updating local commit list for D%d
s0   local commit list for D%d is already up-to-date
s   no newnodes to update
s   restabilizing %s as %s
s   not restabilizing unchanged %s
)fixphase)Dr   r  r   r   r   revrangesortr   r   r   r   checkunfinishedanyrU  r  r7  r8  r9  r   rS  rC  r   r   _confirmbeforesendr  r]  rS   mapr  r   rV  rU  r,  r   r;  	querydrevri  r.  r  wlocklocktransactionr6  r   get_amended_descr\  p2phaser   publicrM   r   formatchangeidr   update_hash_refsr	   metadataonlyctxr   r'  r  commitrn  r<  r  r   r   cleanupnodes
setparents)4rS   r  rU  rX   rV  r3  r  headsrootsfoldrD  drevmatchersrF  r  oldmapconfirm	confirmedrI  	reviewersblockersphidsdrevidsdiffmaplastrevphidrP  rH  rE  rG  oldbasediffoldbaserevidrT  r!  rd  
newrevphidre  rO  rz  rA  rJ  restackwnodemappingrm  rl  rP  oldr  rI  newdescr  newrL  s4    `                                                  rC   phabsendr    s$
   h %D:,,DtT*DIIKkk!GHIIxx%!%&#DID&

+d
+++kk!KLMM
 IImT*E
5zA~UG,IImT*E
5zA~UG,88GDt9>++a @ABB xx!!++a >?@@ 
 (..s/@A 	 
 :1:;a?++EF 
 td%Cdd1gllnd%CDFmmK4GtDHHZ())G&tT:	++a 5677Gb)Ixx
B'HEYtww	233$''8,	
 !1UCDGG KHH,	48<<>/JJKHH(377945 #)**SXXZ9K"L%18'5,[5;ZZR!362Kl chhj DHHX$6$673%$	NHd C*.GCHHJ'   '+
#8I.u56H!),W5J## /66s7HIC.(:$x/GHH
 $!!" #477EEM:1=gFJHFx  ::affh(:;A>'F'F&r1h?  r&9W \ xx B 57HIZZ\499;(8(8(E KA    JOO%EGHQZF#D/33i$QZF#(D5aC%MV,C5DQG*4d; OO%0vvx}}'1vvx}}'1yy{fmm3IJ%44S9: !CFFHMMOcffh[A!DCFFHMMOcffh[A!DG *::G
 "11 '$ XXZ XXZ!iikC "jjlG+2)GCHHJ' !0 *fwi1D
 %voG$))+- # KK$(!%!%"& . T
 OOCHHJ/M *T sxxz* #h-?73K"K2FOP*44HL !
 r56
 KK#&&(=a@KK#&&(=a@ --#$55coo/ ))+
 **, chhj(+2)GCHHJ'3 ,eGn=> ;eCHHJ>OO; D   wdKq 12m )F;\\ I 'Z
 ; &Dh$ E- )F(E;;\\s   3o-o
oo"o
$p5o>o-o#
)Ao-.o(o(Io-Io-5o>=p#
o--
o;7o>>
p	p
p))r&  s   User)r'  s   Date)r(  s   Branch)r)  s   Node ID)r*  s   Parent c           
        [        U R                  5      u  p4U R                  nU H  nX   nUR                  UR                  5       S5      u  pn
U
(       a  UR	                  SU
-  S5      nOUR	                  [        S5      S5      nUR                  [        S5      U[        R                  " XWS5      4-  5        M     UR                  [        S5      U-  5      (       a  gg	)
Nr  r$  r7   s   NEWs   %s - %s
r2   s1   Send the above changes to %s (Y/n)?$$ &Yes $$ &NoFT)
r   rS   r   rC  rb  r   r   r   rc  promptchoice)r  rU  r  r   r   rS   rV  rD  rP  rH  rl  rg  s               rC   r  r    s    dgg&JC	Bi#)::chhj:L#M &xx1DEHxx&	+>?H
lO00+F	
   
	
>?#E  r8   >      closed   accepted	   abandoned   needsreview   needsrevision   changesplannedc                H    U S   R                  SS5      R                  5       $ )z7get normalized status name from a Differential Revision
   statusNamerW  r8   )r  rX  )rI  s    rC   _getstatusnamer    s#    &&tS17799r8   )r(   N)   groupr$      )NN)rk  N)	   ancestorsrk  NN)rh  NN)   and_rh  N)rg  NN)   addrg  N)rg  NN)   subrg  N)r   NNNN)r      symbolNNN)   (   :   &   +   -r  r     endc           
   #  X  ^#    [        U 5      nSmSn[        U 5      nX#:  a  SR                  [        R                  " U4S j[
        R                  " XS  5      5      5      nU(       a  SXB4v   U[        U5      -  nOXUS-    S:w  a  XUS-    S U4v   US-  nX#:  a  M  SS U4v   g 7f)	Ns   ():+-& r   r8   c                   > U T;  $ r<   r{   )chspecials    rC   rD   _tokenize.<locals>.<lambda>  s
    2W,r8   r  r$   rW  r  )
memoryviewr  rN   	itertools	takewhiler   iterbytestr)r  viewposlengthsymbolr  s        @rC   	_tokenizer    s     dDG
CYF
,,h.B.B4:.N

 f**3v;C#'"d*#'*D#661HC , 4
s   BB*"B*c                    [         R                   " [        5      R                  [        U 5      5      u  pU[	        U 5      :w  a  [
        R                  " SU5      eU$ )Ns   invalid token)r   	_elementsparser  r  r   
ParseError)r  treer  s      rC   _parser    sF    i(..y?ID
c$i/55Kr8   c                    U R                  S5      (       a&  U SS R                  5       (       a  [        U SS 5      $ U R                  5       (       a  [        U 5      $ g)z<str -> int or None, ex. 'D45' -> 45; '12' -> 12; 'x' -> None   Dr$   N)rg   isdigitr,  )r  s    rC   
_parsedrevr    sS    6!":#5#5#7#76!":~~6{ r8   c                   [        5       n[        5       nU S   nUS:X  a)  [        U S   5      nU(       a  UR                  U5        X4$ US:X  aF  [        U S   5      u  pEUR	                  U5        UR	                  U5        UR	                  U5        X4$ U SS  H2  n[        U5      u  pEUR	                  U5        UR	                  U5        M4     X4$ )z9return ({single-drev-id}, {ancestor-drev-id}) to prefetchr   r  r$   r  N)r6  r  add_prefetchdrevsupdate)r  rJ  ancestordrevsopr  ats          rC   r  r    s    EEEM	aB	YtAwIIaL  
|	d1g&QQQ 	 abA!!$DALLO  #  r8   c           
       ^ ^^	^
^^ U
U 4S jmU4S jm	0 m
[        U5      n[        U5      u  p4T R                  SS5      n[        U5      nU H-  nUR	                  [        [        SXu-
  5      US-   5      5        M/     U(       a  T" S[        U5      05        [        [        T	" [        U5      5      5      [        U5      -  5      mU	U
UU4S jmT" U5       Vs/ s H  nT
U   PM
     sn$ s  snf )a^  return a list of "Differential Revision" dicts

spec is a string using a simple query language, see docstring in phabread
for details.

A "Differential Revision dict" looks like:

    {
        "activeDiffPHID": "PHID-DIFF-xoqnjkobbm6k4dk6hi72",
        "authorPHID": "PHID-USER-tv3ohwc4v4jeu34otlye",
        "auxiliary": {
          "phabricator:depends-on": [
            "PHID-DREV-gbapp366kutjebt7agcd"
          ]
          "phabricator:projects": [],
        },
        "branch": "default",
        "ccs": [],
        "commits": [],
        "dateCreated": "1499181406",
        "dateModified": "1499182103",
        "diffs": [
          "3",
          "4",
        ],
        "hashes": [],
        "id": "2",
        "lineCount": "2",
        "phid": "PHID-DREV-672qvysjcczopag46qty",
        "properties": {},
        "repositoryPHID": "PHID-REPO-hub2hx62ieuqeheznasv",
        "reviewers": [],
        "sourcePath": null
        "status": "0",
        "statusName": "Needs Review",
        "summary": "",
        "testPlan": "",
        "title": "example",
        "uri": "https://phab.example.com/D2",
    }
c                >  > U R                  S5      =(       d    U R                  S5      =(       d    S/S   nUT;   a  TU   $ [        TSU 5      nU H  nUTUS   '   UT[        US   5      '   M     UT;  a"  [        R                  " [        S5      U -  5      eTU   $ )	zparams -> single drev or Noner     phidsNr   r  r  r*  s#   cannot get Differential Revision %r)r   r  r,  r   r   r   )r   rm   rJ  rI  
prefetchedrS   s       rC   fetchquerydrev.<locals>.fetchK  s    zz&!CVZZ%9CdVQG*c?"B 5v>D(,JtG}%+/Js4;'(  j ++89FB  #r8   c                  > [        5       n/ nU  Vs/ s H  nSU/0PM
     nnU(       a  UR                  5       nT
" U5      nUS   U;   a  M*  UR                  US   5        UR                  [	        US   5      5        UR                  S0 5      nUR                  S/ 5      nU H  n	UR                  SU	/05        M     U(       a  M  UR                  5         [        R                  " U5      $ s  snf )z6given a top, get a stack from the bottom, [id] -> [id]r  r*  s	   auxiliarys   phabricator:depends-onr  )	r6  r   r  r  r,  r   reverser   baseset)
topdrevidsvisitedrY   rP  queuer   rI  	auxiliarydependsr  r  s             rC   getstackquerydrev.<locals>.getstack[  s    %(23
1&1#
3YY[F=DE{g%KKU$MM#d5k*+r2Imm$=rBGh/0   e 	'' 4s   C.r&   r'   r$   r  c                  > U S   nUS:X  a  [        U S   5      nU(       a  [        R                  " U/5      $ U S   [        ;   a?  T Vs/ s H  n[	        TU   5      U S   :X  d  M  UPM     nn[        R                  " U5      $ [
        R                  " [        S5      U S   -  5      eUS;   aN  [        U 5      S:X  d   e[        [        [        R                  " U5      5      " T" U S   5      T" U S   5      5      $ US:X  a  T" U S   5      $ US	:X  a  T" T" U S   5      5      $ [
        R                  " S
U -  5      es  snf )Nr   r  r$   s   unknown symbol: %s>   r  r  r  rf  r   r  r  s   illegal tree: %r)r  r   r  _knownstatusnamesr  r   r   r   r  getattroperatorr   sysstrProgrammingError)	r  r  rI  r  rJ  r  r  valididswalks	        rC   r
  querydrev.<locals>.walk  sE   !W?d1g&D''//a-- &%%jm4Q? %  
  ''..kk!$9":T!W"DEE,,t9>!>8X__R%89T!WtDG}  8^Q= <DaM**(()<t)CDD%s   
D?'D?)	r  r  r   r6  r  r   r=  r   r?  )rS   r   r  rJ  r  	batchsizetofetchr  r  r  r  r	  r
  s   `       @@@@@rC   r  r    s    \ (( J$<D)$/E ^\:I %jGuSAM2AE:; vtG}%&c(4#6783u:EFHE E6 $(:.:aJqM:...s   C,c           	         U S   nU S   R                  5       nU S   R                  5       nU(       a  SU-  nSU S   -  nSR                  [        SXX4/5      5      $ )	zget description (commit message) from "Differential Revision"

This is similar to differential.getcommitmessage API. But we only care
about limited fields: title, summary, test plan, and URL.
r;  r<  r=  s   Test Plan:
%s   Differential Revision: %s   urir?  N)rC  rN   rD  )rI  titlerh  testplanrb   s        rC   getdescfromdrevr    si     NE:%%'GK '')H$x/
&f
5C<<teh%DEFFr8   c                   U(       d  [        U 5      $ SU S   -  n[        R                  UR                  5       5      nU(       d!  SR	                  UR                  5       U/5      $ [        R                  X1R                  5       5      $ )a!  similar to ``getdescfromdrev``, but supports a folded series of commits

This is used when determining if an individual commit needs to have its
message amended after posting it for review.  The determination is made for
each individual commit, even when they were folded into one review.
r  r  r?  )r  r7  r8  r9  rN   ru   )rI  rD  foldedrb   rF  s        rC   r  r    so     t$$
&f
5C 	$**3??+<=A||S__.455&**30ABBr8   c                B   U R                  S5      =(       d    0 nUR                  S5      =(       d    0 n[        U5      S:  a*  UR                  5        Vs1 s H  n[        U5      iM     sn$ [        [	        U 5      R                  SS5      5      =(       d    S1$ s  snf )zcget the set of local commits from a diff object

See ``getdiffmeta()`` for an example diff object.

   propertiesr0  r$   r)  r8   N)r   r  r  r   getdiffmeta)r!  propsr6  rz  s       rC   r  r    s    
 HH]#)rEii()/RG
7|a '/1A// D!%%gs34<==	 0s   Bc                   U R                  S5      =(       d    0 nUR                  S5      nU(       d  UR                  S5      (       a  [        US   R                  5       5      S   n0 nSU;   a  SU;   a  SUS   US   4-  US'   S	U;   a  S
[        US	   5      -  US'   SU;   a  US   US'   UR                  SUR                  S5      5      nU(       a  XBS'   [	        UR                  SS5      5      S:  a  US   S   US'   O0 nSU;  a  SU ;   a  SU S   -  US'   SU;  a  U R                  S5      (       a  U S   US'   SU;  a  U R                  S5      (       a  U S   US'   U$ )aI  get commit metadata (date, node, user, p1) from a diff object

The metadata could be "hg:meta", sent by phabsend, like:

    "properties": {
      "hg:meta": {
        "branch": "default",
        "date": "1499571514 25200",
        "node": "98c08acae292b2faf60a279b4189beb6cff1414d",
        "user": "Foo Bar <foo@example.com>",
        "parent": "6d0abad76b30e4724a37ab8721d630394070fe16"
      }
    }

Or converted from "local:commits", sent by "arc", like:

    "properties": {
      "local:commits": {
        "98c08acae292b2faf60a279b4189beb6cff1414d": {
          "author": "Foo Bar",
          "authorEmail": "foo@example.com"
          "branch": "default",
          "commit": "98c08acae292b2faf60a279b4189beb6cff1414d",
          "local": "1000",
          "message": "...",
          "parents": ["6d0abad76b30e4724a37ab8721d630394070fe16"],
          "rev": "98c08acae292b2faf60a279b4189beb6cff1414d",
          "summary": "...",
          "tag": "",
          "time": 1499546314,
        }
      }
    }

Note: metadata extracted from "local:commits" will lose time zone
information.
r  r%  r0  r   r+  r,  s   %s <%s>r&  r-  s   %d 0r'  r(  r.  rp  r)  r/  r{   r$   r*  s   dateCreateds   %s 0s   sourceControlBaseRevision)r   r?  r:  r,  r  )r!  r  metar  rC  s        rC   r  r    s   L HH]#)rE99Z D99%&&E"23::<=a@FDF"~'? *9%>*. !W &  '#fWo*> >WF""("3Y::iF);<D $W6::j"-.!3"("4Q"7YDd~5$~"66W)!4!4y/Y*F!G!G;<YKr8   c                   ^ [        U5      S:  a?  U4S jnSR                  [        R                  " X25      5      n[	        X5      nU(       a  U$ [
        R                  " [        S5      5      e)zconvert user supplied DREVSPECs into "Differential Revision" dicts

See ``hg help phabread`` for how to specify each DREVSPEC.
r   c                &   > T(       a  SU -  n SU -  $ )Ns   :(%s)s   (%s)r{   )r  stacks    rC   _formatspec_getdrevs.<locals>._formatspec#  s    qLQ;r8   r  s   empty DREVSPEC set)r  rN   r   maplistr  r   r   r   )rS   r  specsr  r   rJ  s    `    rC   	_getdrevsr#    sW    
 5zA~	
 yy))+=>"#L
++a-.
//r8   c           
        [        U Vs1 s H  n[        S US    5       5      iM     sn5      n[        U SSU05      n/ nU H  nU R                  [	        S5      US   -  5        [        S US    5       5      n[        U SS	U05      n[        U5      n	S
n
[        USU-     5      n[        R                  5        H  nX;   d  M
  U
S[        U   X   4-  -  n
M     SXU4-  nUR                  US   U45        M     U" U5        gs  snf )a  generate plain-text patch readable by 'hg import'

write takes a list of (DREV, bytes), where DREV is the differential number
(as bytes, without the "D" prefix) and the bytes are the text of a patch
to be imported. drevs is what "querydrev" returns, results of
"differential.query".
c              3  8   #    U  H  n[        U5      v   M     g 7fr<   r+  ry  r   s     rC   r{  readpatch.<locals>.<genexpr>:  s     9.Q#a&&.   s   diffsr  r  s   reading D%s
r*  c              3  8   #    U  H  n[        U5      v   M     g 7fr<   r+  r&  s     rC   r{  r'  C  s     4^SVV^r(  s   differential.getrawdiffs   diffIDs   # HG changeset patch
r   s   # %s %s
s   %s%s
%sN)
r?  r=  r  noter   r  r  _metanamemapr  r  )rS   rJ  r   rI  diffidsrM  patchesr4  rf   rR  r  r  r   contents                 rC   	readpatchr/  1  s    eLedc9$x.99eLMG68IJEG 
"#d5k124T(^4429Iv;NOt$*
 501""$Ay,,q/47)CCC % t 44UW-.# ( 
'N5 Ms   Ds   phabread   stacks   read dependenciess   DREVSPEC... [OPTIONS]r   c                   ^  [         R                  " U5      n[        T UR                  S5      U5      nU 4S jn[	        T XE5        g)a  print patches from Phabricator suitable for importing

DREVSPEC could be a Differential Revision identity, like ``D123``, or just
the number ``123``. It could also have common operators like ``+``, ``-``,
``&``, ``(``, ``)`` for complex queries. Prefix ``:`` could be used to
select a stack.  If multiple DREVSPEC values are given, the result is the
union of each individually evaluated value.  No attempt is currently made
to reorder the values to run from parent to child.

``abandoned``, ``accepted``, ``closed``, ``needsreview``, ``needsrevision``
could be used to filter patches by status. For performance reason, they
only represent a subset of non-status selections and cannot be used alone.

For example, ``:D6+8-(2+D4)`` selects a stack up to D6, plus D8 and exclude
D2 and D4. ``:D9 & needsreview`` selects "Needs Review" revisions in a
stack up to D9.

If --stack is given, follow dependencies information and read all patches.
It is equivalent to the ``:`` operator.
r0  c                >   > U  H  u  pTR                  U5        M     g r<   )r   )r-  rI  r.  rS   s      rC   _writephabread.<locals>._writev  s    $MDHHW %r8   N)r   r  r#  r   r/  )rS   r  r"  rX   rJ  r3  s   `     rC   phabreadr5  W  s=    8 %Db$((8,e4E b% r8   s   import dependencies as wellc                B  ^ ^^ [         R                  " T5      mSTS'   STS'   STS'   STS'   T R                  S	S
5      (       a  STS
'   T R                  S	S5      (       a  STS'   UUU 4S jn[        T TR	                  S5      U5      n[        TR                  XT5        g)zimport patches from Phabricator for the specified Differential Revisions

The patches are read and applied starting at the parent of the working
directory.

See ``hg help phabread`` for how to specify DREVSPEC.
Ts   bypassr$   s   stripr8   s   prefixFr6   r4   r5   c                  > T	S    R                  5       nT	R                  5          T	R                  5          T	R                  S5         U  H  u  p#T
R	                  [        S5      U-  5        [        R                  " T
[        R                  " U5      5       n[        R                  " T
T	UUT/ S 5      u  pVnU(       d"  [        R                  " [        S5      U-  5      eT
R                  US-   5        T	U   /nS S S 5        M     S S S 5        S S S 5        S S S 5        g ! , (       d  f       M  = f! , (       d  f       N1= f! , (       d  f       N:= f! , (       d  f       g = f)Nr4   s   applying patch from D%s
s   D%s: no diffs found   
)r  r  r  r  r  r   r   extractioBytesIOr   tryimportoner   r   r*  )r-  r  rI  contents	patchdatar   rC  rejrX   r  rS   s           rC   r3  phabimport.<locals>._write  s   t*$$&ZZ\499;(8(8(G")		!89D@A]]2rzz(';<	%,%9%9!&NCs  #kk!,B*Cd*JKKGGC%K(#DzlG =< #* )H;\\ =<	 )H(G;;\\sT   EEAD2A#D ;D2EE 
D/*D22
E <E
E	E
E"r0  N)r   r  r   r#  r   r/  rS   )rS   r  r"  rX   r3  rJ  s   `` `  rC   
phabimportrA  }  s     %D
 DO DNDOD	}}]I..Y	}}]K00 [+0 b$((8,e4Edggu%r8   s
   phabupdate   accepts   accept revisions   rejects   reject revisions   request-reviews   request review on revisions   abandons   abandon revisions   reclaims   reclaim revisions   closes   close revisions   reopens   reopen revisions   plan-changess   plan changes for revisions   resigns#   resign as a reviewer from revisions
   commandeers   commandeer revisionss   comment on the last revisions   local revision to updates"   [DREVSPEC...| -r REV...] [OPTIONS]c           	        [         R                  " U5      n/ SQnU Vs/ s H,  oSR                  UR                  SS5      5      (       d  M*  UPM.     nn[	        U5      S:  a1  [
        R                  " [        S5      SR                  U5      -  5      e/ nU H  nUR                  USS.5        M     UR                  S	5      n	U	(       a  U(       d  [
        R                  " [        S
5      5      eU(       a  [
        R                  " [        S5      5      e[        U[        R                  " X/5      5      n
/ n/ nU
R                  5        H1  u  pUc  UR                  X   5        M  UR                  SU-  5        M3     U(       a6  [
        R                  " [        S5      [        R                   " X5      -  5      e[#        XR                  S5      U5      n[%        U5       Hc  u  nnUS-   [	        U5      :X  a-  UR                  S5      (       a  UR                  SUS   S.5        U(       d  MN  US   US.n['        U SU5        Me     gs  snf )zjupdate Differential Revision in batch

DREVSPEC selects revisions. See :hg:`help phabread` for its usage.
)
rE  rB  rG  rK  rI  rF  rC  rH  rD  rJ  r     _r$   s   %s cannot be used togethers   , Tr9  rp  s   --rev requires a repositorys&   cannot specify both DREVSPEC and --revNr$  s-   selected revisions without a Differential: %sr0  r:  r  )rA  r@  rB  )r   r  r   r  r  r   r   r   rN   r  
InputErrorrW  r   r  r   r   r  r#  r   r  )rS   r  r"  rX   rN  r!  r   rI  frU  drevmapunknownr  r  rJ  rP  rI  r   s                     rC   
phabupdaterR    s   2 %DL %H141F(GQEH
5zA~kk!9:UZZ=NNOOGd34  88FD""1%C#DEE""1%N#OPPT:#6#6tV#DEMMODAytw'VaZ(	 $
 ""BC''67 
 b((8,e4EU#4q5CJ488J#7#7NNZ4
;KLM7%)']!(F 96B $? Is   )IIs
   phabreview   ctx)requiresc                Z   U R                   " US5      n[        R                  UR                  5       5      nU(       a:  [        R
                  " UR                  S5      SUR                  S5      -  S.5      $ UR                  5       R                  UR                  5       5      nU H  n[        R                  U5      (       d  M  UR                  5       R                  R                  SS5      nUR                  S5      (       d  US-  nXe-  n[        R
                  " UUS.5      s  $    g	)
z]:phabreview: Object describing the review for this changeset.
Has attributes `url` and `id`.
rS  r   s   D%sr  )r1   r*  r&   r1   r   N)resourcer7  r8  r9  r   
hybriddictr   r  r4  rC  r5  r   rS   r   rh   )r	   r  rD  rF  r   r  r   s          rC   template_reviewrX  
	  s    
 

7F
+C#**3??+<=A&&-
 	
 xxz""388:.A)//22hhjmm**>6B||D))4KC#.. #    r8   s
   phabstatus>      uirS     repoc                n   U R                   " US5      nU R                   " US5      nU R                   " US5      nUR                  5       n [        X5/5      U   n[	        USSU/05      nU H6  n[        US   5      U:X  d  M  [        R                  " US   US	   S
.5      s  $    g! [         a     gf = f)z8:phabstatus: String. Status of Phabricator differential.rS  rZ  rY  Nr  r  r*  r  r  )r1   s   status)rV  rV  rW  KeyErrorr  r,  r   rW  )	r	   r  rD  r  rS   rV  rl  rJ  rI  s	            rC   template_statusr]  *	  s     

7F
+CGW-D			'5	)B
'')CD%(- 1FVH3EFEtE{v%** L#M2     s   B' '
B43B4s   work)	csettopicc           	       ^ ^ UR                  S5      n[        X5      n/ [        5       0 pvnUR                  5        HU  u  pU	b<  UR	                  U	5        UR                  U	[        5       5      R	                  U5        MD  UR                  U5        MW     [        T SS[        U5      05      n
0 mU
 H   nU[        US   5          H  nUTU'   M
     M"     UU 4S jnU[        R                  " U5      -  n[        R                  " X5      nT R                  SSS	5        Xl        [         R"                  " X5      n[$        R&                  " T UUU[        R(                  S
U0S9  g)z Phabricator differiential statuszsort(_underway(), topo)Nr  r  r*  c                   > TU R                  5          nTR                  SU-  S[        U5      -  5      nTR                  SUS   U4-  5        g )Ns   %(statusName)ss   phabricator.status.%ss   
%s %s
r  )rV  rb  r  r   )rD  rI  r  
drevsbyrevrS   s      rC   
phabstatus&phabstatusshowview.<locals>.phabstatusU	  sR    #'')$$$~d';;
 	fv 667r8   s   experimentals   graphshortenTs   nodelen)r  )rU  rW  r6  r   r  
setdefaultr  r  r   r,  r   r  r   	dagwalkerr  _exthookr%   longestshortestr   displaygraph
asciiedges)rS   r  	displayerrU  rP  unknownrevsr  revsbydrevidrV  rl  rJ  rI  rb  revdagnodelenra  s   `              @rC   phabstatusshowviewro  B	  sA    99./D$G)+SUB,K}}KK##FCE266s;s# ' 1FDM3JKEJDK 01C"JsO 2 8 	H[))D+FLL/48#""4.G
7#r8   )NF)NNNNNNN)r   
__future__r   r  r   r  r:  r  r   r  r  rt   r   typingmercurial.noder   r   mercurial.i18nr   mercurial.thirdpartyr   TYPE_CHECKING	mercurialr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    mercurial.utilsr!   r"   r#    r%   
testedwithehcmdtabler   configtabletemplatekeywordfinaluisetupuisetup
configitem
colortabler   wrapfunctionr]   r   r   r   r   r  r  r  compiler5  Mr7  rS  rW  rc  re  ry  r  r   r~  r  r  r  r  r  r  r  r  r  r  r  r  r"  r7  rU  r]  ri  rn  CATEGORY_IMPORT_EXPORTr  rP   r+  r  r  r  r  r  r  r  r  r  r  r  r  r  r#  r/  r5  rA  rR  rX  r]  showviewro  r{   r8   rC   <module>r     s  3j #    	     	   %  % 
      6 
  #
;;
**nn$$
//   
   
         
   
   
 
  
   
   
    $,#-#- %3$1"*'0)/*0
 			
		
 J'! (!HQh 0<<9x Qy\E/ F/,*  ZZ(>?  jjF 
|~.   
"t 
" 
" %' %' %'P 
 
 
6
<6"J'22 ))
<!!4P%f>*L^ up."E&L& 	vr112AfI>	ha 9:;	k2q!567	j"a =>?BC		
 
j$"H IJ	gua HIJ //#&h3'&h3Z }}6 : 6
2
-
,
,
%/'
	* ,~/BGC6>BJ0*#L 	8UA2345//!!> 	8UA<=>?//	4&4&n 	i"5 67	i"5 67	*H(IJ	j%#7!89	j%#7!89	hq!345	i"5 67	oua(E&FG	i"H IJ	mUA&=$>?	z3"A BC	vsA9:AfIF +,//%(9C)(9Cx MVH5 6> M,DE F. }0' 1'r8   