
                           d Z ddlmZ ddlmZmZ ddlZddlZddlZddl	Z	ddl
Z
ddlZddlmZmZmZmZ ddlmZmZmZmZmZmZ ddlZddlmZ ddlmZmZm Z  dd	l!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZE dd
lFmGZGmHZH ddlImJZJmKZK  ej                  eM      ZN G d deO      ZP G d deO      ZQd ZRd ZSe,e1gZTe2e*e+e/geTz   ZUe.e(geTz   ZV G d deW      ZXd ZY G d deW      ZZ G d deW      Z[d Z\ G d deW      Z]d Z^d Z_ G d de]      Z` G d  d!e`      Za G d" d#eW      Zbd$ Zc G d% d&e`      Zd G d' d(e]      ZeeeZf G d) d*eW      Zg G d+ d,eO      Zh G d- d.eg      Zi G d/ d0eg      Zjd1 ZkeiZl G d2 d3e`      Zmd4 Zn	 d?d5Zo G d6 d7e]      Zpd@d8Zqd9 Zrd: Zsej                  j                  d;       ed<d=      gZvdevfd>Zwy)Aa1  Client side support for the Git protocol.

The Dulwich client supports the following capabilities:

 * thin-pack
 * multi_ack_detailed
 * multi_ack
 * side-band-64k
 * ofs-delta
 * quiet
 * report-status
 * delete-refs
 * shallow

Known capabilities that are not supported:

 * no-progress
 * include-tag
    )closing)BytesIOBufferedReaderN)OptionalDictCallableSet)quoteunquoteurlparseurljoin
urlunsplit
urlunparse)get_xdg_config_home_path)GitProtocolErrorNotGitRepositorySendPackError)$HangupException	_RBUFSIZEagent_stringcapability_agentextract_capability_namesCAPABILITY_AGENTCAPABILITY_DELETE_REFSCAPABILITY_INCLUDE_TAGCAPABILITY_MULTI_ACKCAPABILITY_MULTI_ACK_DETAILEDCAPABILITY_OFS_DELTACAPABILITY_QUIETCAPABILITY_REPORT_STATUSCAPABILITY_SHALLOWCAPABILITY_SYMREFCAPABILITY_SIDE_BAND_64KCAPABILITY_THIN_PACKCAPABILITIES_REFKNOWN_RECEIVE_CAPABILITIESKNOWN_UPLOAD_CAPABILITIESCOMMAND_DEEPENCOMMAND_SHALLOWCOMMAND_UNSHALLOWCOMMAND_DONECOMMAND_HAVECOMMAND_WANTSIDE_BAND_CHANNEL_DATASIDE_BAND_CHANNEL_PROGRESSSIDE_BAND_CHANNEL_FATALPktLineParserProtocolProtocolFileTCP_GIT_PORTZERO_SHAextract_capabilitiesparse_capability)write_pack_datawrite_pack_objects)read_info_refsANNOTATED_TAG_SUFFIXc                       e Zd ZdZd Zy)InvalidWantszInvalid wants.c                 6    t         j                  | d|z         y )Nz/requested wants not in server provided refs: %r)	Exception__init__)selfwantss     !lib/third_party/dulwich/client.pyr@   zInvalidWants.__init__y   s    CeK	
    N__name__
__module____qualname____doc__r@    rD   rC   r=   r=   v   s
    
rD   r=   c                       e Zd ZdZd Zy)HTTPUnauthorizedz!Raised when authentication fails.c                 L    t         j                  | d       || _        || _        y )NzNo valid credentials provided)r?   r@   www_authenticateurl)rA   rN   rO   s      rC   r@   zHTTPUnauthorized.__init__   s"    4!@A 0rD   NrE   rJ   rD   rC   rL   rL      s
    +rD   rL   c                 R    t        t        j                  | gg g d      d         dkD  S )z'Check if a file descriptor is readable.r   )lenselect)filenos    rC   _fileno_can_readrT      s(    v}}fXr2q1!4599rD   c           
          ddl m}m}m} |j	                         }|j	                         }|j
                  j                  | ddd ||       ||            }|st        |j                               |j                  S )zCWrapper around PeekNamedPipe to check how many bytes are available.r   )byrefwintypeswindllN)
ctypesrV   rW   rX   DWORDkernel32PeekNamedPipeOSErrorGetLastErrorvalue)handlerV   rW   rX   c_avail	c_messagesuccesss          rC   _win32_peek_availrd      sm    ..nnG Ioo++auW~uY/?G h++-..==rD   c                   "    e Zd ZdZd Zd Zd Zy)ReportStatusParserzEHandle status as reported by servers with 'report-status' capability.c                 .    d| _         d | _        g | _        y )NF)_done_pack_status_ref_statusesrA   s    rC   r@   zReportStatusParser.__init__   s    
 rD   c              #   P  K   | j                   dvrt        | j                         | j                  D ]a  }	 |j                  dd      \  }}|dk(  r+|j                  dd      \  }}||j                  d      f I|dk(  r|df Ut        d|z         y# t        $ r Y pw xY ww)	zCheck if there were any errors and, if so, raise exceptions.

        Raises:
          SendPackError: Raised when the server could not unpack
        Returns:
          iterator over refs
        )s	   unpack okN       s   ngutf-8s   okNzinvalid ref status %r)ri   r   rj   split
ValueErrordecoder   )rA   statusrestreferrors        rC   checkzReportStatusParser.check   s      $88 1 122((F%||D!4 !ZZa0
U5<<0005Dj &'>'GHH )  s)   3B&BAB&	B# B&"B##B&c                     | j                   rt        d      |d| _         y| j                  |j                         | _        y|j                         }| j                  j                  |       y)zHandle a packet.

        Raises:
          GitProtocolError: Raised when packets are received after a flush
          packet.
        z&received more data after status reportNT)rh   r   ri   striprj   append)rA   pkt
ref_statuss      rC   handle_packetz ReportStatusParser.handle_packet   s_     ::"#KLL;DJ$ #		DJ%%j1rD   N)rF   rG   rH   rI   r@   rw   r}   rJ   rD   rC   rf   rf      s    O 
I02rD   rf   c                 X   d }i }| j                         D ][  }|j                  d      j                  d d      \  }}|dk(  rt        |j	                  dd            |t        |      \  }}|||<   ] t        |      dk(  ri t        g       fS |t        t        ik(  ri }|t        |      fS )N   
rn   s   ERRro   replacer   )
read_pkt_seqrstriprp   r   rr   r6   rQ   setr%   r5   )protoserver_capabilitiesrefsr{   sharu   s         rC   read_pkt_refsr      s    D!!#ZZ&,,T15
c&="3::gy#ABB&)=c)B&S%S	 $ 4yA~3r7{ (++()))rD   c                   \     e Zd ZdZg dZddZd Zd Zd Zd Z	d Z
d	 Z fd
Zd Z xZS )FetchPackResultzResult of a fetch-pack operation.

    Attributes:
      refs: Dictionary with all remote refs
      symrefs: Dictionary with remote symrefs
      agent: User agent string
    clearcopyfromkeysgetitemskeyspoppopitem
setdefaultupdatevalues	viewitemsviewkeys
viewvaluesc                 J    || _         || _        || _        || _        || _        y N)r   symrefsagentnew_shallownew_unshallow)rA   r   r   r   r   r   s         rC   r@   zFetchPackResult.__init__  s'    	
&*rD   c                 <    dd l }|j                  dt        d       y )Nr   z!Use FetchPackResult.refs instead.   
stacklevelwarningswarnDeprecationWarningrA   r   s     rC   _warn_deprecatedz FetchPackResult._warn_deprecated  s    / 	 	
rD   c                     t        |t              r| j                          | j                  |k(  S | j                  |j                  k(  xr4 | j                  |j                  k(  xr | j
                  |j
                  k(  S r   )
isinstancedictr   r   r   r   rA   others     rC   __eq__zFetchPackResult.__eq__  sf    eT"!!#99%%II# *-*

ekk)	
rD   c                 >    | j                          || j                  v S r   r   r   rA   names     rC   __contains__zFetchPackResult.__contains__"      tyy  rD   c                 @    | j                          | j                  |   S r   r   r   s     rC   __getitem__zFetchPackResult.__getitem__&      yyrD   c                 L    | j                          t        | j                        S r   r   rQ   r   rk   s    rC   __len__zFetchPackResult.__len__*      499~rD   c                 L    | j                          t        | j                        S r   r   iterr   rk   s    rC   __iter__zFetchPackResult.__iter__.      DIIrD   c                     |t        |       j                  v r&| j                          t        | j                  |      S t
        t        |   |      S r   )type_FORWARDED_ATTRSr   getattrr   superr   __getattribute__rA   r   	__class__s     rC   r   z FetchPackResult.__getattribute__2  sD    4:...!!#499d++_d<TBBrD   c                     | j                   j                  d| j                  d| j                  d| j                  dS N(z, ))r   rF   r   r   r   rk   s    rC   __repr__zFetchPackResult.__repr__8  s.    NN##IILLJJ	
 	
rD   NNrF   rG   rH   rI   r   r@   r   r   r   r   r   r   r   r   __classcell__r   s   @rC   r   r      s>    "+

!C
rD   r   c                   \     e Zd ZdZg dZddZd Zd Zd Zd Z	d Z
d	 Z fd
Zd Z xZS )SendPackResulta  Result of a upload-pack operation.

    Attributes:
      refs: Dictionary with all remote refs
      agent: User agent string
      ref_status: Optional dictionary mapping ref name to error message (if it
        failed to update), or None if it was updated successfully
    r   c                 .    || _         || _        || _        y r   )r   r   r|   )rA   r   r   r|   s       rC   r@   zSendPackResult.__init__\  s    	
$rD   c                 <    dd l }|j                  dt        d       y )Nr   z Use SendPackResult.refs instead.r   r   r   r   s     rC   r   zSendPackResult._warn_deprecateda  s    . 	 	
rD   c                     t        |t              r| j                          | j                  |k(  S | j                  |j                  k(  xr | j                  |j                  k(  S r   )r   r   r   r   r   r   s     rC   r   zSendPackResult.__eq__j  sL    eT"!!#99%%yyEJJ&D4::+DDrD   c                 >    | j                          || j                  v S r   r   r   s     rC   r   zSendPackResult.__contains__p  r   rD   c                 @    | j                          | j                  |   S r   r   r   s     rC   r   zSendPackResult.__getitem__t  r   rD   c                 L    | j                          t        | j                        S r   r   rk   s    rC   r   zSendPackResult.__len__x  r   rD   c                 L    | j                          t        | j                        S r   r   rk   s    rC   r   zSendPackResult.__iter__|  r   rD   c                     |t        |       j                  v r&| j                          t        | j                  |      S t
        t        |   |      S r   )r   r   r   r   r   r   r   r   r   s     rC   r   zSendPackResult.__getattribute__  sD    4:...!!#499d++^T;DAArD   c                 h    | j                   j                  d| j                  d| j                  dS r   )r   rF   r   r   rk   s    rC   r   zSendPackResult.__repr__  s!    #~~66		4::NNrD   r   r   r   s   @rC   r   r   A  s@    "%

E!BOrD   r   c                 D   t               }t               }| j                         D ]v  }|j                  dd      \  }}|t        k(  r |j	                  |j                                A|t        k(  r |j	                  |j                                jt        d|z         ||fS )Nrm   rn   zunknown command %s)r   r   rp   r)   addry   r*   r   )r   r   r   r{   cmdr   s         rC   _read_shallow_updatesr     s    %KEM!!#99T1%S/!OOCIIK(%%ciik*"#7##=>> $ ''rD   c                       e Zd ZdZ	 	 	 	 ddZd Zed        ZddZddZ		 	 ddZ
d	 Zd
 Zed        Zd Zd Z	 ddedee   deegdf   deeeee   f      fdZd Zd ZdefdZy)	GitClientzGit smart server client.Nc                    || _         d| _        t        t              | _        | j                  j                  t                      t        t              | _        | j                  j                  t                      |r| j                  j                  t               |s| j                  j                  t               |r | j                  j                  t               yy)a6  Create a new GitClient instance.

        Args:
          thin_packs: Whether or not thin packs should be retrieved
          report_activity: Optional callback for reporting transport
            activity.
          include_tags: send annotated tags when sending the objects they point
            to
        N)_report_activity_report_status_parserr   UPLOAD_CAPABILITIES_fetch_capabilitiesr   r   RECEIVE_CAPABILITIES_send_capabilitiesr   remover$   r   )rA   
thin_packsreport_activityquietinclude_tagss        rC   r@   zGitClient.__init__  s      !0%)"#&':#;   $$%5%78"%&:";##$4$67##''(89$$++,@A$$(()?@ rD   c                 ,    t        | j                        )zRetrieves full url to given path.

        Args:
          path: Repository path (as string)

        Returns:
          Url to path (as string)

        )NotImplementedErrorget_urlrA   paths     rC   r   zGitClient.get_url  s     "$,,//rD   c                 ,    t        | j                        )zCreate an instance of this client from a urlparse.parsed object.

        Args:
          parsedurl: Result of urlparse()

        Returns:
          A `GitClient` object
        )r   from_parsedurlcls	parsedurlkwargss      rC   r   zGitClient.from_parsedurl  s     "#"4"455rD   c                 ,    t        | j                        )ap  Upload a pack to a remote repository.

        Args:
          path: Repository path (as bytestring)
          update_refs: Function to determine changes to remote refs. Receive
            dict with existing remote refs, returns dict with
            changed refs (name -> sha, where sha=ZERO_SHA for deletions)
          generate_pack_data: Function that can return a tuple
            with number of objects and list of pack data to include
          progress: Optional progress function

        Returns:
          SendPackResult object

        Raises:
          SendPackError: if server rejects the pack data

        )r   	send_pack)rA   r   update_refsgenerate_pack_dataprogresss        rC   r   zGitClient.send_pack  s    & "$..11rD   c                   	 |j                   j                  }t        | j                  v rt	               		fd}d }nj                   j                         \  	}}	 | j                  ||j                         	j                  ||      } |        j                  |j                  |j                         |S # t        $ r	  |         w xY w)a  Fetch into a target repository.

        Args:
          path: Path to fetch from (as bytestring)
          target: Target repository to fetch into
          determine_wants: Optional function to determine what refs to fetch.
            Receives dictionary of name->sha, should return
            list of shas to fetch. Defaults to all shas.
          progress: Optional progress function
          depth: Depth to fetch at

        Returns:
          Dictionary with all remote refs (not just those fetched)

        c                       j                         r8 j                  d       j                  j                   j                  d        y y )Nr   )tellseekobject_storeadd_thin_packread)ftargets   rC   commitzGitClient.fetch.<locals>.commit  s6    668FF1I''55affdC rD   c                       y r   rJ   rJ   rD   rC   abortzGitClient.fetch.<locals>.abort      rD   r   depth)r  determine_wants_allr$   r   r   add_pack
fetch_packget_graph_walkerwriteBaseExceptionupdate_shallowr   r   )
rA   r   r  determine_wantsr   r  r	  r  resultr  s
     `      @rC   fetchzGitClient.fetch  s      "$11EEO4#;#;; 	AD
  &22;;=Avu	__'')! % F Hf00&2F2FG  	G	s    /B> >Cc                 ,    t        | j                        )  Retrieve a pack from a git smart server.

        Args:
          path: Remote path to fetch from
          determine_wants: Function determine what refs
        to fetch. Receives dictionary of name->sha, should return
        list of shas to fetch.
          graph_walker: Object with next() and ack().
          pack_data: Callback called for each bit of data in the pack
          progress: Callback for progress reports (strings)
          depth: Shallow fetch depth

        Returns:
          FetchPackResult object

        )r   r  )rA   r   r  graph_walker	pack_datar   r  s          rC   r  zGitClient.fetch_pack  s    2 "$//22rD   c                 ,    t        | j                        )zRetrieve the current refs from a git smart server.

        Args:
          path: Path to the repo to fetch from. (as bytestring)

        Returns:

        )r   get_refsr   s     rC   r  zGitClient.get_refs5  s     "$--00rD   c                     |j                         D ]&  }t        |dd       }|dd }	 ||   }| ||       ( y# t        $ r t        d|z        w xY w)a  Read per-channel data.

        This requires the side-band-64k capability.

        Args:
          proto: Protocol object to read from
          channel_callbacks: Dictionary mapping channels to packet
            handlers to use. None for a callback discards channel data.
        Nrn   zInvalid sideband channel %d)r   ordKeyErrorAssertionError)rA   r   channel_callbacksr{   channelcbs         rC   _read_side_band64k_dataz!GitClient._read_side_band64k_data@  sr     %%'C#bq'lGab'C&w/ >sG (
  N$%BW%LMMNs	   ;Ac                 B    t        d | j                         D              S )Nc              3   .   K   | ]  }|t         k7    y wr   )r5   ).0r   s     rC   	<genexpr>z.GitClient._should_send_pack.<locals>.<genexpr>X  s     @.?s3(?.?s   )anyr   )new_refss    rC   _should_send_packzGitClient._should_send_packU  s     @hoo.?@@@rD   c           	         g }|j                         D cg c]  }|t        k(  r| }}d}|D ]+  }	t        |	t              st	        d|	z        |j                  |	t              }
t        |
t              st	        d|	d|
      |j                  |	t              }t        |t              st	        d|	d|      |
|k7  rut        j                  d|	|
|       |r|j                  |
dz   |z   dz   |	z          n=|j                  |
dz   |z   dz   |	z   dz   dj                  t        |            z          d	}||vs|t        k7  s|j                  |       . |j                  d
       ||fS c c}w )a:  Handle the head of a 'git-receive-pack' request.

        Args:
          proto: Protocol object to read from
          capabilities: List of negotiated capabilities
          old_refs: Old refs, as received from the server
          new_refs: Refs to change

        Returns:
          (have, want) tuple
        Fzrefname is not a bytestring: %rzold sha1 for z is not a bytestring: z is not a bytestring z Sending updated ref %r: %r -> %rrm       TN)r   r5   r   bytes	TypeErrorr   loggerdebugwrite_pkt_linejoinsortedrz   )rA   r   capabilitiesold_refsr,  wantxhavesent_capabilitiesrefnameold_sha1new_sha1s               rC   _handle_receive_pack_headz#GitClient._handle_receive_pack_headZ  s    #??,B,aAM,B!Ggu- AG KLL||GX6Hh.AH(S   ||GX6Hh.@GR  8#6Xx1 %((D8)Cd)JW)TU(( "#  "	"
    ))F<$89: )-%t#H(<H%A  B 	T"d|K Cs
   E2E2c                     | j                   |z  }d }|D ]  }t        |      \  }}|t        k(  s|} t        |      t        z
  }||fS r   )r   r7   r   r   r&   )rA   r   negotiated_capabilitiesr   
capabilitykvunknown_capabilitiess           rC   $_negotiate_receive_pack_capabilitiesz.GitClient._negotiate_receive_pack_capabilities  sb    "&"9"9<O"O-J#J/DAq$$ .
 %%89<VV 	 '--rD   r   r7  r   returnc                    t         |v rP|d }d|i}t        |v r,t        | j                  j                        j
                  |d<   | j                  ||       n8t        |v r0|j                         D ]  }| j                  j	                  |        | j                  #t        | j                  j                               S y)a  Handle the tail of a 'git-receive-pack' request.

        Args:
          proto: Protocol object to read from
          capabilities: List of negotiated capabilities
          progress: Optional progress reporting function

        Returns:
          dict mapping ref name to:
            error message if the ref failed to update
            None if it was updated successfully
        Nc                      y r   rJ   r:  s    rC   r   z5GitClient._handle_receive_pack_tail.<locals>.progress      rD      rn   )
r#   r    r1   r   r}   parser&  r   r   rw   )rA   r   r7  r   r#  r{   s         rC   _handle_receive_pack_tailz#GitClient._handle_receive_pack_tail  s    $ $|3 "#H'<7'4..<<(% "!$ ((0AB'<7 --/C..<<SA 0%%12288:;;rD   c                     t        |      t        z
  }i }d }|D ]?  }t        |      \  }}|t        k(  r|j	                  dd      \  }}	|	||<   |t
        k(  s>|}A | j                  |z  }
|
||fS )N   :rn   )r   r'   r7   r"   rp   r   r   )rA   r   rF  r   r   rC  rD  rE  srcdstrB  s              rC   #_negotiate_upload_pack_capabilitiesz-GitClient._negotiate_upload_pack_capabilities  s    $%89<UU 	 -J#J/DAq%%WWT1-
c"$$ . #'":":=P"P'%88rD   c                 P   t        |t              rt        |d   t              sJ |j                  t        dz   |d   z   dz   dj                  t        |            z   dz          |dd D ]   }|j                  t        dz   |z   dz          " |dvst        |dd      rt        |vrt        d      |j                  D ]   }|j                  t        dz   |z   dz          " |6|j                  t        dz   t        |      j                  d	      z   dz          |j                  d       |t        |      \  }	}
n"dx}	}
nt!               x}	}
|j                  d       t#        |      }|r|j                  t$        dz   |z   dz          |u |       rn|j'                         }|j)                  d      j+                  d      }|d   d
k(  r6|j-                  |d          |d   dv rn|d   dk(  rnt/        d|d   z        t#        |      }|r|j                  t0        dz          |	|
fS )a  Handle the head of a 'git-upload-pack' request.

        Args:
          proto: Protocol object to read from
          capabilities: List of negotiated capabilities
          graph_walker: GraphWalker instance to call .ack() on
          wants: List of commits to fetch
          can_read: function that returns a boolean that indicates
        whether there is extra graph data to read on proto
          depth: Depth for request

        Returns:

        r   rm   r   rn   N)r   Nshallowz=server does not support shallow capability required for depthascii   ACKrM  )   continue   common   readyz(%s not in ('continue', 'ready', 'common))r   listr0  r4  r-   r5  r6  r   r!   r   rV  r)   r(   strencoder   r   nextr,   read_pkt_liner   rp   ackr"  r+   )rA   r   r7  r  rB   can_readr  r9  r   r   r   r;  r{   partss                 rC   _handle_upload_pack_headz"GitClient._handle_upload_pack_head  s[   " %&:eAh+FFFAh  ii|,-	.
 	
 !"ID  !4t!;e!CD 	!W\9d%K!5&V  $++$$_t%;c%AE%IJ , $$"T)CJ,=,=g,FFN   &#/DU/K,m.22m*-%/K-  &L!  !4t!;e!CD#
))+

5)//58v% $$U1X.Qx#;;qX-,FqQ  %D   	\E12]++rD   c                    |j                         }|re|j                  d      j                  d      }|d   dk(  r|j                  |d          t	        |      dk  s|d   dvrn|j                         }|ret
        |v r$|d
 }| j                  |t        |t        |i       y		 |j                  |      }	|	dk(  ry	 ||	        )a  Handle the tail of a 'git-upload-pack' request.

        Args:
          proto: Protocol object to read from
          capabilities: List of negotiated capabilities
          graph_walker: GraphWalker instance to call .ack() on
          pack_data: Function to call with pack data
          progress: Optional progress reporting function
          rbufsize: Read buffer size

        Returns:

        r   rm   r   rX  rn   r   rM  )r[  rY  rZ  Nc                      y r   rJ   rK  s    rC   r   z4GitClient._handle_upload_pack_tail.<locals>.progress=  rL  rD   rD   )
r`  r   rp   ra  rQ   r#   r&  r.   r/   r  )
rA   r   r7  r  r  r   rbufsizer{   rc  datas
             rC   _handle_upload_pack_tailz"GitClient._handle_upload_pack_tail  s    , !!#JJu%++D1EQx6!  q*5zA~q 2 "
 %%'C  $|3 ((*I. zz(+3;$	 rD   )TNFFr   NNNr   )rF   rG   rH   rI   r@   r   classmethodr   r   r  r  r  r&  staticmethodr-  r@  rG  r2   r	   r0  r   r   r   r]  rO  rT  rd  r   ri  rJ   rD   rC   r   r     s    " A:
0 	6 	62*0p 36	1* A A2h." -1	%% %j% E7D=)	%
 
$uhsm+,	-%N9$A,R 5 rD   r   c                     t        |       |j                         D ch c]  \  }}|j                  t              r| c}}z
  }|rt	        |      yc c}}w )zCheck that a set of wants is valid.

    Args:
      wants: Set of object SHAs to fetch
      refs: Refs dictionary to check against

    Returns:

    N)r   r   endswithr;   r=   )rB   r   rD  rE  missings        rC   check_wantsrp  O  sY     %j

$fq!AJJ7K,L G 7## s
   AAc                    | 
t               S | j                         D cg c]  }|j                  d       }}|D ]<  }|j                  d      st	        |t        d      d  j                  dd            c S  t        |      S c c}w )Nr   s   ERROR: ro   r   )r   	readlinesr   
startswithr   rQ   rr   )stderrlineliness      rC   _remote_error_from_stderrrw  `  s    ~  ,2,<,<,>?,>DT[[,>E???:&#DZ):$;$B$B7I$VWW  5!!	 @s   Bc                   \     e Zd ZdZdZef fd	Zd Zd	dZ	 	 d
dZd Z		 	 	 	 	 ddZ
 xZS )TraditionalGitClientzTraditional Git client.ro   c                 :    || _         t        t        |   di | y NrJ   )_remote_path_encodingr   ry  r@   )rA   path_encodingr   r   s      rC   r@   zTraditionalGitClient.__init__o  s    %2""D2<V<rD   c                    K   t               w)a  Create a connection to the server.

        This method is abstract - concrete implementations should
        implement their own variant which connects to the server and
        returns an initialized Protocol object with the service ready
        for use and a can_read function which may be used to see if
        reads would block.

        Args:
          cmd: The git service name to which we should connect.
          path: The path we should pass to the service. (as bytestirng)
        )r   )rA   r   r   s      rC   _connectzTraditionalGitClient._connects  s      "##s   c                     | j                  d|      \  }}}|5  	 t        |      \  }}	| j	                  |	      \  }
}t
        |
v rt               | _        | j                  }	  |t        |            x}}t        |j                               j                  t        |j                                     r(|j                  d       t        ||i       cddd       S t        |	vr`t        |      }|j                         D ]B  \  }}|t         k(  st
        |
v r(|j"                  j%                  d|z   dz          d|_        ||= D |(|j                  d       t        ||i       cddd       S t)        |      dk(  rQt)        |      rF|j                  d       |t        |j+                               }nd}t        |||      cddd       S | j-                  ||
||      \  }} |||t.        |
v       \  }}| j1                  |      rt3        |j5                         ||       | j7                  ||
|      }t        |||      cddd       S # t        $ r t        |      w xY w# t        $ r |j                  d        w xY w# 1 sw Y   yxY w)	ai  Upload a pack to a remote repository.

        Args:
          path: Repository path (as bytestring)
          update_refs: Function to determine changes to remote refs.
        Receive dict with existing remote refs, returns dict with
        changed refs (name -> sha, where sha=ZERO_SHA for deletions)
          generate_pack_data: Function that can return a tuple with
        number of objects and pack data to upload.
          progress: Optional callback called with progress updates

        Returns:
          SendPackResult

        Raises:
          SendPackError: if server rejects the pack data

        s   receive-packNr   r|   s   ng s&    remote does not support deleting refsFr   	ofs_delta)r  r   r   rw  rG  r    rf   r   r   r  r4  r   r   issubsetr   r   r5   rj   rz   _ref_status_okrQ   rw   r@  r   r-  r8   
write_filerO  )rA   r   r   r   r   r   unused_can_readrt  r8  r   rB  r   report_status_parserr,  orig_new_refsru   r   r|   r;  r9  pack_data_countr  s                         rC   r   zTraditionalGitClient.send_pack  s   & *.)M&80=e0D-- 99:MN''+BB-?-A*#'#=#= +6tH~+FF=
 8>>#$--c(..2B.CD$$T*%heK+ U. &-@@. - 3 3 5HCh37NN0>>EE &/X X CH0?$SM !6 $$T*%heKK UN 8}!c-&8$$T*'3!%&:&@&@&B!CJ!%J%he
S] U`  99.(LT4 *</3JJ*&OY %%h/ 0 0 2OYO77.J "(%JOA U # 8/778 ! $$T* UsU   JI7J!I%4AJ2JAJ-AJA7JI""J%JJJc           	         | j                  d|      \  }}}	|5  	 t        |      \  }
}| j	                  |      \  }}}|
'|j                  d       t        |
||      cddd       S 	  ||
      }||D cg c]  }|t        k7  s| }}|s'|j                  d       t        |
||      cddd       S | j                  ||||||      \  }}| j                  |||||       t        |
||||      cddd       S # t        $ r t        |	      w xY w# t        $ r |j                  d        w xY wc c}w # 1 sw Y   yxY w)r     upload-packN)r  )r  r   r   rw  rT  r4  r   r  r5   rd  ri  )rA   r   r  r  r  r   r  r   rb  rt  r   r   rB  r   r   rB   cidr   r   s                      rC   r  zTraditionalGitClient.fetch_pack  s   2 #'--"Ex8,9%,@)) 889LM	' |$$T*&tWe< U'-  (-AA$$T*&tWe<1 U2 ,0+H+H' ,I ,([- ))' #4%mTQ U # 8/778 ! $$T* B+ UsQ   D7C;4D7(D0D76D2D2	!D74=D7;DD7D//D77E c                     | j                  d|      \  }}}|5  	 t        |      \  }}|j	                  d       |cddd       S # t        $ r t        |      w xY w# 1 sw Y   yxY w)2Retrieve the current refs from a git smart server.r  N)r  r   r   rw  r4  )rA   r   r   _rt  r   s         rC   r  zTraditionalGitClient.get_refs  so      ==>q&8'.a   & U # 8/778 Us!   AAAAAA&c	           
         | j                  d|      \  }	}
}|	5  ||	j                  d|z          |	j                  d|z          ||D ]  }|	j                  d|z           ||	j                  d|z          |	j                  d        	 |	j                         }|dk(  s|dk(  r
	 d d d        y |dk(  s|dk(  rnL|j                  d	      r-t        |d
d  j                  d      j                  dd            t        d|z        |	j                         }|t        d      | j                  |	t        |t        |t        |i       d d d        y # t        $ r t	        |      w xY w# 1 sw Y   y xY w)Ns   upload-archives   argument --format=s	   argument s   argument --prefix=s   NACK
s   NACKs   ACK
rX  s   ERR    r   ro   r   zinvalid response %rzexpected pkt tail)r  r4  r`  r   rw  rs  r   r   rr   r"  r&  r.   r/   r0   )rA   r   
committish
write_datar   write_errorformatsubdirsprefixr   rb  rt  subdirr{   rets                  rC   archivezTraditionalGitClient.archive(  s    #'--0A4"Hx!$$%:V%CD  
!:;"%F(()>? &!$$%:V%CD  &8))+ i3'> U  C6M(&s12w~~e'<'C'CGY'WXX$%:S%@AA%%'C$%899((*J.+[3 U # 8/778 Us+   A/E&	EE&-BE&E##E&&E/r   r   NNNNN)rF   rG   rH   rI   DEFAULT_ENCODINGr@   r  r   r  r  r  r   r   s   @rC   ry  ry  j  sL    !%5 =$TPx BUH
" ,rD   ry  c                   @     e Zd ZdZd fd	Zed        Zd Zd Z xZ	S )TCPGitClientz8A Git Client that works over TCP directly (i.e. git://).c                 X    |t         }|| _        || _        t        t        |   di | y r{  )r4   _host_portr   r  r@   )rA   hostportr   r   s       rC   r@   zTCPGitClient.__init__Z  s-    <D

lD*4V4rD   c                 @     | |j                   fd|j                  i|S )Nr  )hostnamer  r   s      rC   r   zTCPGitClient.from_parsedurla  s!    9%%EINNEfEErD   c                     | j                   }| j                  %| j                  t        k7  r|d| j                  z  z  }t        d||ddf      S )N:%dgit )r  r  r4   r   rA   r   netlocs      rC   r   zTCPGitClient.get_urle  sI    ::!djjL&@edjj((F5&$B788rD   c                    t        |t              st        |      t        |t              s|j                  | j                        }t        j                  | j                  | j                  t
        j                  t
        j                        }d t        j                  d| j                  z        }|D ]a  \  }}}}}	t        j
                  |||      j                  t
        j                  t
        j                  d       	 j                  |	        n |j#                  dd      j#                  dd      fd}t%        j&                  j(                  || j*                        }|j-                  d	      r|dd  }|j/                  d
|z   |d| j                  j                  d      z          |fdd fS # t
        j                  $ r!}
|
}j!                          d Y d }
~
?d }
~
ww xY w)Nzno address found for %srn   rbwbr   c                  f     j                          j                          j                          y r   )close)rfileswfiles   rC   r  z$TCPGitClient._connect.<locals>.close  s    KKMKKMGGIrD   r   s   /~   git-s   host=rW  c                      t               S r   )rT   )r  s   rC   <lambda>z'TCPGitClient._connect.<locals>.<lambda>  s    .q1rD   )r   r0  r1  r^  r|  socketgetaddrinfor  r  	AF_UNSPECSOCK_STREAMrv   
setsockoptIPPROTO_TCPTCP_NODELAYconnectr  makefiler2   r  r  r   rs  send_cmd)rA   r   r   	sockaddrserrfamilysocktyper   	canonnamesockaddrer  r  r  r  s               @@@rC   r  zTCPGitClient._connectk  s   #u%C. $&;;t99:D&&JJ

F$4$4f6H6H
	 ll4tzzAB>G:VXuifh6ALL++V-?-?C		(# ?H 9I

4$

4#	
 JJKK 11	
 ??5!8Dw}dHtzz7H7H7Q,QR14777 << =GGI	s   GG<G77G<r   )
rF   rG   rH   rI   r@   rk  r   r   r  r   r   s   @rC   r  r  W  s+    B5 F F9+8rD   r  c                   2    e Zd ZdZd Zed        Zd Zd Zy)SubprocessWrapperz:A socket-like object that talks to a subprocess via pipes.c                     || _         t        |j                        j                  | _        |j                  j
                  | _        y r   )procr   stdoutr  stdinr  )rA   r  s     rC   r@   zSubprocessWrapper.__init__  s0    	"4;;/44	ZZ%%
rD   c                 .    | j                   j                  S r   )r  rt  rk   s    rC   rt  zSubprocessWrapper.stderr  s    yyrD   c                     t         j                  dk(  r>ddlm}  || j                  j
                  j                               }t        |      dk7  S t        | j                  j
                  j                               S )Nwin32r   )get_osfhandle)	sysplatformmsvcrtr  r  r  rS   rd   rT   )rA   r  r`   s      rC   rb  zSubprocessWrapper.can_read  s\    <<7","499#3#3#:#:#<=F$V,11#DII$4$4$;$;$=>>rD   c                 <   | j                   j                  j                          | j                   j                  j                          | j                   j                  r$| j                   j                  j                          | j                   j                          y r   )r  r  r  r  rt  waitrk   s    rC   r  zSubprocessWrapper.close  s]    				 99II""$		rD   N)	rF   rG   rH   rI   r@   propertyrt  rb  r  rJ   rD   rC   r  r    s(    D&
    ?rD   r  c                      t         j                  dk(  r	 ddl} | j                  d      \  }}|gS dgS # t        $ r g dcY S w xY w)z3Find command to run for system Git (usually C Git).r  r   Nr  )r   z/cr  )r  r  win32apiFindExecutableImportError)r  rs   r  s      rC   find_git_commandr    sQ    
||w	 #11%8KFC5Lw  	(''	(s   3 AAc                   *    e Zd ZdZed        ZdZd Zy)SubprocessGitClientz5Git client that talks to a server using a subprocess.c                      | di |S r{  rJ   r   s      rC   r   z"SubprocessGitClient.from_parsedurl      }V}rD   Nc                     t        |t              st        |      t        |t              r|j                  | j                        }| j
                  
t               }|j                  d      |gz   }t        j                  |dt        j                  t        j                  t        j                        }t        |      }t        |j                  |j                  |j                  | j                        |j                   |j"                  fS )NrW  r   bufsizer  r  rt  r  )r   r0  r1  rr   r|  git_commandr  
subprocessPopenPIPEr  r2   r  r  r  r   rb  rt  )rA   servicer   r  argvppws          rC   r  zSubprocessGitClient._connect  s    '5)G$$dE";;t99:D#*,KgnnW5t<<//????
 q! $ 5 5	 KKHH	
 		
rD   )rF   rG   rH   rI   rk  r   r  r  rJ   rD   rC   r  r    s#    ?  K
rD   r  c                   `    e Zd ZdZddZd Zed        Zed        ZddZ	ddZ
	 	 dd	Zd
 Zy)LocalGitClientz'Git Client that just uses a local Repo.Nc                     || _         y)zCreate a new LocalGitClient instance.

        Args:
          thin_packs: Whether or not thin packs should be retrieved
          report_activity: Optional callback for reporting transport
            activity.
        N)r   )rA   r   r   configs       rC   r@   zLocalGitClient.__init__  s     !0rD   c                 "    t        dd|ddf      S )Nfiler  )r   r   s     rC   r   zLocalGitClient.get_url  s    62tR455rD   c                      | di |S r{  rJ   r   s      rC   r   zLocalGitClient.from_parsedurl  r  rD   c                 z    ddl m} t        |t              st	        j
                  |      }t         ||            S )Nr   )Repo)dulwich.repor  r   r]  osfsdecoder   )r   r   r  s      rC   
_open_repozLocalGitClient._open_repo  s,    %$$;;t$DtDz""rD   c                    |sd }| j                  |      5 }|j                         } |t        |            }|j                         D cg c]  }|t        k7  s| }	}g }
|j                         D ]*  \  }}||	vs||
vs|t        k7  s|
j                  |       , |
sUt        |j                               j                  t        |j                                     rt        |i       cddd       S  |j                  j                   ||	|
d        i }|j                         D ]  \  }}|j                  |t              }|t        k7  r4|j                  j                  |||      rCd|d|} ||       |||<   Y|j                  j                  ||      rv |d|z         d	||<    	 ddd       t              S c c}w # 1 sw Y   xY w)
a  Upload a pack to a remote repository.

        Args:
          path: Repository path (as bytestring)
          update_refs: Function to determine changes to remote refs.
        Receive dict with existing remote refs, returns dict with
        changed refs (name -> sha, where sha=ZERO_SHA for deletions)
        with number of items and pack data to upload.
          progress: Optional progress function

        Returns:
          SendPackResult

        Raises:
          SendPackError: if server rejects the pack data

        c                      y r   rJ   rK  s    rC   r   z*LocalGitClient.send_pack.<locals>.progress  r  rD   )r|   NTr  zunable to set z to zunable to remove %szunable to remove)r  r  r   r   r5   r   rz   r   r  r   r  add_pack_datar   r   set_if_equalsremove_if_equals)rA   r   r   r   r   r  r8  r,  sha1r;  r9  r=  r?  r|   r>  msgs                   rC   r   zLocalGitClient.send_pack  s   $  __T"f(H"4>2H%-__%6K%6T$(:JD%6DKD%-^^%5!D( , H,KK) &6 C 01::3x~~?O;PQ%h2> #"" .F--#D$$? J%-^^%5!#<<:x'!;;44WhQ:A8L .1
7+!;;77J !6!@A.@
7+ &6/ #F h:>>? L	 #"sI   4GGGG=G	GA G6A6G-2G GGGc                     | j                  |      5 }|j                  ||||      }t        ||j                  j	                         t                     cddd       S # 1 sw Y   yxY w)a  Fetch into a target repository.

        Args:
          path: Path to fetch from (as bytestring)
          target: Target repository to fetch into
          determine_wants: Optional function determine what refs
        to fetch. Receives dictionary of name->sha, should return
        list of shas to fetch. Defaults to all shas.
          progress: Optional progress function
          depth: Shallow fetch depth

        Returns:
          FetchPackResult object

        )r  r   r  N)r  r  r   r   get_symrefsr   )rA   r   r  r  r   r  rr   s           rC   r  zLocalGitClient.fetchB  sZ      __T"a77 /!	  D #4););)=|~N #""s   AAA'c                 X   | j                  |      5 }|j                  ||||      }|j                  j                         }	t	               }
|t        d|	|
      cddd       S t        d|      }t        ||       t        |j                         |	|
      cddd       S # 1 sw Y   yxY w)r  r  N)	r  fetch_objectsr   r  r   r   r3   r9   r  )rA   r   r  r  r  r   r  r  objects_iterr   r   protocols               rC   r  zLocalGitClient.fetch_pack[  s    2 __T"a?? + L ff((*G NE #&tWe< #" $D)4Hx6"1::<%@ #""s   AB $2B  B)c                 p    | j                  |      5 }|j                         cddd       S # 1 sw Y   yxY w)r  N)r  r  )rA   r   r  s      rC   r  zLocalGitClient.get_refs  s(     __T"f??$ #""s   ,5)TNNr   rj  r   )rF   rG   rH   rI   r@   r   rk  r   r  r   r  r  r  rJ   rD   rC   r  r    sW    106   # #:?xO> &AP%rD   r  c                   0    e Zd ZdZ	 	 	 	 ddZ	 	 	 	 ddZy)	SSHVendorz!A client side SSH implementation.Nc                 d    dd l }|j                  dt               | j                  ||||||      S )Nr   z?SSHVendor.connect_ssh has been renamed to SSHVendor.run_command)usernamer  passwordkey_filename)r   r   r   run_command)rA   r  commandr  r  r  r  r   s           rC   connect_sshzSSHVendor.connect_ssh  sE     	M	
 %   
 	
rD   c                 ,    t        | j                        )a  Connect to an SSH server.

        Run a command remotely and return a file-like object for interaction
        with the remote command.

        Args:
          host: Host name
          command: Command to run (as argv array)
          username: Optional ame of user to log in as
          port: Optional SSH port to use
          password: Optional ssh password for login or private key
          key_filename: Optional path to private keyfile

        Returns:

        )r   r  )rA   r  r  r  r  r  r  s          rC   r  zSSHVendor.run_command  s    2 "$"2"233rD   NNNN)rF   rG   rH   rI   r  r  rJ   rD   rC   r  r    s+    + 
: 4rD   r  c                   "     e Zd ZdZ fdZ xZS )StrangeHostnamez,Refusing to connect to strange SSH hostname.c                 ,    t         t        |   |       y r   )r   r  r@   )rA   r  r   s     rC   r@   zStrangeHostname.__init__  s    ot-h7rD   )rF   rG   rH   rI   r@   r   r   s   @rC   r  r    s    68 8rD   r  c                        e Zd ZdZ	 	 	 	 ddZy)SubprocessSSHVendorz6SSH vendor that shells out to the local 'ssh' command.Nc                    |t        d      ddg}|r|j                  dt        |      g       |r|j                  dt        |      g       |r|d|}|j                  d      rt	        |      |j                  |       t        j                  ||gz   d	t        j                  t        j                  t        j                  
      }t        |      S )Nz6Setting password not supported by SubprocessSSHVendor.sshz-xz-p-i@-r  r   r  )
r   extendr]  rs  r  rz   r  r  r  r  )	rA   r  r  r  r  r  r  argsr  s	            rC   r  zSubprocessSSHVendor.run_command  s     %H  t}KKs4y)*KKs<012&-D??3!400DG9//????
 !&&rD   r  rF   rG   rH   rI   r  rJ   rD   rC   r  r    s    @ $'rD   r  c                        e Zd ZdZ	 	 	 	 ddZy)PLinkSSHVendorz8SSH vendor that shells out to the local 'plink' command.Nc                 ,   t         j                  dk(  rddg}nddg}|1dd l}|j                  d       |j	                  dt        |      g       |r|j	                  dt        |      g       |r|j	                  d	t        |      g       |r|d
|}|j                  d      rt        |      |j                  |       t        j                  ||gz   dt        j                  t        j                  t        j                        }	t        |	      S )Nr  z	plink.exez-sshplinkr   zHInvoking PLink with a password exposes the password in the process list.z-pwz-Pr  r  r  r   r  )r  r  r   r   r!  r]  rs  r  rz   r  r  r  r  )
rA   r  r  r  r  r  r  r"  r   r  s
             rC   r  zPLinkSSHVendor.run_command  s     <<7"(DV$DMM  KKH./KKs4y)*KKs<012&-D??3!400DG9//????
 !&&rD   r  r#  rJ   rD   rC   r%  r%    s    B +'rD   r%  c                  R    dd l }|j                  dt               ddlm}  |di | S )Nr   zDParamikoSSHVendor has been moved to dulwich.contrib.paramiko_vendor.)ParamikoSSHVendorrJ   )r   r   r   dulwich.contrib.paramiko_vendorr)  )r   r   r)  s      rC   r)  r)  (  s+    MMN B&v&&rD   c                   N     e Zd Z	 	 	 	 	 	 d fd	Zd Zed        Zd Zd Z xZ	S )SSHGitClientc                     || _         || _        || _        || _        || _        t        t        |   di | i | _        ||| _	        y t               | _	        y r{  )r  r  r  r  r  r   r,  r@   alternative_paths
ssh_vendorget_ssh_vendor)
rA   r  r  r  vendorr  r  r  r   r   s
            rC   r@   zSSHGitClient.__init__9  sZ     		  (lD*4V4!#$DO,.DOrD   c                     | j                   }| j                  |d| j                  z  z  }| j                  t        | j                  d      dz   |z   }t	        d||ddf      S )Nr  z@/:r  r  r  )r  r  r  urlquoter   r  s      rC   r   zSSHGitClient.get_urlP  sb    99 edii''F==$dmmU3c9FBF5&$B788rD   c                 V     | d|j                   |j                  |j                  d|S )N)r  r  r  rJ   )r  r  r  r   s      rC   r   zSSHGitClient.from_parsedurlZ  s7     
##''
 	
 	
rD   c                 h    | j                   j                  |d|z         }t        |t              sJ |S )Nr  )r.  r   r   r0  )rA   r   s     rC   _get_cmd_pathzSSHGitClient._get_cmd_pathc  s3    $$((gm<#u%%%
rD   c                    t        |t              st        |      t        |t              r|j                  | j                        }|j                  d      r|dd  }| j                  |      j                  | j                        dz   |z   dz   }i }| j                  | j                  |d<   | j                  | j                  |d<    | j                  j                  | j                  |f| j                  | j                  d|}t        |j                  |j                   |j"                  | j$                        |j&                  t)        |d	d       fS )
Nz/~rn   z ''r  r  )r  r  r  rt  )r   r0  r1  rr   r|  rs  r6  r  r  r/  r  r  r  r  r2   r  r  r  r   rb  r   )rA   r   r   r  r   cons         rC   r  zSSHGitClient._connecth  sD   #u%C. dE";;t99:D??4 8Ds#**4+E+EF  	 ==$!%F:(%)%6%6F>")doo))IIt
"&))dmm
GM
 				 $ 5 5	 LLC4(	
 		
rD   )NNNNNN)
rF   rG   rH   r@   r   rk  r   r6  r  r   r   s   @rC   r,  r,  8  s?     /.9 
 


rD   r,  c            	      ~    ddj                  t        j                  D  cg c]  } t        |        c}       z  S c c} w )Nzgit/dulwich/%s.)r5  dulwich__version__r]  rK  s    rC   default_user_agent_stringr>    s6     chh8K8K'L8K1A8K'LMMM'Ls   :
c                 L   dx}}dx}}|*dD ]%  }t         j                  j                  |      }|% n | N|	 | j                  dd      }	 | j                  dd      }	 | j	                  dd      }	 | j                  dd      }|
t               }d	|i}	i }
|du rd
|
d<   n|du rd|
d<   nd
|
d<   |||
d<   |
j                  |       d|
vr,|
j                  d      dk7  r	 ddl}|j                         |
d<   ddl
}|;||j                  }t        |t              s|j                         } ||fd|	i|
}|S ||j                  } |dd|	i|
}|S # t        $ r Y w xY w# t        $ r Y w xY w# t        $ r d}Y w xY w# t        $ r d}Y w xY w# t        $ r Y w xY w)a  Return `urllib3` connection pool manager.

    Honour detected proxy configurations.

    Args:
      config: dulwich.config.ConfigDict` instance with Git configuration.
      kwargs: Additional arguments for urllib3.ProxyManager

    Returns:
      `pool_manager_cls` (defaults to `urllib3.ProxyManager`) instance for
      proxy configurations, `proxy_manager_cls` (defaults to
      `urllib3.PoolManager`) instance otherwise.

    N)https_proxy
http_proxy	all_proxys   https   proxys	   useragents	   sslVerifyTs	   sslCAInfoz
User-agentCERT_REQUIRED	cert_reqsF	CERT_NONEca_certsr   headersrJ   )r  environr   r!  get_booleanr>  r   certifiwherer  urllib3ProxyManagerr   r]  rr   PoolManager)r  pool_manager_clsproxy_manager_clsoverride_kwargsproxy_server
user_agentrF  
ssl_verify	proxynamerG  r   rJ  rL  managers                 rC   default_urllib3_managerrW    s'   " !%$L:  HzCI::>>)4L' D
 %zz'8<	G\:J
	++G\BJ	zz'<8H .0
Z(GFT-{	u	){ .{%z
MM/" FJJ{$;{$J	1 ")F:$ ' 4 4 ,,'..0L#LL'LVL N	 #&22"=7=f=Ny    		  	J	
  	H	2  		sY   E E#  E3 3F !F 	E E #	E0/E03FFFF	F#"F#c                   n    e Zd Z	 	 	 	 	 ddZd Zed        Zd Zd ZddZ	d Z
d	 Zdd
Z	 	 ddZd Zy)HttpGitClientNc                 \   |j                  d      dz   | _        || _        || _        || _        |t        |      | _        n|| _        |L|d|}dd l}	|	j                  j                  |      }
| j                  j                  j                  |
       t        j                  | fi | y )N/:r   )
basic_auth)r   	_base_url	_username	_passworddumbrW  pool_managerurllib3.utilutilmake_headersrG  r   r   r@   )rA   base_urlra  rb  r  r  r  r   credentialsrL  r]  s              rC   r@   zHttpGitClient.__init__  s     "-3!!	 7 ?D ,D &.x8K 22k2JJ%%,,Z84*6*rD   c                 B    | j                  |      j                  d      S )Nr[  )_get_urlr   r   s     rC   r   zHttpGitClient.get_url  s    }}T"))#..rD   c                 F   |j                   }|t        |      |d<   |j                  }|t        |      |d<   |j                  }|j                  r|d|j                  }|j                  r|j                  d|}|j                  |      } | t        |      fi |S )Nr  r  r\  r  )r  )r  
urlunquoter  r  r  _replacer   )r   r   r   r  r  r  s         rC   r   zHttpGitClient.from_parsedurl  s    %%!+H!5F:%%!+H!5F:##>> &	7F ) 2 2F;F&&f&5	:i(3F33rD   c                 f    t        |       j                  d| j                  d| j                  dS )Nr   z, dumb=r   )r   rF   r^  ra  rk   s    rC   r   zHttpGitClient.__repr__  s'    JNNII
 	
rD   c                     t        |t              s|j                  d      }t        | j                  |      j                  d      dz   S )Nro   r[  )r   r]  rr   r   r^  r   r   s     rC   ri  zHttpGitClient._get_url&  s=    $$ ;;w'Dt~~t,33C83>>rD   c                    | j                   j                  j                         }||j                  |       d|d<   |rd|d<   nd|d<   || j                   j	                  d||      }n| j                   j	                  d|||	      }|j
                  d
k(  r
t               |j
                  dk(  rt        |j                  d      |      |j
                  dk7  rt        d|j
                  |fz        t        |j                        j                  }|j                  d      |_        	 |j                         }||k7  r|nd|_        ||fS # t         $ r |j#                         |_        Y ||fS w xY w)a  Perform HTTP request.

        Args:
          url: Request URL.
          headers: Optional custom headers to override defaults.
          data: Request data.
          allow_compression: Allow GZipped communication.

        Returns:
          Tuple (`response`, `read`), where response is an `urllib3`
          response object with additional `content_type` and
          `redirect_location` properties, and `read` is a consumable read
          method for the response data.

        zno-cachePragmagzipzAccept-EncodingidentityGET)rG  POST)rG  bodyi  i  zWWW-Authenticate   zunexpected http resp %d for %sContent-Typer  )rb  rG  r   r   requestrs   r   rL   	getheaderr   r   rh  r  content_typegeturlredirect_locationAttributeErrorget_redirect_location)	rA   rO   rG  rh  allow_compressionreq_headersrespr  resp_urls	            rC   _http_requestzHttpGitClient._http_request-  s     ''//446w' *H-3K)*-7K)*<$$,,UC,MD$$,,[t - D ;;#"$$;;#"4>>2D#EsKK;;#"0DKK3EE  tyy!&& NN>:	I{{}H
 2:SXbD"Tz  	B%)%?%?%AD" Tz	Bs   ,E E21E2c                 H   |d   dk(  sJ d}ddi}| j                   dur|d|j                  d      z  z  }t        ||      }| j                  ||d	      \  }}|j                  rR|j                  j                  |      st        d
|d|j                  d|      |j                  d t        |        }	 |j                  j                  d       | _         | j                   slt        |d       }	 t        |j                               \  }	|	j                  d      d|z   k7  rt        d|	z        t        |      |fz   |j!                          S t#        |      t%               |f|j!                          S # t        $ r t        d      w xY w# |j!                          w xY w)Nr  r[  z	info/refsAcceptz*/*Tz?service=%srW  )r  zRedirected from URL z to URL z	 without zapplication/x-git-z%unexpected number of packets receivedr   s
   # service=z*unexpected first line %r from smart server)ra  rr   r   r  r|  rn  r   rQ   rz  rs  r2   r\  r   rq   r   r   r  r:   r   )
rA   r  rf  tailrG  rO   r  r  r   r{   s
             rC   _discover_referencesz"HttpGitClient._discover_referencesh  s   |s"""U#99D MGNN7$;;;Dh%''W'M
d!!))2248&D22D:  --lT
;H	 --889MNNDI99 t,T !3!3!56ES ::e$)@A*DsJ  %U+xk9 JJL &d+SUH<JJL " T*+RSST JJLs*   89F 2E7 3F F 7FF F!c                     |d   dk(  sJ t        ||      }d|z  }d|z  |t        t        |            d}| j                  |||      \  }}|j                  |k7  rt        d|j                  z        ||fS )Nr  r[  zapplication/x-%s-resultzapplication/x-%s-request)rw  r  zContent-Lengthz$Invalid content-type from server: %s)r   r]  rQ   r  rz  r   )rA   r  rO   rh  result_content_typerG  r  r  s           rC   _smart_requestzHttpGitClient._smart_request  s    2w#~~c7#7'A6@)!#d)n

 ''Wd;
d 33"69J9JJ  TzrD   c                    | j                  |      }| j                  d|      \  }}}| j                  |      \  }}	|j                  t	                      t
        |v rt               | _         |t        |            }
|
t        ||	i       S t        |
j                               j                  t        |j                                     rt        |
|	i       S | j                  rt        | j                        t!               }t#        d|j$                        }| j'                  ||||
      \  }} |||t(        |v       \  }}| j+                  |
      rt-        |j/                         ||       | j1                  d||j3                               \  }}	 t#        |d      }| j5                  |||      }t        |
|	|      |j7                          S # |j7                          w xY w)aW  Upload a pack to a remote repository.

        Args:
          path: Repository path (as bytestring)
          update_refs: Function to determine changes to remote refs.
        Receives dict with existing remote refs, returns dict with
        changed refs (name -> sha, where sha=ZERO_SHA for deletions)
          generate_pack_data: Function that can return a tuple
        with number of elements and pack data to upload.
          progress: Optional progress function

        Returns:
          SendPackResult

        Raises:
          SendPackError: if server rejects the pack data

        s   git-receive-packNr  r  zgit-receive-packrh  )ri  r  rG  r   r   r    rf   r   r   r   r   r   r  ra  r   r  r   r2   r  r@  r   r-  r8   r  r  getvaluerO  r  )rA   r   r   r   r   rO   r8  r   rB  r   r,  req_data	req_protor;  r9  r  r  r  r  
resp_protor|   s                        rC   r   zHttpGitClient.send_pack  s   & mmD!-1-F-F.
*%s 556IJ	
###$4$67#'>>);)=D&tH~.!(%BGGx~~ ))#hnn.>*?@!(%BGG99%doo669T8>>2	55.(
t &8+/FF&
"
 !!(+I002OYO(((*;*;*= ) 

d	!$-J773XJ "(%JOJJLDJJLs   ,G G'c                    | j                  |      }| j                  d|      \  }}	}| j                  |	      \  }
}} ||      }||D cg c]  }|t        k7  s| }}|st	        |||      S | j
                  rt        | j                        t               }t        d|j                        }| j                  ||
||d|      \  }}| j                  d||j                               \  }}	 t        |d      }||t        |      \  }}| j                  ||
|||       t	        |||||      |j!                          S c c}w # |j!                          w xY w)a  Retrieve a pack from a git smart server.

        Args:
          path: Path to fetch from
          determine_wants: Callback that returns list of commits to fetch
          graph_walker: Object with next() and ack().
          pack_data: Callback called for each bit of data in the pack
          progress: Callback for progress reports (strings)
          depth: Depth for request

        Returns:
          FetchPackResult object

           git-upload-packN)rb  r  zgit-upload-packr  )ri  r  rT  r5   r   ra  r   r  r   r2   r  rd  r  r  r   ri  r  )rA   r   r  r  r  r   r  rO   r   r   rB  r   r   rB   r  r  r  r   r   r  r  r  s                         rC   r  zHttpGitClient.fetch_pack  s   . mmD!)-)B)B*
&!3 445HI		
#%$)=ESSH_SEE="4%8899%doo669T8>>2	'+'D'D# (E (
$m ((s):):)< ) 

d	!$-J"}'</DZ/P,m))' #4%mTJJL? >> JJLs   EE0AE Ec                 T    | j                  |      }| j                  d|      \  }}}|S )r  r  )ri  r  )rA   r   rO   r   r  s        rC   r  zHttpGitClient.get_refs   s.    mmD!../A3G
arD   r  )NNFr   r   )rF   rG   rH   r@   r   rk  r   r   ri  r  r  r  r   r  r  rJ   rD   rC   rY  rY    sf     +>/ 4 4
?9v#J >L AFrD   rY  c                    t        |       }|j                  dk(  r"t        j                  |fi ||j                  fS |j                  dv r"t        j                  |fi ||j                  fS |j                  dv r$t        j                  |fd|i||j                  fS |j                  dk(  r"t        j                  |fi ||j                  fS t        d|j                  z        )aT  Obtain a git client from a URL.

    Args:
      url: URL to open (a unicode string)
      config: Optional config object
      thin_packs: Whether or not thin packs should be retrieved
      report_activity: Optional callback for reporting transport
        activity.

    Returns:
      Tuple with client instance and relative path.

    r  )zgit+sshr  )httphttpsr  r  zunknown scheme '%s')	r   schemer  r   r   r,  rY  default_local_git_client_clsrq   )rO   r  r   parseds       rC   get_transport_and_path_from_urlr  '  s     c]F}}++F=f=v{{KK	,	,**6<V<fkkII	+	+((II&IKK
 	
 
&	 (77I&IKK
 	

 *V]]:
;;rD   c                     d| v rd| vr| j                  dd      \  }}d}nCd| v r4| j                  dd      \  }}d|v r|j                  dd      \  }}nd}|}nt        d      |||fS )zParse a rsync-style URL.r\  r  rn   Nznot a valid rsync-style URL)rp   rsplitrq   )locationr  r   user	user_hosts        rC   parse_rsync_urlr  H  s    
h3h.~~c1-t	"..a0	4)"))#q1JD$DD677$rD   c                 (   	 t        | fi |S # t        $ r Y nw xY wt        j                  dk(  r(| d   j	                         r| dd dk(  rt        di || fS 	 t        |       \  }}}t        |fd|i||fS # t        $ r t        di || fcY S w xY w)aQ  Obtain a git client from a URL.

    Args:
      location: URL or path (a string)
      config: Optional config object
      thin_packs: Whether or not thin packs should be retrieved
      report_activity: Optional callback for reporting transport
        activity.

    Returns:
      Tuple with client instance and relative path.

    r  r   rn   r   z:\r  rJ   )r  rq   r  r  isalphar  r  r,  )r  r   r  r  r   s        rC   get_transport_and_pathr  [  s    .xB6BB  ||w8A;#6#6#8Xa]e=S+5f5x??I%4X%>"8T
 HBxB6BDHH	  @+5f5x??@s    	A8 8BBz~/.git-credentialsr  rg  c                 b   |D ]  }	 t        |d      5 }|D ]q  }t        |j                               }|j                  | k(  s,|j                  |k(  s<||j
                  |k(  sN|j
                  |j                  fc cd d d        c S  	 d d d         y # 1 sw Y   xY w# t        $ r Y w xY w)Nr  )openr   ry   r  r  r  r  FileNotFoundError)r  r  r  fnamesfnamer  ru  parsed_lines           rC   get_credentials_from_storer    s     	eT"aD"*4::<"8K#**f4'00H<%-1E1E1Q*33[5I5III #" # "" ! 		sF   B".BBB$B=	B"	BB"B	B""	B.-B.r   r   )xrI   
contextlibr   ior   r   loggingr  rR   r  r  r  typingr   r   r   r	   urllib.parser
   r3  r   rk  r   r   r   r   r<  dulwich.configr   dulwich.errorsr   r   r   dulwich.protocolr   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.   r/   r0   r1   r2   r3   r4   r5   r6   r7   dulwich.packr8   r9   dulwich.refsr:   r;   	getLoggerrF   r2  r?   r=   rL   rT   rd   COMMON_CAPABILITIESr   r   objectrf   r   r   r   r   r   rp  rw  ry  r  r  r  r  r  r  r  r  r  r%  r)  r0  r,  r>  rW  rY  r  r  r  r   
expanduserDEFAULT_GIT_CREDENTIALS_PATHSr  rJ   rD   rC   <module>r     sX  *(  &  	    
 0 0   3 
% % % % % % % % % %L 
		8	$
9 
y :
 ,-EF !	
     02 02f*&P
f P
fFOV FOR("q  q h$""j9 jZ?8' ?8D :"
. "
J^%Y ^%D  . 54 54p8i 8'') ''T.'Y .'b	' %N
' N
bN 6:ZzxI xv	<B&ID GG+,UM2!   $,IrD   