
    >G                        S r SSKJr  SSKJr  SSKrSSKrSSKJrJ	r	  Sr
SrSrSrS	rSrS	rS
rSrSrSrSrSrSrSrSrSrSrSrSrSrSrSr Sr!Sr"Sr#Sr$Sr%Sr&S r'\\ \!\#\/r(\)" \(\"\\\\\$\\\\%\&/-   5      r*\)" \(\\\\/-   5      r+S! r,S" r-S# r.S$ r/S% r0S& r1S'r2Sr3S(r4S)r5S*r6S+r7 " S, S-\85      r9S. r:S/ r;S0 r< " S1 S2\85      r=S3r> " S4 S5\=5      r?S6 r@S7 rAS8 rB " S9 S:\85      rC " S; S<\85      rDg)=z<Generic functions for talking the git smart server protocol.    )BytesIO)SEEK_ENDN)HangupExceptionGitProtocolErrori$  s(   0000000000000000000000000000000000000000         s   atomics   deepen-sinces
   deepen-nots   deepen-relatives   delete-refss   include-tag	   multi_ack   multi_ack_detaileds   no-dones   no-progresss	   ofs-deltas   quiets   report-statuss   shallows	   side-bands   side-band-64ks	   thin-packs   agents   symrefs   allow-tip-sha1-in-wants   allow-reachable-sha1-in-wants   capabilities^{}c                  F    S[         R                  -  R                  S5      $ )Nzdulwich/%d.%d.%dascii)dulwich__version__encode     #lib/third_party/dulwich/protocol.pyagent_stringr   o   s    !4!44<<WEEr   c                  *    [         S-   [        5       -   $ )N   =)CAPABILITY_AGENTr   r   r   r   capability_agentr   s   s    d"\^33r   c                 &    [         S-   U -   S-   U-   $ )Nr      :)CAPABILITY_SYMREF)from_refto_refs     r   capability_symrefr   w   s    t#h.5>>r   c                 &    [        S U  5       5      $ )Nc              3   >   #    U  H  n[        U5      S    v   M     g7f)r   N)parse_capability).0cs     r   	<genexpr>+extract_capability_names.<locals>.<genexpr>|   s     <|!"1%|s   )setcapabilitiess    r   extract_capability_namesr)   {   s    <|<<<r   c                 h    U R                  SS5      n[        U5      S:X  a  US   S 4$ [        U5      $ )Nr   r   r   )splitlentuple)
capabilitypartss     r   r!   r!      s8    T1%E
5zQa$<r   c                 >    U  Vs/ s H  n[        U6 PM     sn$ s  snf N)r   )symrefsks     r   symref_capabilitiesr4      s     +237aq!7333s   s   deepens	   unshallows   dones   wants   havec                   *    \ rS rSrSrS rS rS rSrg)ProtocolFile   z;A dummy file for network ops that expect file-like objects.c                     Xl         X l        g r1   readwrite)selfr:   r;   s      r   __init__ProtocolFile.__init__   s    	
r   c                     g r1   r   r<   s    r   tellProtocolFile.tell       r   c                     g r1   r   r@   s    r   closeProtocolFile.close   rC   r   r9   N)	__name__
__module____qualname____firstlineno____doc__r=   rA   rE   __static_attributes__r   r   r   r6   r6      s    Er   r6   c                 `    U S-   SR                  U Vs/ s H  o"S-   PM	     sn5      -   $ s  snf )N    r       )join)cmdargsas      r   format_cmd_pktrT      s.    :t!<t!u9t!<===!<s   +
c                 z    U R                  S5      nU S U XS-   S  p2USS  S:X  d   eX#S S R                  S5      4$ )NrN   r   rO   )findr+   )line	splice_atrQ   rR   s       r   parse_cmd_pktrZ      sR    		$IZi $1}"79Sb	&&&r   c                 P    U c  gS[        U 5      S-   -  R                  S5      U -   $ )zWrap data in a pkt-line.

Args:
  data: The data to wrap, as a str or None.
Returns: The data prefixed with its length in pkt-line format; if data was
    None, returns the flush-pkt ('0000').
s   0000z%04x   r   )r,   r   )datas    r   pkt_liner^      s/     |c$i!m$,,W5<<r   c                   j    \ rS rSrSrSS jrS rS rS rS r	S	 r
S
 rS rS rS rS rS rS rSrg)Protocol   a  Class for interacting with a remote git process over the wire.

Parts of the git wire protocol use 'pkt-lines' to communicate. A pkt-line
consists of the length of the line as a 4-byte hex string, followed by the
payload data. The length includes the 4-byte header. The special line
'0000' indicates the end of a section of input and is called a 'flush-pkt'.

For details on the pkt-line format, see the cgit distribution:
    Documentation/technical/protocol-common.txt
Nc                 B    Xl         X l        X0l        X@l        S U l        g r1   )r:   r;   _closereport_activity
_readahead)r<   r:   r;   rE   rd   s        r   r=   Protocol.__init__   s    	
.r   c                 H    U R                   (       a  U R                  5         g g r1   )rc   r@   s    r   rE   Protocol.close   s    ;;KKM r   c                     U $ r1   r   r@   s    r   	__enter__Protocol.__enter__   s    r   c                 $    U R                  5         g r1   )rE   )r<   exc_typeexc_valexc_tbs       r   __exit__Protocol.__exit__   s    

r   c                    U R                   c  U R                  nOU R                   R                  nSU l          U" S5      nU(       d
  [        5       e[        US5      nUS:X  a$  U R                  (       a  U R	                  SS5        gU R                  (       a  U R	                  US5        U" US-
  5      n[        U5      S-   U:w  a  [        S[        U5      S-   U4-  5      eU$ ! [        R                   a  n[        U5      eSnAff = f)zReads a pkt-line from the remote git process.

This method may read from the readahead buffer; see unread_pkt_line.

Returns: The next string from the stream, without the length prefix, or
    None for a flush-pkt ('0000').
Nr\      r   r:   z9Length of pkt read %04x does not match length prefix %04x)	re   r:   r   intrd   r,   r   socketerror)r<   r:   sizestrsizepkt_contentses         r   read_pkt_lineProtocol.read_pkt_line   s     ??"99D??''D"DO	 1gG%''w#Dqy''((F3##$$T62q>L < 1$,&O<(1,d34    || 	&"1%%	&s   AC& .C& &D
:DD
c                 h     U R                  5       nU R                  U5        g! [         a     gf = f)zTest whether the protocol stream has reached EOF.

Note that this refers to the actual stream EOF and not just a
flush-pkt.

Returns: True if the stream is at EOF, False otherwise.
TF)r{   r   unread_pkt_line)r<   	next_lines     r   eofProtocol.eof   s<    	**,I 	Y'  		s   $ 
11c                 f    U R                   b  [        S5      e[        [        U5      5      U l         g)a  Unread a single line of data into the readahead buffer.

This method can be used to unread a single pkt-line into a fixed
readahead buffer.

Args:
  data: The data to unread, without the length prefix.
Raises:
  ValueError: If more than one pkt-line is unread.
Nz'Attempted to unread multiple pkt-lines.)re   
ValueErrorr   r^   r<   r]   s     r   r~   Protocol.unread_pkt_line  s*     ??&FGG!(4.1r   c              #   v   #    U R                  5       nU(       a  Uv   U R                  5       nU(       a  M  gg7f)zRead a sequence of pkt-lines from the remote git process.

Returns: Yields each line of data up to but not including the next
    flush-pkt.
N)r{   )r<   pkts     r   read_pkt_seqProtocol.read_pkt_seq  s2        "I$$&C cs   399c                      [        U5      nU R                  U5        U R                  (       a  U R                  [        U5      S5        gg! [        R
                   a  n[        U5      eSnAff = f)zSends a pkt-line to the remote git process.

Args:
  line: A string containing the data to send, without the length
    prefix.
r;   N)r^   r;   rd   r,   ru   rv   r   )r<   rX   rz   s      r   write_pkt_lineProtocol.write_pkt_line"  s]    	&D>DJJt##$$SY8 $|| 	&"1%%	&s   AA A0 A++A0c                 0     " S S[         5      nU" U 5      $ )z5Return a writable file-like object for this protocol.c                   ,    \ rS rSrS rS rS rS rSrg))Protocol.write_file.<locals>.ProtocolFilei4  c                     Xl         SU l        g Nr   )_proto_offset)r<   protos     r   r=   2Protocol.write_file.<locals>.ProtocolFile.__init__5  s    # r   c                 v    U R                   R                  U5        U =R                  [        U5      -  sl        g r1   )r   r;   r   r,   r   s     r   r;   /Protocol.write_file.<locals>.ProtocolFile.write9  s&    !!$'D	)r   c                     U R                   $ r1   )r   r@   s    r   rA   .Protocol.write_file.<locals>.ProtocolFile.tell=  s    ||#r   c                     g r1   r   r@   s    r   rE   /Protocol.write_file.<locals>.ProtocolFile.close@  s    r   )r   r   N)	rG   rH   rI   rJ   r=   r;   rA   rE   rL   r   r   r   r6   r   4  s    !*$r   r6   )object)r<   r6   s     r   
write_fileProtocol.write_file1  s    	6 	 D!!r   c                     U(       a9  U R                  [        [        U/5      5      USS -   5        USS nU(       a  M8  gg)zWrite multiplexed data to the sideband.

Args:
  channel: An int specifying the channel to write to.
  blob: A blob of data (as a string) to send on this channel.
N  )r   bytes	bytearray)r<   channelblobs      r   write_sidebandProtocol.write_sidebandE  s>     i	&: ;d6El JK<D dr   c                 :    U R                  [        U/UQ76 5        g)zSend a command and some arguments to a git server.

Only used for the TCP git protocol (git://).

Args:
  cmd: The remote service to access.
  args: List of arguments to send to remove service.
N)r   rT   )r<   rQ   rR   s      r   send_cmdProtocol.send_cmdS  s     	N3667r   c                 8    U R                  5       n[        U5      $ )zRead a command and some arguments from the git client

Only used for the TCP git protocol (git://).

Returns: A tuple of (command, [list of arguments]).
)r{   rZ   )r<   rX   s     r   read_cmdProtocol.read_cmd^  s     !!#T""r   )rc   re   r:   rd   r;   )NN)rG   rH   rI   rJ   rK   r=   rE   rj   rp   r{   r   r~   r   r   r   r   r   r   rL   r   r   r   r`   r`      sI    	" H2	'&"( 	8#r   r`   i    c                   B   ^  \ rS rSrSrSS\4U 4S jjrS rS rSr	U =r
$ )ReceivableProtocolil  a  Variant of Protocol that allows reading up to a size without blocking.

This class has a recv() method that behaves like socket.recv() in addition
to a read() method.

If you want to read n bytes from the wire and block until exactly n bytes
(or EOF) are read, use read(n). If you want to read at most n bytes from
the wire but don't care if you get less, use recv(n). Note that recv(n)
will still block until at least one byte is read.
Nc                 v   > [         [        U ]  U R                  X#US9  Xl        [        5       U l        XPl        g )N)rE   rd   )superr   r=   r:   _recvr   _rbuf	_rbufsize)r<   recvr;   rE   rd   rbufsize	__class__s         r   r=   ReceivableProtocol.__init__x  s:     	 $0IIu? 	1 	
 
Y
!r   c                    US:  d   eU R                   nUR                  5       nUR                  S[        5        UR                  5       U-
  nXA:  aw  UR                  U5        UR	                  U5      n[        5       U l         U R                   R                  UR	                  5       5        U R                   R                  S5        U$ [        5       U l          X-
  nU R                  U5      nU(       d  OY[        U5      nX:X  a	  U(       d  U$ X:X  a  UR                  U5        AO(X::  d   SXh4-  5       eUR                  U5        XH-  nAMv  UR                  U5        UR	                  5       $ )Nr   z_recv(%d) returned %d bytes)	r   rA   seekr   r:   r   r;   r   r,   )	r<   rx   bufstartbuf_lenrvleftr]   ns	            r   r:   ReceivableProtocol.read  s6    axx
 jj
H((*u$?HHUO$B DJJJSXXZ(JJOOAIY
>D ::d#DD	Ay y		$9G;tiGG9IIdOLG3 6 	xxzr   c                    US:  d   eU R                   nUR                  5       nUR                  S[        5        UR                  5       nUR                  U5        XC-
  nU(       d_  U R	                  U R
                  5      n[        U5      U:X  a  U$ [        5       nUR                  U5        UR                  S5        AX l         UR                  U5      $ r   )
r   rA   r   r   r   r   r,   r   r;   r:   )r<   rx   r   r   r   r   r]   s          r   r   ReceivableProtocol.recv  s    axxjj
H((*::dnn-D4yD )CIIdOHHQKJxx~r   )r   r   r   )rG   rH   rI   rJ   rK   	_RBUFSIZEr=   r:   r   rL   __classcell__)r   s   @r   r   r   l  s&    	 "&ti";z r   r   c                     SU ;  a  U / 4$ U R                  5       R                  S5      u  pXR                  5       R                  S5      4$ )zExtract a capabilities list from a string, if present.

Args:
  text: String to extract from
Returns: Tuple with text with capabilities removed and list of capabilities
rO   rN   )rstripr+   strip)textr(   s     r   extract_capabilitiesr     sK     DRx,,U3D$$&,,T233r   c                     U R                  5       R                  S5      n[        U5      S:  a  U / 4$ SR                  USS 5      USS 4$ )a\  Extract a capabilities list from a want line, if present.

Note that want lines have capabilities separated from the rest of the line
by a space instead of a null byte. Thus want lines have the form:

    want obj-id cap1 cap2 ...

Args:
  text: Want line to extract from
Returns: Tuple with text with capabilities removed and list of capabilities
rN   r	   Nr   )r   r+   r,   rP   )r   
split_texts     r   extract_want_line_capabilitiesr     sO     $$T*J
:RxIIj!n%z!"~66r   c                 >    SU ;   a  [         $ SU ;   a  [        $ [        $ )z.Extract the ack type from a capabilities list.r   r
   )MULTI_ACK_DETAILED	MULTI_ACK
SINGLE_ACKr'   s    r   ack_typer     s$    ,!!		%r   c                   .    \ rS rSrSrSS jrS rS rSrg)	BufferedPktLineWriteri  a  Writer that wraps its data in pkt-lines and has an independent buffer.

Consecutive calls to write() wrap the data in a pkt-line and then buffers
it until enough lines have been written such that their total length
(including length prefix) reach the buffer size.
c                 H    Xl         X l        [        5       U l        SU l        g)zInitialize the BufferedPktLineWriter.

Args:
  write: A write callback for the underlying writer.
  bufsize: The internal buffer size, including length prefixes.
r   N)_write_bufsizer   _wbuf_buflen)r<   r;   bufsizes      r   r=   BufferedPktLineWriter.__init__  s     Y
r   c                 X   [        U5      n[        U5      nU R                  U-   U R                  -
  nUS:  a3  X4-
  nU R                  R                  USU 5        U R                  5         OSnX%S nU R                  R                  U5        U =R                  [        U5      -  sl        g)z&Write data, wrapping it in a pkt-line.r   N)r^   r,   r   r   r   r;   flush)r<   r]   rX   line_lenoverr   saveds          r   r;   BufferedPktLineWriter.write  s    ~t9||h&619OEJJT&5\*JJLEV

E
"r   c                     U R                   R                  5       nU(       a  U R                  U5        SU l        [	        5       U l         g)zFlush all data from the buffer.r   N)r   getvaluer   _lenr   r   s     r   r   BufferedPktLineWriter.flush"  s3    zz""$KK	Y
r   )r   r   r   r   r   N)r   )	rG   rH   rI   rJ   rK   r=   r;   r   rL   r   r   r   r   r     s    
#r   r   c                   *    \ rS rSrSrS rS rS rSrg)PktLineParseri+  zBPacket line parser that hands completed packets off to a callback.c                 .    Xl         [        5       U l        g r1   )
handle_pktr   re   )r<   r   s     r   r=   PktLineParser.__init__.  s    $!)r   c                    U R                   R                  U5        U R                   R                  5       n[        U5      S:  a  g[        U5      S:  af  [	        USS S5      nUS:X  a  U R                  S5        USS nO)U[        U5      ::  a  U R                  USU 5        X#S nOO[        U5      S:  a  Mf  [        5       U l         U R                   R                  U5        g)zAParse a fragment of data and call back for any completed packets.r\   Nrs   r   )re   r;   r   r,   rt   r   r   )r<   r]   r   rx   s       r   parsePktLineParser.parse2  s    d#oo&&(s8a<#h!ms2Aw#Dqy%!"gS!Ad,%j #h!m ")c"r   c                 6    U R                   R                  5       $ )zRead back any unused data.)re   r   r@   s    r   get_tailPktLineParser.get_tailE  s    ''))r   )re   r   N)	rG   rH   rI   rJ   rK   r=   r   r   rL   r   r   r   r   r   +  s    L$#&*r   r   )ErK   ior   osr   ru   r   dulwich.errorsr   r   TCP_GIT_PORTZERO_SHAr   r   r   SIDE_BAND_CHANNEL_DATASIDE_BAND_CHANNEL_PROGRESSSIDE_BAND_CHANNEL_FATALCAPABILITY_ATOMICCAPABILITY_DEEPEN_SINCECAPABILITY_DEEPEN_NOTCAPABILITY_DEEPEN_RELATIVECAPABILITY_DELETE_REFSCAPABILITY_INCLUDE_TAGCAPABILITY_MULTI_ACKCAPABILITY_MULTI_ACK_DETAILEDCAPABILITY_NO_DONECAPABILITY_NO_PROGRESSCAPABILITY_OFS_DELTACAPABILITY_QUIETCAPABILITY_REPORT_STATUSCAPABILITY_SHALLOWCAPABILITY_SIDE_BANDCAPABILITY_SIDE_BAND_64KCAPABILITY_THIN_PACKr   r   !CAPABILITY_ALLOW_TIP_SHA1_IN_WANT'CAPABILITY_ALLOW_REACHABLE_SHA1_IN_WANTCAPABILITIES_REFCOMMON_CAPABILITIESr&   KNOWN_UPLOAD_CAPABILITIESKNOWN_RECEIVE_CAPABILITIESr   r   r   r)   r!   r4   COMMAND_DEEPENCOMMAND_SHALLOWCOMMAND_UNSHALLOWCOMMAND_DONECOMMAND_WANTCOMMAND_HAVEr   r6   rT   rZ   r^   r`   r   r   r   r   r   r   r   r   r   r   <module>r     s  , C   
 
	      ) % / ' ' #  5  ' #  +  # + #   $= !*I ' &     %")/   ! 	 F4?=4   6 >'
=n#v n#b 	h hV
47$)F )X*F *r   