o
    ﯪg                     @   s2  d gZ ddlZddlmZmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZmZmZ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 dd
lmZm Z  er{ddl!m"Z" ddl	m#Z# ddl$m%Z%m&Z&m'Z'm(Z( ddlm)Z) ddl*m+Z+ edd dZ,dddee df de fddZ-G dd  d Z.dS )SymbolicReference    N)BadName	BadObject)defenc)Object)Commit)RefLog)LockedFDassure_directory_exists
hex_to_bin	join_pathjoin_path_nativeto_native_path_linux)	AnyIteratorListTYPE_CHECKINGTupleTypeTypeVarUnioncast)AnyGitObjectPathLike)GitConfigParser)ActorHeadTagReferenceRemoteReference	Reference)RefLogEntry)RepoT_References)boundrepor"   pathreturnc                 C   s   | }|dv r
| j S | jS )z2Find the git dir that is appropriate for the path.)HEAD	ORIG_HEAD
FETCH_HEADindexlogs)git_dir
common_dir)r%   r&   name r0   M/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/git/refs/symbolic.py_git_dir4   s   r2   c                   @   sb  e Zd ZU dZdZdZdZdZdZdZ	dmdd	d
e
deddfddZdefddZdefddZdedefddZdedefddZdefddZedefddZede
fddZedd	defdd Zedd	deeeef  fd!d"Zedd	d#ee
df defd$d%Zed#e
ddfd&d'Z edd	d#ee
df deeedf edef f fd(d)Z!edd	d#ee
df deeedf edef f fd*d+Z"de#fd,d-Z$dnd/d0Z%	dod1ee&d ef d2eedf dd fd3d4Z'	dod5ee#d ef d2eedf dd fd6d7Z(ee%e'd8d9Z)ee$e(d:d9Zdpd;d<Z*	dod=ee#d ef d2eedf dd fd>d?Z+ed@ e,dA< ee*e+dBd9Z-e-Z.defdCdDZ/edefdEdFZ0dqdHdIZ1	dodJe2dKeedf dLee2df ddMfdNdOZ3dPeddMfdQdRZ4ed
ee
d f de
fdSdTZ5edd	d
e
ddfdUdVZ6e	dodWe7e8 dd	d
e
dXedAed ef dYed2eedf de8fdZd[Z9e	\		drdWe7e8 dd	d
e
dAed ef d2eedf dYed]e:de8fd^d_Z;dmd`e
dYedd fdadbZ<e	dodWe7e8 dd	dcee
df dee8 fdddeZ=e	dodWe7e8 dd	dcee
df dfe:d]e:dee8 fdgdhZ>edWe7e8 dd	d
e
de8fdidjZ?defdkdlZ@dS )sr   a  Special case of a reference that is symbolic.

    This does not point to a specific commit, but to another
    :class:`~git.refs.head.Head`, which itself specifies a commit.

    A typical example for a symbolic reference is :class:`~git.refs.head.HEAD`.
    r%   r&   FT zrefs/remotesr/   r%   r"   r&   
check_pathr'   Nc                 C   s   || _ || _d S Nr3   )selfr%   r&   r5   r0   r0   r1   __init__M   s   
zSymbolicReference.__init__c                 C   
   t | jS r6   strr&   r7   r0   r0   r1   __str__Q      
zSymbolicReference.__str__c                 C   s   d| j j| jf S )Nz<git.%s "%s">)	__class____name__r&   r<   r0   r0   r1   __repr__T   s   zSymbolicReference.__repr__otherc                 C   s$   t |drtt|}| j|jkS dS )Nr&   F)hasattrr   r   r&   r7   rB   r0   r0   r1   __eq__W   s   

zSymbolicReference.__eq__c                 C   s
   | |k S r6   r0   rD   r0   r0   r1   __ne__]   r>   zSymbolicReference.__ne__c                 C   r9   r6   )hashr&   r<   r0   r0   r1   __hash__`   r>   zSymbolicReference.__hash__c                 C   r9   )z
        :return:
            In case of symbolic references, the shortest assumable name is the path
            itself.
        r:   r<   r0   r0   r1   r/   c   s   
zSymbolicReference.namec                 C   s   t t| j| j| jS r6   )r   r2   r%   r&   r<   r0   r0   r1   abspathl      zSymbolicReference.abspathc                 C   s   t j|jdS )Npacked-refs)osr&   joinr.   )clsr%   r0   r0   r1   _get_packed_refs_pathp   s   z'SymbolicReference._get_packed_refs_pathc              	   c   s    zWt | |dddB}|D ]5}| }|sq|dr-|dr,d|vr,td| q|d d	kr4qttttf t|	d
dV  qW d   W dS 1 sQw   Y  W dS  t
yb   Y dS w )zReturn an iterator yielding pairs of sha1/path pairs (as strings) for the
        corresponding refs.

        :note:
            The packed refs file will be kept open as long as we iterate.
        rtUTF-8encoding#z# pack-refs with:peeledz-PackingType of packed-Refs not understood: %rr   ^    N)openrO   strip
startswith	TypeErrorr   r   r;   tuplesplitOSError)rN   r%   fpliner0   r0   r1   _iter_packed_refst   s&   
	"&z#SymbolicReference._iter_packed_refsref_pathc                 C   s    	 |  ||\}}|dur|S q)a  
        :return:
            hexsha stored in the reference at the given `ref_path`, recursively
            dereferencing all intermediate references as required

        :param repo:
            The repository containing the reference at `ref_path`.
        TN)_get_ref_info)rN   r%   rc   hexshar0   r0   r1   dereference_recursive   s
   z'SymbolicReference.dereference_recursivec                 C   sz  d}d}t | D ]t}|dv rtd|  d|dkr7|du s"|dkr*td|  d|dkr6td|  dnA|dkrT|dkrGtd|  d	|du rStd|  d
n$|dkrd|dkrdtd|  dt|dk spt|dkrxtd|  d|}|}q|dkrtd|  d|dkrtd|  d|dkr|du rtd|  dtdd t | dD rtd|  ddS )z|Check a ref name for validity.

        This is based on the rules described in :manpage:`git-check-ref-format(1)`.
        Nz ~^:?*[\zInvalid reference 'z': references cannot contain spaces, tildes (~), carets (^), colons (:), question marks (?), asterisks (*), open brackets ([) or backslashes (\)./z<': references cannot start with a period (.) or contain '/.'z!': references cannot contain '..'z!': references cannot contain '//'z3': references cannot start with forward slashes '/'{@z!': references cannot contain '@{'       z5': references cannot contain ASCII control charactersz*': references cannot end with a period (.)z1': references cannot end with a forward slash (/)z': references cannot be '@'c                 s   s    | ]}| d V  qdS )z.lockN)endswith).0	componentr0   r0   r1   	<genexpr>       z:SymbolicReference._check_ref_name_valid.<locals>.<genexpr>zJ': references cannot have slash-separated components that end with '.lock')r;   
ValueErrorordanyr^   )rc   previousone_before_previouscr0   r0   r1   _check_ref_name_valid   sP   



z'SymbolicReference._check_ref_name_validc           	      C   s  |r|  | d}t||}z2ttj|t|ddd}|  }W d   n1 s.w   Y  |	 }t
|dks?J W n ty\   | |D ]\}}||krUqL||f} Y nw |du rgtd| |d dkrsd|d fS |j|d r|d dfS td	| )

        :return:
            *(str(sha), str(target_ref_path))*, where:

            * *sha* is of the file at rela_path points to if available, or ``None``.
            * *target_ref_path* is the reference we point to, or ``None``.
        NrP   rQ   rR   r   zReference at %r does not existzref:rX   z-Failed to parse reference information from %r)rx   r2   rY   rL   r&   rM   r;   readrstripr^   lenr_   rb   rr   re_hexsha_onlymatch)	rN   r%   rc   tokensrepodirr`   valueshar&   r0   r0   r1   _get_ref_info_helper   s2   

z&SymbolicReference._get_ref_info_helperc                 C   s   |  ||S )ry   )r   )rN   r%   rc   r0   r0   r1   rd     s   	zSymbolicReference._get_ref_infoc                 C   s   t | jt| | j| jS )z
        :return:
            The object our ref currently refers to. Refs can be cached, they will always
            point to the actual object as it gets re-created on each query.
        )r   new_from_shar%   r   rf   r&   r<   r0   r0   r1   _get_object  s   zSymbolicReference._get_objectr   c                 C   s4   |   }|jdkr|j}|jtjkrtd| |S )z
        :return:
            :class:`~git.objects.commit.Commit` object we point to. This works for
            detached and non-detached :class:`SymbolicReference` instances. The symbolic
            reference will be dereferenced recursively.
        tagz<Symbolic Reference pointed to object %r, commit was required)r   typeobjectr   r\   )r7   objr0   r0   r1   _get_commit"  s   
zSymbolicReference._get_commitcommitlogmsgc              
   C   s   d}t |tr|jtjk}n/t |tr|jjtjk}n"z| j|jtjk}W n tt	fy< } zt
d| |d}~ww |rEt
d| | || | S )a.  Like :meth:`set_object`, but restricts the type of object to be a
        :class:`~git.objects.commit.Commit`.

        :raise ValueError:
            If `commit` is not a :class:`~git.objects.commit.Commit` object, nor does it
            point to a commit.

        :return:
            self
        FzInvalid object: %sNzNeed commit, got %r)
isinstancer   r   r   r   r   r%   	rev_parser   r   rr   
set_object)r7   r   r   invalid_typeer0   r0   r1   
set_commit3  s   

zSymbolicReference.set_commitr   c                 C   sR   t |tr|j}d}z| j}W n	 ty   Y nw |r!| ||S |  ||S )ax  Set the object we point to, possibly dereference our symbolic reference
        first. If the reference does not exist, it will be created.

        :param object:
            A refspec, a :class:`SymbolicReference` or an
            :class:`~git.objects.base.Object` instance.

            * :class:`SymbolicReference` instances will be dereferenced beforehand to
              obtain the git object they point to.
            * :class:`~git.objects.base.Object` instances must represent git objects
              (:class:`~git.types.AnyGitObject`).

        :param logmsg:
            If not ``None``, the message will be used in the reflog entry to be written.
            Otherwise the reflog is not altered.

        :note:
            Plain :class:`SymbolicReference` instances may not actually point to objects
            by convention.

        :return:
            self
        T)r   r   r   is_detachedrr   set_reference_get_referencer   )r7   r   r   r   r0   r0   r1   r   Y  s   

zSymbolicReference.set_objectzQuery or set commits directly)docz-Return the object our ref currently refers toc                 C   s:   |  | j| j\}}|du rtd| |f | | j|S )z
        :return:
            :class:`~git.refs.reference.Reference` object we point to

        :raise TypeError:
            If this symbolic reference is detached, hence it doesn't point to a
            reference, but to a commit.
        Nz6%s is a detached symbolic reference as it points to %r)rd   r%   r&   r\   	from_path)r7   r   target_ref_pathr0   r0   r1   r     s   	z SymbolicReference._get_referencerefc           
   
   C   sb  d}d}t |trd|j }n9t |tr|}|j}n.t |trBz| j|d }|j}W n tt	fyA } zt
d| |d}~ww t
d| |dur[| jr[|jtjkr[td| d}|durtz| jj}W n t
ys   tj}Y nw | j}t|dd	 t|}|jddd
}	z|	|dd  |  W n ty   |   w |dur| || | S )a  Set ourselves to the given `ref`.

        It will stay a symbol if the `ref` is a :class:`~git.refs.reference.Reference`.

        Otherwise a git object, specified as a :class:`~git.objects.base.Object`
        instance or refspec, is assumed. If it is valid, this reference will be set to
        it, which effectively detaches the reference if it was a purely symbolic one.

        :param ref:
            A :class:`SymbolicReference` instance, an :class:`~git.objects.base.Object`
            instance (specifically an :class:`~git.types.AnyGitObject`), or a refspec
            string. Only if the ref is a :class:`SymbolicReference` instance, we will
            point to it. Everything else is dereferenced to obtain the actual object.

        :param logmsg:
            If set to a string, the message will be used in the reflog.
            Otherwise, a reflog entry is not written for the changed reference.
            The previous commit of the entry will be the commit we point to now.

            See also: :meth:`log_append`

        :return:
            self

        :note:
            This symbolic reference will not be dereferenced. For that, see
            :meth:`set_object`.
        Nzref: %sz^{}z Could not extract object from %szUnrecognized Value: %rzRequire commit, got %r    T)is_file)writestreamzutf-8   
)r   r   r&   r   re   r;   r%   r   r   r   rr   _points_to_commits_onlyr   r   r\   r   binshaNULL_BIN_SHArI   r
   r	   rY   r   encodeBaseExceptionrollback
log_append)
r7   r   r   write_valuer   r   	oldbinshafpathlfdfdr0   r0   r1   r     sN   !




zSymbolicReference.set_referencer   	referencez!Returns the Reference we point toc              	   C   s&   z| j  W dS  ttfy   Y dS w )z
        :return:
            ``True`` if the reference is valid, hence it can be read and points to a
            valid object or reference.
        FT)r   r_   rr   r<   r0   r0   r1   is_valid  s   zSymbolicReference.is_validc                 C   s"   z| j  W dS  ty   Y dS w )z
        :return:
            ``True`` if we are a detached reference, hence we point to a specific commit
            instead to another reference.
        FT)r   r\   r<   r0   r0   r1   r     s   zSymbolicReference.is_detachedr   c                 C   s   t t | S )ad  
        :return:
            :class:`~git.refs.log.RefLog` for this reference.
            Its last entry reflects the latest change applied to this reference.

        :note:
            As the log is parsed every time, its recommended to cache it for use instead
            of calling this method repeatedly. It should be considered read-only.
        )r   	from_filer&   r<   r0   r0   r1   log  s   
zSymbolicReference.logr   message	newbinshar!   c                 C   s^   z| j j}W n ty   | j }Y nw |du r| j j}|du r#d}t|t| |||S )a  Append a logentry to the logfile of this ref.

        :param oldbinsha:
            Binary sha this ref used to point to.

        :param message:
            A message describing the change.

        :param newbinsha:
            The sha the ref points to now. If None, our current commit sha will be used.

        :return:
            The added :class:`~git.refs.log.RefLogEntry` instance.
        Nr4   )	r   	committerrr   r%   config_readerr   r   append_entryr&   )r7   r   r   r   committer_or_readerr0   r0   r1   r   !  s   zSymbolicReference.log_appendr+   c                 C   s   t t | |S )a  
        :return:
            :class:`~git.refs.log.RefLogEntry` at the given index

        :param index:
            Python list compatible positive or negative index.

        :note:
            This method must read part of the reflog during execution, hence it should
            be used sparingly, or only if you need just one index. In that case, it will
            be faster than the :meth:`log` method.
        )r   entry_atr&   )r7   r+   r0   r0   r1   	log_entryE  s   zSymbolicReference.log_entryc                 C   sD   t |tr|j}|}| js|S t|| jd s d| j|f }|S )a  
        :return:
            String with a full repository-relative path which can be used to initialize
            a :class:`~git.refs.reference.Reference` instance, for instance by using
            :meth:`Reference.from_path <git.refs.reference.Reference.from_path>`.
        rh   z%s/%s)r   r   r&   _common_path_defaultr;   r[   )rN   r&   full_ref_pathr0   r0   r1   to_full_pathT  s   
zSymbolicReference.to_full_pathc                 C   sb  |  |}tj|j|}tj|rt| n| |}zrt|dB}g }d}d}	|D ]1}
|
	t
}|d\}}}| }|dsI||krZ|	rR|	rZ|dsZ|| d}	q-d}d}	q-W d   n1 siw   Y  |rt|d}|d	d
 |D  W d   n1 sw   Y  W n	 ty   Y nw t| ||}tj|rt| dS dS )af  Delete the reference at the given path.

        :param repo:
            Repository to delete the reference from.

        :param path:
            Short or full path pointing to the reference, e.g. ``refs/myreference`` or
            just ``myreference``, hence ``refs/`` is implied.
            Alternatively the symbolic reference to be deleted.
        rbFrW   rT   rV   TNwbc                 s   s    | ]}| tV  qd S r6   )r   r   )rn   ra   r0   r0   r1   rp     rq   z+SymbolicReference.delete.<locals>.<genexpr>)r   rL   r&   rM   r.   existsremoverO   rY   decoder   	partitionrZ   r[   append
writelinesr_   r   isfile)rN   r%   r&   r   abs_pathpack_file_pathreader	new_linesmade_changedropped_last_line
line_bytesra   _line_refr   reflog_pathr0   r0   r1   deletee  sP   



zSymbolicReference.deleterN   resolveforcec                 C   s   t ||}| |}tj||}	|}
|r|t|}
|sctj|	rct|
}t|
t	r2t|
j}|s8d| }t
|	d}| t }W d   n1 sQw   Y  ||krctd|||f | ||}||
| |S )a3  Internal method used to create a new symbolic reference.

        If `resolve` is ``False``, the reference will be taken as is, creating a proper
        symbolic reference. Otherwise it will be resolved to the corresponding object
        and a detached symbolic reference will be created instead.
        zref: r   NzDReference at %r does already exist, pointing to %r, requested was %r)r2   r   rL   r&   rM   r   r;   r   r   r   rY   rz   r   r   rZ   r_   r   )rN   r%   r&   r   r   r   r   r-   r   abs_ref_pathtargettarget_datar   existing_datar   r0   r0   r1   _create  s0   




zSymbolicReference._creater(   kwargsc                 K   s   |  ||| j|||S )aF  Create a new symbolic reference: a reference pointing to another reference.

        :param repo:
            Repository to create the reference in.

        :param path:
            Full path at which the new symbolic reference is supposed to be created at,
            e.g. ``NEW_HEAD`` or ``symrefs/my_new_symref``.

        :param reference:
            The reference which the new symbolic reference should point to.
            If it is a commit-ish, the symbolic ref will be detached.

        :param force:
            If ``True``, force creation even if a symbolic reference with that name
            already exists. Raise :exc:`OSError` otherwise.

        :param logmsg:
            If not ``None``, the message to append to the reflog.
            If ``None``, no reflog entry is written.

        :return:
            Newly created symbolic reference

        :raise OSError:
            If a (Symbolic)Reference with the same name but different contents already
            exists.

        :note:
            This does not alter the current HEAD, index or working tree.
        )r   _resolve_ref_on_create)rN   r%   r&   r   r   r   r   r0   r0   r1   create  s   )zSymbolicReference.createnew_pathc           
      C   s  |  |}| j|kr| S tjt| j||}tjt| j| j| j}tj|rq|slt|d}| 	 }W d   n1 sBw   Y  t|d}| 	 }W d   n1 s]w   Y  ||krlt
d| t| tj|}	tj|	st|	 t|| || _| S )aw  Rename self to a new path.

        :param new_path:
            Either a simple name or a full path, e.g. ``new_name`` or
            ``features/new_name``.
            The prefix ``refs/`` is implied for references and will be set as needed.
            In case this is a symbolic ref, there is no implied prefix.

        :param force:
            If ``True``, the rename will succeed even if a head with the target name
            already exists. It will be overwritten in that case.

        :return:
            self

        :raise OSError:
            If a file at path but with different contents already exists.
        r   NzFile at path %r already exists)r   r&   rL   rM   r2   r%   r   rY   rz   rZ   r_   r   dirnameisdirmakedirsrename)
r7   r   r   new_abs_pathcur_abs_pathfd1f1fd2f2dnamer0   r0   r1   r     s,   



zSymbolicReference.renamecommon_pathc              	   c   s   |d u r| j }t }tt|j|D ]<\}}}d|tjvr1dd |D }|r1dg|dd < |D ]}|dkr:q3tt	||}	|
|	t|jd d q3q| |D ]\}
}|t|rf|
| qVt|D ]}z	| ||V  W qk ty   Y qkw d S )Nrefsc                 S   s   g | ]}|d kr|qS )r   r0   )rn   dr0   r0   r1   
<listcomp>6  s    z1SymbolicReference._iter_items.<locals>.<listcomp>r   rK   rh   r4   )r   setrL   walkr   r.   r^   sepr   r   addreplacerb   r[   r;   sortedr   rr   )rN   r%   r   
rela_pathsrootdirsfilesrefs_idfr   _sha	rela_pathr&   r0   r0   r1   _iter_items*  s4   	
zSymbolicReference._iter_itemsargsc                 O   s   dd |  ||D S )a  Find all refs in the repository.

        :param repo:
            The :class:`~git.repo.base.Repo`.

        :param common_path:
            Optional keyword argument to the path which is to be shared by all returned
            Ref objects.
            Defaults to class specific portion if ``None``, ensuring that only refs
            suitable for the actual class are returned.

        :return:
            A list of :class:`SymbolicReference`, each guaranteed to be a symbolic ref
            which is not detached and pointing to a valid ref.

            The list is lexicographically sorted. The returned objects are instances of
            concrete subclasses, such as :class:`~git.refs.head.Head` or
            :class:`~git.refs.tag.TagReference`.
        c                 s   s$    | ]}|j tu s|js|V  qd S r6   )r?   r   r   )rn   rr0   r0   r1   rp   m  s   " z/SymbolicReference.iter_items.<locals>.<genexpr>)r   )rN   r%   r   r   r   r0   r0   r1   
iter_itemsR  s   zSymbolicReference.iter_itemsc           
   	   C   s   |st d| ddlm}m}m}m}m} |||||tfD ]!}z|||}	|	jtu r2|	j	r2t d|	W   S  t y?   Y qw t d| )a  Make a symbolic reference from a path.

        :param path:
            Full ``.git``-directory-relative path name to the Reference to instantiate.

        :note:
            Use :meth:`to_full_path` if you only have a partial path of a known
            Reference type.

        :return:
            Instance of type :class:`~git.refs.reference.Reference`,
            :class:`~git.refs.head.Head`, or :class:`~git.refs.tag.Tag`, depending on
            the given path.
        zCannot create Reference from %rrX   )r(   r   r   r   r    z$SymbolicRef was detached, we drop itz8Could not find reference type suitable to handle path %r)
rr   r4   r(   r   r   r   r    r   r?   r   )
rN   r%   r&   r(   r   r   r   r    ref_typeinstancer0   r0   r1   r   o  s&   

zSymbolicReference.from_pathc                 C   s   t | j| jd S )zB:return: True if this symbolic reference points to a remote branchrh   )r;   r&   r[   _remote_common_path_defaultr<   r0   r0   r1   	is_remote  rJ   zSymbolicReference.is_remote)F)r'   r   r6   )r'   r   )r'   r   )r(   NF)Ar@   
__module____qualname____doc__	__slots__r   r   r   r   _id_attribute_r   boolr8   r;   r=   rA   r   rE   rF   intrH   propertyr/   rI   classmethodrO   r   r   rb   r   rf   staticmethodrx   r   rd   r   r   r   r   r   r   r   r   r   __annotations__r   r   r   r   r   bytesr   r   r   r   r   r#   r   r   r   r   r   r   r   r   r0   r0   r0   r1   r   <   sR  
  ' /
/8




)

-


S



$;

+

*2
'
 ,)/__all__rL   	gitdb.excr   r   
git.compatr   git.objects.baser   git.objects.commitr   git.refs.logr   git.utilr	   r
   r   r   r   r   typingr   r   r   r   r   r   r   r   r   	git.typesr   r   
git.configr   r   git.refsr   r   r   r    r!   git.repor"   r#   r2   r   r0   r0   r0   r1   <module>   s&    ,