HEX
Server: Apache
System: Linux infong-uk86 4.4.400-icpu-106 #2 SMP Mon Sep 15 08:23:40 UTC 2025 x86_64
User: u44115835 (4976590)
PHP: 8.4.17
Disabled: NONE
Upload Files
File: //kunden/lib/python3/dist-packages/dulwich/__pycache__/server.cpython-39.pyc
a

	�_��@s�dZddlZddlZddlZddlZddlZddlmZmZm	Z	m
Z
mZddlZddl
Z
ddlmZddlmZmZmZmZmZmZmZddlmZddlmZmZddlmZdd	lm 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-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDdd
lEmFZFmGZGddlHmIZImJZJe�KeL�ZMGdd
�d
eN�ZOGdd�deN�ZPGdd�deO�ZQGdd�deO�ZRGdd�deN�ZSGdd�deS�ZTGdd�deT�ZUdd�ZVdd�ZWdd�ZXd d!�ZYGd"d#�d#eN�ZZe2e1dfZ[Gd$d%�d%eN�Z\Gd&d'�d'eN�Z]Gd(d)�d)eN�Z^Gd*d+�d+eT�Z_Gd,d-�d-eS�Z`eUe_e`d.�ZaGd/d0�d0e
jb�ZcGd1d2�d2e
jd�Zeejffd3d4�Zgejfdejhejifd5d6�Zjd7d8�Zkd9d:�Zld;d<�ZmeLd=k�r�eg�dS)>a�Git smart network protocol server implementation.

For more detailed implementation on the network protocol, see the
Documentation/technical directory in the cgit distribution, and in particular:

* Documentation/technical/protocol-capabilities.txt
* Documentation/technical/pack-protocol.txt

Currently supported capabilities:

 * include-tag
 * thin-pack
 * multi_ack_detailed
 * multi_ack
 * side-band-64k
 * ofs-delta
 * no-progress
 * report-status
 * delete-refs
 * shallow
 * symref
�N)�List�Tuple�Dict�Optional�Iterable)�
tar_stream)�ApplyDeltaError�ChecksumMismatch�GitProtocolError�	HookError�NotGitRepository�UnexpectedCommandError�ObjectFormatException)�	log_utils)�Commit�valid_hexsha)�write_pack_objects)%�BufferedPktLineWriter�capability_agent�CAPABILITIES_REF�CAPABILITY_AGENT�CAPABILITY_DELETE_REFS�CAPABILITY_INCLUDE_TAG�CAPABILITY_MULTI_ACK_DETAILED�CAPABILITY_MULTI_ACK�CAPABILITY_NO_DONE�CAPABILITY_NO_PROGRESS�CAPABILITY_OFS_DELTA�CAPABILITY_QUIET�CAPABILITY_REPORT_STATUS�CAPABILITY_SHALLOW�CAPABILITY_SIDE_BAND_64K�CAPABILITY_THIN_PACK�COMMAND_DEEPEN�COMMAND_DONE�COMMAND_HAVE�COMMAND_SHALLOW�COMMAND_UNSHALLOW�COMMAND_WANT�	MULTI_ACK�MULTI_ACK_DETAILED�Protocol�ProtocolFile�ReceivableProtocol�SIDE_BAND_CHANNEL_DATA�SIDE_BAND_CHANNEL_PROGRESS�SIDE_BAND_CHANNEL_FATAL�
SINGLE_ACK�TCP_GIT_PORT�ZERO_SHA�ack_type�extract_capabilities�extract_want_line_capabilities�symref_capabilities)�ANNOTATED_TAG_SUFFIX�write_info_refs)�BaseRepo�Repoc@seZdZdZdd�ZdS)�Backendz2A backend for the Git smart server implementation.cCst|j��dS)z�Open the repository at a path.

        Args:
          path: Path to the repository
        Raises:
          NotGitRepository: no git repository was found at path
        Returns: Instance of BackendRepo
        N)�NotImplementedError�open_repository��self�path�rB�0/usr/lib/python3/dist-packages/dulwich/server.pyr>�s	zBackend.open_repositoryN)�__name__�
__module__�__qualname__�__doc__r>rBrBrBrCr<}sr<c@sLeZdZdZdZdZeeefd�dd�Zee	ed�dd�Z
dd	d
�ZdS)�BackendRepoz�Repository abstraction used by the Git server.

    The methods required here are a subset of those provided by
    dulwich.repo.Repo.
    N��returncCst�dS)zZ
        Get all the refs in the repository

        Returns: dict of name -> sha
        N�r=�r@rBrBrC�get_refs�szBackendRepo.get_refs)�namerJcCsdS)a�Return the cached peeled value of a ref, if available.

        Args:
          name: Name of the ref to peel
        Returns: The peeled value of the ref. If the ref is known not point to
            a tag, this will be the SHA the ref refers to. If no cached
            information about a tag is available, this method may return None,
            but it should attempt to peel the tag if possible.
        NrB)r@rNrBrBrC�
get_peeled�s
zBackendRepo.get_peeledcCst�dS)a
        Yield the objects required for a list of commits.

        Args:
          progress: is a callback to send progress messages to the client
          get_tagged: Function that returns a dict of pointed-to sha ->
            tag sha for including tags.
        NrK)r@�determine_wants�graph_walker�progress�
get_taggedrBrBrC�
fetch_objects�s
zBackendRepo.fetch_objects)N)rDrErFrG�object_store�refsr�bytesrMrrOrTrBrBrBrCrH�s
�rHc@s(eZdZdZdd�Zeed�dd�ZdS)�DictBackendz?Trivial backend that looks up Git repositories in a dictionary.cCs
||_dS�N)�repos)r@rZrBrBrC�__init__�szDictBackend.__init__)rArJcCsBt�d|�z|j|WSty<tdt|d���Yn0dS)NzOpening repository at %sz'No git repository was found at %(path)s)rA)�logger�debugrZ�KeyErrorr�dictr?rBrBrCr>�s�zDictBackend.open_repositoryN)rDrErFrGr[�strr:r>rBrBrBrCrX�srXcs.eZdZdZejf�fdd�	Zdd�Z�ZS)�FileSystemBackendzDSimple backend looking up Git repositories in the local file system.cs6tt|���tj�|�tj�tjdtj�|_dS)N�)	�superrar[�osrA�abspath�sep�replace�root)r@rh��	__class__rBrCr[�s�zFileSystemBackend.__init__cCsht�d|�tj�tj�|j|��tj}tj�|�}tj�|j�}|�	|�s`t
d||jf��t|�S)Nzopening repository at %szPath %r not inside root %r)r\r]rdrAre�joinrhrf�normcase�
startswithrr;)r@rAreZnormcase_abspathZ
normcase_rootrBrBrCr>�s
��z!FileSystemBackend.open_repository)	rDrErFrGrdrfr[r>�
__classcell__rBrBrirCra�srac@s"eZdZdZddd�Zdd�ZdS)�Handlerz*Smart protocol command handler base class.NcCs||_||_||_dSrY)�backend�proto�
stateless_rpc�r@rprqrrrBrBrCr[�szHandler.__init__cCst|j��dSrY)r=�handlerLrBrBrCrt�szHandler.handle)N)rDrErFrGr[rtrBrBrBrCro�s
rocs�eZdZdZd�fdd�	Zedd��Zeeed�dd	��Z	eeed�d
d��Z
eeed�dd
��Zeedd�dd�Zee
d�dd�Zdd�dd�Z�ZS)�PackHandlerzProtocol handler for packs.Ncs$tt|��|||�d|_d|_dS�NF)rcrur[�_client_capabilities�_done_receivedrsrirBrCr[�szPackHandler.__init__cCs t�d|�d�dd�|D��S)NzSending capabilities: %s�cSsg|]}d|�qS)� rB)�.0�crBrBrC�
<listcomp>�ryz/PackHandler.capability_line.<locals>.<listcomp>)r\�infork)�cls�capabilitiesrBrBrC�capability_line�szPackHandler.capability_linerIcCst|j��dSrY)r=r��rrBrBrCr��szPackHandler.capabilitiescCsttttt�gSrY)rr"rrrr�rBrBrC�innocuous_capabilities�s�z"PackHandler.innocuous_capabilitiescCsgS)zAReturn a list of capabilities that we require the client to have.rBr�rBrBrC�required_capabilities�sz!PackHandler.required_capabilities)�capsrJcCs�t|���}|�|���|D](}|�td�r2q||vrtd|��q|��D]}||vrPtd|��qPt|�|_t	�
d|�dS)N�=z7Client asked for capability %r that was not advertised.z/Client does not support required capability %r.zClient capabilities: %s)�setr��updater�rmrr
r�rwr\r~)r@r�Zallowable_caps�caprBrBrC�set_client_capabilitiess ��
z#PackHandler.set_client_capabilities)r�rJcCs |jdurtd|��||jvS)Nz=Server attempted to access capability %r before asking client)rwr
)r@r�rBrBrC�has_capabilitys

�zPackHandler.has_capabilitycCs
d|_dS)NT)rxrLrBrBrC�notify_doneszPackHandler.notify_done)N)rDrErFrGr[�classmethodr�rrWr�r�r�r��boolr�r�rnrBrBrirCru�s
rucsTeZdZdZd�fdd�	Zedd��Zedd	��Zd
d�Zddd
�Z	dd�Z
�ZS)�UploadPackHandlerz4Protocol handler for uploading a pack to the client.NFcs<tt|�j|||d�|�|d�|_d|_||_d|_dS)N�rrrF)rcr�r[r>�repoZ
_graph_walker�advertise_refs�_processing_have_lines�r@rp�argsrqrrr�rirBrCr[!s
�zUploadPackHandler.__init__c	Cstttttttttg	SrY)	rrr!r"rrrr rr�rBrBrCr�-s
�zUploadPackHandler.capabilitiescCs
tttfSrY)r!r"rr�rBrBrCr�4s�z'UploadPackHandler.required_capabilitiescCs&|�t�s|jrdS|j�t|�dSrY)r�rr�rq�write_sidebandr/)r@�messagerBrBrCrR9s

�zUploadPackHandler.progresscCsv|�t�siS|dur |j��}|durBt|jdd�}|durBiSi}|��D]"\}}|�|�}||krN|||<qN|S)a�Get a dict of peeled values of tags to their original tag shas.

        Args:
          refs: dict of refname -> sha of possible tags; defaults to all
            of the backend's refs.
          repo: optional Repo instance for getting peeled refs; defaults
            to the backend's repo, if available
        Returns: dict of peeled_sha -> tag_sha, where tag_sha is the sha of a
            tag whose peeled value is peeled_sha.
        Nr�)r�rr�rM�getattr�itemsrO)r@rVr�ZtaggedrN�sha�
peeled_sharBrBrCrS?s



zUploadPackHandler.get_taggedcs��fdd�}t��jj�jj�jjj��g���fdd�}�jj|��j�jd�}d�_	t
��dkrhdSd�_	����t
��j�s�dS��d	t
|��d
��ttd|�|��j�d�dS)Ncs�j�t|�SrY�rqr�r.��xrLrBrC�write`sz'UploadPackHandler.handle.<locals>.writecs����|���SrY)�extendrP)rV)rQ�wantsrBrC�
wants_wrapperhsz/UploadPackHandler.handle.<locals>.wants_wrapper)rSTrFzcounting objects: %d, done.
�ascii)�_ProtocolGraphWalkerr�rUrOrV�get_symrefsrTrRrSr��len�handle_doner�rrx�encoderr,rq�write_pkt_line)r@r�r�Zobjects_iterrB)rQr@r�rCrt_s6��
���zUploadPackHandler.handle)NF)NN)rDrErFrGr[r�r�r�rRrSrtrnrBrBrirCr�s�


 r�cCs�|sdg}n|�d��dd�}|d}|dur>||vr>t|��t|�dkr^|tdfvr^|dfSt|�dkr�|ttttfvr�t	|d�s�t
d��t|�S|tkr�|t
|d�fSt
d|��dS)	acSplit a line read from the wire.

    Args:
      line: The line read from the wire.
      allowed: An iterable of command names that should be allowed.
        Command names not listed below as possible return values will be
        ignored.  If None, any commands from the possible return values are
        allowed.
    Returns: a tuple having one of the following forms:
        ('want', obj_id)
        ('have', obj_id)
        ('done', None)
        (None, None)  (for a flush-pkt)

    Raises:
      UnexpectedCommandError: if the line cannot be parsed into one of the
        allowed return values.
    N�
rz�rrbzInvalid shaz%Received invalid line from client: %r)�rstrip�splitr
r�r$r(r%r&r'rr
�tupler#�int)�line�allowed�fields�commandrBrBrC�_split_proto_line�s$�r�cs�i���fdd�}g}|D](}��|�}t|t�r|�|jdf�qt�}t�}|r�|��\}	}
|
|kr�|�|	�|
d�|��fdd�||	�D��qP|�|	�qP||fS)aFind shallow commits according to a given depth.

    Args:
      store: An ObjectStore for looking up objects.
      heads: Iterable of head SHAs to start walking from.
      depth: The depth of ancestors to include. A depth of one includes
        only the heads themselves.
    Returns: A tuple of (shallow, not_shallow), sets of SHAs that should be
        considered shallow and unshallow according to the arguments. Note that
        these sets may overlap if a commit is reachable along multiple paths.
    cs&��|d�}|s"�|j}|�|<|SrY)�get�parents)r��result)r��storerBrC�get_parents�s

z"_find_shallow.<locals>.get_parentsr�c3s|]}|�fVqdSrYrB)r{�p)�	new_depthrBrC�	<genexpr>�ryz _find_shallow.<locals>.<genexpr>)	Zpeel_sha�
isinstancer�append�idr��pop�addr�)r��heads�depthr�ZtodoZhead_sha�obj�not_shallow�shallowr�Z	cur_depthrB)r�r�r�rC�
_find_shallow�s"


r�c
Cs�||}t�|g�}t|g�}|r�|��}|j|vr8dS|jdkrDq|jD]4}||vrXqJ|�|�||}	|	j|krJ|�	|	�qJqdS)NTscommitF)
�collections�dequer��popleftr�Z	type_namer�r��commit_timer�)
r��haves�want�earliest�o�pendingZknownZcommit�parentZ
parent_objrBrBrC�_want_satisfied�s"





r�csJt|�}|r$t�fdd�|D��}nd}|D]}t�|||�s,dSq,dS)a~Check whether all the current wants are satisfied by a set of haves.

    Args:
      store: Object store to retrieve objects from
      haves: A set of commits we know the client has.
      wants: A set of commits the client wants
    Note: Wants are specified with set_wants rather than passed in since
        in the current interface they are determined outside this class.
    csg|]}�|j�qSrB)r�)r{�h�r�rBrCr}ryz(_all_wants_satisfied.<locals>.<listcomp>rFT)r��minr�)r�r�r�r�r�rBr�rC�_all_wants_satisfied�s
r�c@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	e	Z
dd�Zdd�Zdd�Z
d"dd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!S)#r�a7A graph walker that knows the git protocol.

    As a graph walker, this class implements ack(), next(), and reset(). It
    also contains some base methods for interacting with the wire and walking
    the commit tree.

    The work of determining which acks to send is passed on to the
    implementation instance stored in _impl. The reason for this is that we do
    not know at object creation time what ack level the protocol requires. A
    call to set_ack_type() is required to set up the implementation, before
    any calls to next() or ack() are made.
    cCsj||_||_||_||_|j|_|j|_|j|_g|_t�|_	t�|_
t�|_d|_g|_
d|_d|_dS)NFr)�handlerr�rOr�rqrrr��_wantsr�r��client_shallow�	unshallow�_cached�_cache�_cache_index�_impl)r@r�rUrOr�rBrBrCr[sz_ProtocolGraphWalker.__init__c	Cs�|��}t|���}|js |js�tt|����D]�\}\}}z|�|�}Wnt	y`Yq0Yn0|d|}|s�|d|j
�|j
��t
|����7}|j�|d�||kr0|j�|d|td�q0|j�d�|jr�gS|j��}	|	s�gSt|	�\}}
|j
�|
�|�t|
��tttdf}t||�\}}g}
|tk�rv||v�rZtd|��|
�|�|�|�\}}�q:|�|
�|ttfv�r�|�||�|�|
�|j�r�|j� ��r�gS|
S)a-Determine the wants for a set of heads.

        The given heads are advertised to the client, who then specifies which
        refs they want using 'want' lines. This portion of the protocol is the
        same regardless of ack type, and in fact is used to set the ack type of
        the ProtocolGraphWalker.

        If the client has the 'shallow' capability, this method also reads and
        responds to the 'shallow' and 'deepen' lines from the client. These are
        not part of the wants per se, but they set up necessary state for
        walking the graph. Additionally, later code depends on this method
        consuming everything up to the first 'have' line.

        Args:
          heads: a dict of refname->SHA1 to advertise
        Returns: a list of SHA1s requested by the client
        rz�r�NzClient wants invalid object %s)!r�r��valuesr�rr�	enumerate�sortedr�rOr^r�r�r�r7rqr�r8�
read_pkt_liner6r��set_ack_typer4r(r&r#r�r
r��read_proto_line�	set_wants�unread_proto_line�_handle_shallow_request�eof)r@r��symrefsr��i�refr�r�r�r�r�r�r�Z	want_revsrBrBrCrP)s`

����


�


z$_ProtocolGraphWalker.determine_wantscCs0t|t�rt|��d�}|j�|d|�dS)Nr�rz)r�r�r`r�rqZunread_pkt_line)r@r��valuerBrBrCr�ws
z&_ProtocolGraphWalker.unread_proto_linecCs$t|�dkrtd|��|j�|�S)N�(zinvalid sha %r)r��
ValueErrorr��ack�r@Zhave_refrBrBrCr�|sz_ProtocolGraphWalker.ackcCsd|_d|_dS)NTr)r�r�rLrBrBrC�reset�sz_ProtocolGraphWalker.resetcCsN|js |js|jrdSt|j�S|jd7_|jt|j�krBdS|j|jS)Nr�)r�r�rr�nextr�r�r�rLrBrBrCr��s
z_ProtocolGraphWalker.nextcCst|j��|�S)aRead a line from the wire.

        Args:
          allowed: An iterable of command names that should be allowed.
        Returns: A tuple of (command, value); see _split_proto_line.
        Raises:
          UnexpectedCommandError: If an error occurred reading the line.
        )r�rqr�)r@r�rBrBrCr��s	z$_ProtocolGraphWalker.read_proto_linec
Cs�|�ttf�\}}|tkr |}q.|j�|�q|�d�t|j||�\}}|j�||�|j|j}||j@}|_	t
|�D]}	|j�td|	�q~t
|�D]}	|j�t
d|	�q�|j�d�dS)NrYrz)r�r#r&r�r�r�r�r�r�r�r�rqr�r')
r@r�r��valr�r�r�Znew_shallowr�r�rBrBrCr��s"�
z,_ProtocolGraphWalker._handle_shallow_requestcCs|j��dSrY)r�r�rLrBrBrCr��sz _ProtocolGraphWalker.notify_donerycCs(|rd|}|j�d||d�dS)NrzsACK r��rqr�)r@r�r4rBrBrC�send_ack�sz_ProtocolGraphWalker.send_ackcCs|j�d�dS)NsNAK
r�rLrBrBrC�send_nak�sz_ProtocolGraphWalker.send_nakcCs|j�||�SrY)r�r��r@Z
done_requiredZ
done_receivedrBrBrCr��sz _ProtocolGraphWalker.handle_donecCs
||_dSrY)r�)r@r�rBrBrCr��sz_ProtocolGraphWalker.set_wantscCst|j||j�S)a0Check whether all the current wants are satisfied by a set of haves.

        Args:
          haves: A set of commits we know the client has.
        Note: Wants are specified with set_wants rather than passed in since
            in the current interface they are determined outside this class.
        )r�r�r�)r@r�rBrBrC�all_wants_satisfied�sz(_ProtocolGraphWalker.all_wants_satisfiedcCs"tttttti}|||�|_dSrY)r)�MultiAckGraphWalkerImplr*�MultiAckDetailedGraphWalkerImplr1�SingleAckGraphWalkerImplr�)r@r4Zimpl_classesrBrBrCr��s
�z!_ProtocolGraphWalker.set_ack_typeN)ry)rDrErFrGr[rPr�r�r�r��__next__r�r�r�r�r�r�r�r�r�rBrBrBrCr�s"N


r�c@s4eZdZdZdd�Zdd�Zdd�ZeZdd	�Zd
S)r�z@Graph walker implementation that speaks the single-ack protocol.cCs||_g|_dSrY��walker�_common�r@r�rBrBrCr[�sz!SingleAckGraphWalkerImpl.__init__cCs"|js|j�|�|j�|�dSrY)rr�r�r�r�rBrBrCr��szSingleAckGraphWalkerImpl.ackcCs:|j�t�\}}|dtfvr*|j��dS|tkr6|SdSrY)r�r��_GRAPH_WALKER_COMMANDSr$r�r%�r@r�r�rBrBrCr��s
zSingleAckGraphWalkerImpl.nextcCs.|js|j��|r|sdS|s*|js*dSdS)NFT)rr�r�r�rBrBrCr��s

z$SingleAckGraphWalkerImpl.handle_doneN�	rDrErFrGr[r�r�r�r�rBrBrBrCr��s	r�c@s4eZdZdZdd�Zdd�Zdd�ZeZdd	�Zd
S)r�z?Graph walker implementation that speaks the multi-ack protocol.cCs||_d|_g|_dSrv)r��_found_baserrrBrBrCr[
sz MultiAckGraphWalkerImpl.__init__cCs8|j�|�|js4|j�|d�|j�|j�r4d|_dS)N�continueT)rr�rr�r�r�r�rBrBrCr�s
zMultiAckGraphWalkerImpl.ackcCsb|j�t�\}}|dur&|j��qq|tkr<|j��dS|tkr|jrX|j�|d�|SqdS)Nr)	r�r�rr�r$r�r%rr�rrBrBrCr�s

zMultiAckGraphWalkerImpl.nextcCsB|r|sdS|s|jsdS|jr4|j�|jd�n
|j��dS�NF���T�rr�r�r�r�rBrBrCr�-s

z#MultiAckGraphWalkerImpl.handle_doneNrrBrBrBrCr�
sr�c@s4eZdZdZdd�Zdd�Zdd�ZeZdd	�Zd
S)r�zEGraph walker implementation speaking the multi-ack-detailed protocol.cCs||_g|_dSrYr�rrBrBrCr[Hsz(MultiAckDetailedGraphWalkerImpl.__init__cCs|j�|�|j�|d�dS)Nscommon)rr�r�r�r�rBrBrCr�Lsz#MultiAckDetailedGraphWalkerImpl.ackcCsz|j�t�\}}|durR|j�|j�r:|j�|jdd�|j��|jjrtdSq|tkrh|j�	�qvq|t
kr|SqdS)Nrsready)r�r�rr�rr�r�rrr$r�r%rrBrBrCr�Qs

z$MultiAckDetailedGraphWalkerImpl.nextcCsB|r|sdS|s|jsdS|jr4|j�|jd�n
|j��dSrr	r�rBrBrCr�ns

z+MultiAckDetailedGraphWalkerImpl.handle_doneNrrBrBrBrCr�Esr�cs�eZdZdZd�fdd�	Zeeed�dd��Ze	e
eeefe	e
eefd	�d
d�Ze	e
eefdd�d
d�Zdd�Z
dd�dd�Z�ZS)�ReceivePackHandlerz8Protocol handler for downloading a pack from the client.NFcs0tt|�j|||d�|�|d�|_||_dS)Nr�r)rcr
r[r>r�r�r�rirBrCr[�s

�zReceivePackHandler.__init__rIcCsttttttgSrY)rrrrr!rr�rBrBrCr��s�zReceivePackHandler.capabilities)rVrJc
Cs�ttttttjtjtf}g}d}|D]}|dt	kr$d}q$|r�z0t
|jdd�}|jj
�|jj|�|�d�Wq�|y�}z,|�dt|��dd��d	�f�WYd}~q�d}~00n
|�d�|D]�\}}	}
d
}z�|	t	k�r"t|��vr�td��z|jj�|
|�Wn|�yd}Yn0n0z|jj�|
||	�Wn|�yPd
}Yn0Wnt�yld}Yn0|�|
|f�q�|S)NFr�T�recv)�unpack�okr�
�zutf-8r
z8Attempted to delete refs without delete-refs capability.sfailed to deletesfailed to writesbad ref)�IOError�OSErrorr	r�AssertionError�socket�error�zlibrr3r�rqr�rUZ
add_thin_pack�readr�r`rgr�rr�r
rVZremove_if_equalsZ
set_if_equalsr^)r@rVZall_exceptions�statusZwill_send_packr�r�eZoldshar�r�Z
ref_statusrBrBrC�_apply_pack�sN
��

�
zReceivePackHandler._apply_pack)rrJcs���t�r0t�fdd����j}��fdd�}n�jj}dd�}|D]T\}}|dkrf|d|d�qD|d	kr�|d
|d�qD|d|d|d�qD|d�|�dS)
Ncs�j�t|�SrYr�)�drLrBrC�<lambda>�ryz3ReceivePackHandler._report_status.<locals>.<lambda>cs����j�d�dSrY)�flushrqr�rB�r@�writerrBrCr�sz0ReceivePackHandler._report_status.<locals>.flushcSsdSrYrBrBrBrBrCr�srsunpack r�r
sok sng rz)r�r!rr�rqr�)r@rr�rrN�msgrBrrC�_report_status�s 

�z!ReceivePackHandler._report_statusc
Cst|jj�dd�}|sdSz |�|�}|r6|j�t|�Wn6tyn}z|j�tt	|��WYd}~n
d}~00dS)Nzpost-receive)
r�Zhooksr�Zexecuterqr�r/rr0�repr)r@�client_refs�hook�output�errrBrBrC�_on_post_receive�s
z#ReceivePackHandler._on_post_receivecCsT|js|js�t|j�����}t|jj�����}|s@tt	fg}|j
�|ddd|ddd|�|�
�t|��d�tdt|��D],}||}|j
�|dd|dd�q�|j
�d�|jr�dSg}|j
��}|dur�dSt|�\}}|�|�|�r&|�|���|j
��}�q|�|�}|�|�|�t��rP|�|�dS)Nrr�rzr�r�)r�rrr�r�rMr�rVr�rr3rqr�r�r�r7�ranger�r�r5r�r�r�rr&r�rr )r@rVr�r�r�r"r�rrBrBrCrt�sB
����"



zReceivePackHandler.handle)NF)rDrErFrGr[r�rrWr�rrrr r&rtrnrBrBrirCr
�s��5r
cs&eZdZd�fdd�	Zdd�Z�ZS)�UploadArchiveHandlerNcs(tt|��|||�|�|d�|_dS)Nr)rcr(r[r>r�)r@rpr�rqrrrirBrCr[s
�zUploadArchiveHandler.__init__cs(�fdd�}g}�j��D]8}|�dd�\}}|dkrBtd|��|�|�d��qd}d	}d
}�jj}	|t|�kr�||}
|
dkr�|d7}||}n:|
dkr�|d7}||�	d
�}n�jj
|
}|	|	|j}|d7}qh�j�d��j�d�t
|	|t��||d�D]}
||
��q�j�d�dS)Ncs�j�t|�SrYr�r�rLrBrCr�$sz*UploadArchiveHandler.handle.<locals>.writerzr�sargumentzunknown command %sr�ryZtarrs--prefixs--formatr�sACK)�mtime�prefix�format)rqZread_pkt_seqr�r
r�r�r�rUr��decoderV�treer�r�time)r@r�Z	argumentsZpkt�keyr�r*r+r�r�ZargumentZ
commit_shar-�chunkrBrLrCrt#s:

�
zUploadArchiveHandler.handle)N)rDrErFr[rtrnrBrBrirCr(sr()sgit-upload-packsgit-receive-packsgit-upload-archivec@seZdZdd�Zdd�ZdS)�TCPGitRequestHandlercOs$||_tjj|g|�Ri|��dSrY)�handlers�socketserver�StreamRequestHandlerr[)r@r2r��kwargsrBrBrCr[NszTCPGitRequestHandler.__init__cCsjt|jj|jj�}|��\}}t�d||�|j�	|d�}t
|�sNtd|��||jj
||�}|��dS)NzHandling %s request, args=%szInvalid service %s)r-Z
connectionrZwfiler�Zread_cmdr\r~r2r��callabler
�serverrprt)r@rqr�r�rr�rBrBrCrtRszTCPGitRequestHandler.handleN)rDrErFr[rtrBrBrBrCr1Lsr1c@s>eZdZdZejjZdd�Ze	dfdd�Z
dd�Zd	d
�ZdS)�TCPGitServerTcOst|jg|�Ri|��SrY)r1r2)r@r�r5rBrBrC�
_make_handlercszTCPGitServer._make_handlerNcCsLtt�|_|dur|j�|�||_t�d||�tj�	|||f|j
�dS)Nz&Listening for TCP connections on %s:%d)r_�DEFAULT_HANDLERSr2r�rpr\r~r3�	TCPServerr[r9)r@rpZlisten_addr�portr2rBrBrCr[fs
��zTCPGitServer.__init__cCst�d|�dS)NzHandling request from %sT)r\r~�r@ZrequestZclient_addressrBrBrC�verify_requestpszTCPGitServer.verify_requestcCst�d|�dS)Nz7Exception happened during processing of request from %s)r\Z	exceptionr=rBrBrC�handle_errorts�zTCPGitServer.handle_error)
rDrErFZallow_reuse_addressr3r;�
serve_foreverZserver9r2r[r>r?rBrBrBrCr8^s
r8cCs�ddl}|��}|jdddddd�|jd	d
dttdd
�|�|�\}}t��t|�dkrf|d}nd}t	|�}t
||j|j�}|�
�dS)z*Entry point for starting a TCP git server.rNz-lz--listen_address�listen_addressZ	localhostzBinding IP address.)�dest�default�helpz-pz--portr<zBinding TCP port.)rB�typerCrDr��.)�optparseZOptionParserZ
add_optionr�r2�
parse_argsrZdefault_logging_configr�rar8rAr<r@)�argvrG�parserZoptionsr�Zgitdirrpr7rBrBrC�mainys$
��
rKcsF|durt�}�fdd�}t|j|�}|||dd�|�}|��dS)a�Serve a single command.

    This is mostly useful for the implementation of commands used by e.g.
    git+ssh.

    Args:
      handler_cls: `Handler` class to use for the request
      argv: execv-style command-line arguments. Defaults to sys.argv.
      backend: `Backend` to use
      inf: File-like object to read from, defaults to standard input.
      outf: File-like object to write to, defaults to standard output.
    Returns: Exit code for use with sys.exit. 0 on success, 1 on failure.
    Ncs��|����dSrY)r�r)�data��outfrBrC�send_fn�s
zserve_command.<locals>.send_fnr�r)rar+rrt)Zhandler_clsrIrp�infrNrOrqr�rBrMrC�
serve_command�srQcCs|��}t||j�S)zGenerate an info refs file.)rMr9rU)r�rVrBrBrC�generate_info_refs�srRccs*|jjD]}dt�|jj�dVqdS)z Generate an index for for packs.sP r�N)rU�packsrd�fsencoderL�filename)r�ZpackrBrBrC�generate_objects_info_packs�s
��rVcCsF|�tj�dd�d�t|���|�tj�ddd�d�t|���dS)z�Generate server info for dumb file access.

    This generates info/refs and objects/info/packs,
    similar to "git update-server-info".
    r~rVryZobjectsrSN)Z_put_named_filerdrArkrRrV)r�rBrBrC�update_server_info�s��rW�__main__)nrGr�rdr�sysr.�typingrrrrrrr3Zdulwich.archiverZdulwich.errorsrr	r
rrr
rZdulwichrZdulwich.objectsrrZdulwich.packrZdulwich.protocolrrrrrrrrrrrrrr r!r"r#r$r%r&r'r(r)r*r+r,r-r.r/r0r1r2r3r4r5r6r7Zdulwich.refsr8r9Zdulwich.repor:r;Z	getLoggerrDr\�objectr<rHrXrarorur�r�r�r�r�r�rr�r�r�r
r(r:r4r1r;r8rIrK�stdin�stdoutrQrRrVrWrBrBrBrC�<module>sh$	�'
+7q')Q
,;A*�
�