o
    ﯪg                  	   @   s  U d dl Z g dZe jdkred d dlmZ d dlZd dlmZ d dl	Z	d dl
Z
d dlZd dl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Zd dlmZmZ d dl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%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5 e1rd d
l6m7Z7 d dl8m9Z9m:Z: d dl;m<Z< d dl=m>Z> d dl?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZH e2de3d ddZIe
JeKZLdeMdeNdeNfddZOdeMdeNdeNfddZPePddZQePddZRe2dZSde'deSf de'deSf fdd ZTejUd!eDde)eDddf fd"d#ZVejUdeMd$eMde)d% fd&d'ZWd(eDddfd)d*ZXd(eDddfd+d,ZYdd.e&d/e&d0eZdeZfd1d2Z[d3eDd4eDdeDfd5d6Z\e jdkrwd(eDdeDfd7dZ]d(eDdeMfd8d9Z^e]Z_nd(eDdeMfd:d9Z^e^Z_d3eDd4eDdeDfd;d<Z`dd(eDd>eNdeNfd?d@Zade/eM fdAdBZbddCeMd(e-eD de,eM fdDdEZcdFe-eM d(eMdeMfdGdHZdeedIdJdK d=feedLedd=feedMedd=feedNejfdOdK dfeedPdQdK d=ffZge0e0e.eM e'eNf df ehdR< d(eMdeMfdSdTZieedUZjd(eDdeMfdVdWZki Zle(eMe-eN f ehdX< dYeMdeNfdZd[Zme5dYddeCd= fd\d]Zne5dYeDdeNfd^d]ZndYe3deDf deNfd_d]ZndeMfd`daZodbe3ejpdcf dde$ddfdedfZqe5dd4ddgeNddfdhdiZre5dd4eDdgeNdeMfdjdiZrdd4e3deDf dgeNde-eD fdkdiZrdle/eM de,eM fdmdnZsG dodp dpZtG dqdr dretZuG dsdt dtZvG dudv dvZwG dwdx dxZxG dydz dzZyG d{d| d|eyZzG d}d~ d~e,eI Z{eHG dd deEZ|G dd de}Z~G dd de~dZdS )    N)stream_copy	join_pathto_native_path_linuxjoin_path_nativeStatsIndexFileSHA1WriterIterableObjIterableListBlockingLockFileLockFileActorget_user_idassure_directory_existsRemoteProgressCallableRemoteProgressrmtreeunbare_repoHIDE_WINDOWS_KNOWN_ERRORSwin32to_native_path_windows)abstractmethod)wraps)urlsplit
urlunsplit)		LazyMixinLockedFD
bin_to_hexfile_contents_rofile_contents_ro_filepath
hex_to_binmake_sha
to_bin_sha
to_hex_sha)AnyAnyStrBinaryIOCallableDict	GeneratorIOIteratorListOptionalPatternSequenceTupleTYPE_CHECKINGTypeVarUnioncastoverload)Git)GitConfigParserSectionConstraint)Remote)Repo)	Files_TDHas_id_attributeHSH_TDLiteralPathLikeProtocolSupportsIndexTotal_TDruntime_checkableT_IterableObj)r   r;   T)bound	covariantnamedefaultreturnc                 C   sj   zt j|  }W n ty   | Y S w td|  |  }|dv r%dS |dv r+dS td| || |S )zRead a boolean flag from an environment variable.

    :return:
        The flag, or the `default` value if absent or ambiguous.
    zlThe %s environment variable is deprecated. Its effect has never been documented and changes without warning.>    0nofalseF>   1yestrueTz-%s has unrecognized value %r, treating as %r.)osenvironKeyError_loggerwarningstriplower)rF   rG   valueadjusted_value rY   D/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/git/util.py_read_env_flags   s    r[   c                 C   s   t jdko	t| |S )a  Read a boolean flag from an environment variable on Windows.

    :return:
        On Windows, the flag, or the `default` value if absent or ambiguous.
        On all other operating systems, ``False``.

    :note:
        This only accesses the environment on Windows.
    r   )sysplatformr[   )rF   rG   rY   rY   rZ   _read_win_env_flag   s   
r^   r   HIDE_WINDOWS_FREEZE_ERRORSTfunc.c              	      s8   ddl m  tdddtdtdtf fdd	}|S )
ztMethods with this decorator raise :exc:`~git.exc.InvalidGitRepositoryError` if
    they encounter a bare repository.   )InvalidGitRepositoryErrorselfr8   argskwargsrH   c                    s,   | j jr dj | g|R i |S )Nz/Method '%s' cannot operate on bare repositories)repobare__name__rd   re   rf   rc   ra   rY   rZ   wrapper   s   zunbare_repo.<locals>.wrapper)excrc   r   r#   r`   )ra   rl   rY   rk   rZ   r      s   "r   new_dirc              	   c   s8    t  }t |  z| V  W t | dS t | w )zContext manager to temporarily change directory.

    This is similar to :func:`contextlib.chdir` introduced in Python 3.11, but the
    context manager object returned by a single call to this function is not reentrant.
    N)rP   getcwdchdir)rn   old_dirrY   rY   rZ   cwd   s   
rr   rW   )NNNc              	   c   s`    t | }|t j| < zdV  W |du rt j| = dS |t j| < dS |du r*t j| = w |t j| < w )z=Context manager to temporarily patch an environment variable.N)rP   getenvrQ   )rF   rW   	old_valuerY   rY   rZ   	patch_env   s   

ru   pathc                 C   s`   dt dtdtddfdd}tjdkrt|  dS tjd	kr'tj| |d
 dS tj| |d dS )zRemove the given directory tree recursively.

    :note:
        We use :func:`shutil.rmtree` but adjust its behaviour to see whether files that
        couldn't be deleted are read-only. Windows will not remove them in that case.
    functionrv   _excinforH   Nc              
   S   sX   t |tj z| | W dS  ty+ } ztr&ddlm} |d| | d}~ww )zuCallback for :func:`shutil.rmtree`.

        This works as either a ``onexc`` or ``onerror`` style callback.
        r   )SkipTestz%FIXME: fails with: PermissionError
  N)rP   chmodstatS_IWUSRPermissionErrorr   unittestry   )rw   rv   rx   exry   rY   rY   rZ   handler   s   zrmtree.<locals>.handlerr   )      )onexc)onerror)r&   r>   r#   r\   r]   shutilr   version_info)rv   r   rY   rY   rZ   r      s   

r   c                 C   s2   t | rtjdkrt| d t|  dS dS )zWEnsure file deleted also on *Windows* where read-only files need special
    treatment.r   i  N)ospisfiler\   r]   rP   rz   removerv   rY   rY   rZ   rmfile   s
   

r      sourcedestination
chunk_sizec                 C   s:   d}	 |  |}|| |t|7 }t||k r	 |S q)zCopy all data from the `source` stream into the `destination` stream in chunks
    of size `chunk_size`.

    :return:
        Number of bytes written
    r   )readwritelen)r   r   r   brchunkrY   rY   rZ   r      s   

r   apc                 G   sh   t | }|D ]+}t |}|sq|dr||dd 7 }q|dks&|dr+||7 }q|d| 7 }q|S )zmJoin path tokens together similar to osp.join, but always use ``/`` instead of
    possibly ``\`` on Windows./rb   NrI   )str
startswithendswith)r   r   rv   brY   rY   rZ   r     s   

r   c                 C      t | } | ddS )Nr   \r   replacer   rY   rY   rZ   r   $     c                 C   r   )Nr   r   r   r   rY   rY   rZ   r   (  r   r   c                 C   s   t | S N)r   r   rY   rY   rZ   r   /  s   c                 G   s   t t| g|R  S )zLike :func:`join_path`, but makes sure an OS native path is returned.

    This is only needed to play it safe on Windows and to ensure nice paths that only
    use ``\``.
    )to_native_pathr   )r   r   rY   rY   rZ   r   5  s   r   Fis_filec                 C   s.   |rt | } t | stj| dd dS dS )a$  Make sure that the directory pointed to by path exists.

    :param is_file:
        If ``True``, `path` is assumed to be a file and handled correctly.
        Otherwise it must be a directory.

    :return:
        ``True`` if the directory was created, ``False`` if it already existed.
    T)exist_okF)r   dirnameisdirrP   makedirs)rv   r   rY   rY   rZ   r   >  s   


r   c                  C   s>   t jdd } | rtdd | t jD S tjdkrdS dS )NPATHEXTc                 s   s    | ]}|  V  qd S r   )upper).0r   rY   rY   rZ   	<genexpr>T  s    z&_get_exe_extensions.<locals>.<genexpr>r   )z.BATz.COMz.EXErY   )rP   rQ   gettuplesplitpathsepr\   r]   )r   rY   rY   rZ   _get_exe_extensionsQ  s   
r   programc                    s   t  dtdtffdd}g }|stjd }t|tjD ]'}|d}|rFt	||   g fddD  D ]}||rE|
| q:q|S )	a6  Perform a path search to assist :func:`is_cygwin_git`.

    This is not robust for general use. It is an implementation detail of
    :func:`is_cygwin_git`. When a search following all shell rules is needed,
    :func:`shutil.which` can be used instead.

    :note:
        Neither this function nor :func:`shutil.which` will predict the effect of an
        executable search on a native Windows system due to a :class:`subprocess.Popen`
        call without ``shell=True``, because shell and non-shell executable search on
        Windows differ considerably.
    fpathrH   c                    s>   t  ot tjotjdkp pt fddD S )Nr   c                 3   s    | ]
}   |V  qd S r   )r   r   )r   extr   rY   rZ   r   p  s    z,py_where.<locals>.is_exec.<locals>.<genexpr>)r   r   rP   accessX_OKr\   r]   anyr   )winprog_extsr   rZ   is_execk  s
   
$zpy_where.<locals>.is_execPATH"c                    s   g | ]}d  |f qS )z%s%srY   )r   e)exe_pathrY   rZ   
<listcomp>{  s    zpy_where.<locals>.<listcomp>)r   r   boolrP   rQ   r   r   rU   r   joinappend)r   rv   r   progsfolderfrY   )r   r   rZ   py_where[  s   	


r   drivec                 C   st   t |r
| s
|}n&|ot t t |}t |r&| r!|}nt|}n
| r0d|  |f }t|}|ddS )Nz/proc/cygdrive/%s/%sr   r   )	r   isabsnormpath
expandvars
expandusercygpathrV   r   r   )r   rv   r   p_strrY   rY   rZ   
_cygexpath  s   

r   z*\\\\\?\\UNC\\([^\\]+)\\([^\\]+)(?:\\(.*))?c                 C   s   d| || ddf S )Nz
//%s/%s/%sr   r   )r   )servershare	rest_pathrY   rY   rZ   <lambda>  s    r   z\\\\\?\\(\w):[/\\](.*)z(\w):[/\\](.*)z	file:(.*)c                 C      | S r   rY   )r   rY   rY   rZ   r         z(\w{2,}:.*)c                 C   r   r   rY   )urlrY   rY   rZ   r     r   _cygpath_parsersc                 C   s\   t | } | ds,tD ]\}}}|| }|r&||  } |r#t| }  | S qtd| } | S )zJUse :meth:`git.cmd.Git.polish_url` instead, that works on any environment.)z	/cygdrivez//z/proc/cygdriveN)r   r   r   matchgroupsr   r   )rv   regexparserrecurser   rY   rY   rZ   r     s   


r   z(?:/proc)?/cygdrive/(\w)(/.*)?c                 C   sB   t | } t| }|r| \}}d| |pdf } | ddS )Nz%s:%srI   r   r   )r   _decygpath_regexr   r   r   r   )rv   mr   r   rY   rY   rZ   	decygpath  s   
r   _is_cygwin_cachegit_executablec           	   
   C   s   t | }|d u rZd}z2t| }|s"t| }|r t|d nd}t|d}tj|gtjdd}|	 \}}d|v }W n t
yU } ztd| W Y d }~nd }~ww |t | < |S )	NFr   rI   unameT)stdoutuniversal_newlinesCYGWINz/Failed checking if running in CYGWIN due to: %r)r   r   r   r   r   r   
subprocessPopenPIPEcommunicate	ExceptionrS   debug)	r   	is_cygwingit_dirres	uname_cmdprocess	uname_out_r   rY   rY   rZ   _is_cygwin_git  s$   

r   c                 C      d S r   rY   r   rY   rY   rZ   is_cygwin_git     r   c                 C   r   r   rY   r   rY   rY   rZ   r     r   c                 C   s&   t jdkrdS | d u rdS tt| S )Nr   F)r\   r]   r   r   r   rY   rY   rZ   r     s
   
c                   C   s   dt  t f S )zM:return: String identifying the currently active system user as ``name@node``z%s@%s)getpassgetuserr]   noderY   rY   rY   rZ   r     s   r   proczGit.AutoInterruptrf   c                 K   s   | j di | dS )zXWait for the process (clone, fetch, pull or push) and handle its errors
    accordingly.NrY   )wait)r   rf   rY   rY   rZ   finalize_process  s   r   expand_varsc                 C   r   r   rY   r   r   rY   rY   rZ   expand_path  r   r   c                 C   r   r   rY   r   rY   rY   rZ   r     s   c                 C   sT   t | tjr
|  S zt| } |rt| } tt| W S  t	y)   Y d S w r   )

isinstancepathlibPathresolver   r   r   r   abspathr   r   rY   rY   rZ   r     s   

cmdlinec              	   C   s   g }t | D ]L\}}|| z:t|}|jdu r |jdu r W q|jdur1|j|j|jdd}|jdurB|j|j|jdd}t|||< W q t	yR   Y qw |S )a>  Parse any command line argument and if one of the elements is an URL with a
    username and/or password, replace them by stars (in-place).

    If nothing is found, this just returns the command line as-is.

    This should be used for every log line that print a command line, as well as
    exception messages.
    Nz*****)netloc)
	enumerater   r   passwordusername_replacer  r   r   
ValueError)r  new_cmdlineindexto_parser   rY   rY   rZ   remove_password_if_present  s    	


r  c                   @   s   e Zd ZU dZdZeed< dd eeD \	ZZ	Z
ZZZZZZee	B Ze ZdZdZdZed	Zed
ZdddZdeddfddZdeegdf fddZdeddfddZ 		ddede!ee"f de!ee"df deddf
ddZ#dS )r   zHandler providing an interface to parse progress information emitted by
    :manpage:`git-push(1)` and :manpage:`git-fetch(1)` and to dispatch callbacks
    allowing subclasses to react to the progress.	   _num_op_codesc                 C   s   g | ]}d |> qS )rb   rY   )r   xrY   rY   rZ   r   C  s    zRemoteProgress.<listcomp>zdone.z, )	_cur_line	_seen_opserror_linesother_linesz%(remote: )?([\w\s]+):\s+()(\d+)()(.*)z2(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)rH   Nc                 C   s   g | _ d | _g | _g | _d S r   )r  r  r  r  rd   rY   rY   rZ   __init__S  s   
zRemoteProgress.__init__linec                 C   s  t |tr|d}n|}|| _| jdr| j| j dS d\}}| j|}|du r3| j	|}|sB| 
| | j| dS d}| \}}}	}}}
|dkrX|| jO }nC|dkrb|| jO }n9|dkrl|| jO }n/|d	krv|| jO }n%|d
kr|| jO }n|dkr|| jO }n|dkr|| jO }n| 
| dS || jvr| j| || jO }|
du rd}
|
 }
|
| jr|| jO }|
dt| j  }
|
| j}
| ||ot||ot||
 dS )a^  Parse progress information from the given line as retrieved by
        :manpage:`git-push(1)` or :manpage:`git-fetch(1)`.

        - Lines that do not contain progress info are stored in :attr:`other_lines`.
        - Lines that seem to contain an error (i.e. start with ``error:`` or ``fatal:``)
          are stored in :attr:`error_lines`.
        zutf-8)zerror:zfatal:N)NNr   zCounting objectszCompressing objectszWriting objectszReceiving objectszResolving deltaszFinding sourceszChecking out filesrI   )r   bytesdecoder  r   r  r   re_op_relativer   re_op_absoluteline_droppedr  r   COUNTINGCOMPRESSINGWRITING	RECEIVING	RESOLVINGFINDING_SOURCESCHECKING_OUTr  BEGINrU   r   
DONE_TOKENENDr   TOKEN_SEPARATORupdatefloat)rd   r  line_str	cur_count	max_countr   op_code_remoteop_name_percentmessagerY   rY   rZ   _parse_progress_lineY  sb   







z#RemoteProgress._parse_progress_linec                    s   dt ddf fdd}|S )z
        :return:
            A progress handler suitable for :func:`~git.cmd.handle_process_output`,
            passing lines on to this progress handler in a suitable format.
        r  rH   Nc                    s     |  S r   )r3  rstrip)r  r  rY   rZ   r     s   z3RemoteProgress.new_message_handler.<locals>.handler)r$   )rd   r   rY   r  rZ   new_message_handler  s   z"RemoteProgress.new_message_handlerc                 C      dS )zICalled whenever a line could not be understood and was therefore dropped.NrY   )rd   r  rY   rY   rZ   r    s   zRemoteProgress.line_droppedrI   r.  r,  r-  r2  c                 C   r6  )a  Called whenever the progress changes.

        :param op_code:
            Integer allowing to be compared against Operation IDs and stage IDs.

            Stage IDs are :const:`BEGIN` and :const:`END`. :const:`BEGIN` will only be
            set once for each Operation ID as well as :const:`END`. It may be that
            :const:`BEGIN` and :const:`END` are set at once in case only one progress
            message was emitted due to the speed of the operation. Between
            :const:`BEGIN` and :const:`END`, none of these flags will be set.

            Operation IDs are all held within the :const:`OP_MASK`. Only one Operation
            ID will be active per call.

        :param cur_count:
            Current absolute count of items.

        :param max_count:
            The maximum count of items we expect. It may be ``None`` in case there is no
            maximum number of items or if it is (yet) unknown.

        :param message:
            In case of the :const:`WRITING` operation, it contains the amount of bytes
            transferred. It may possibly be used for other purposes as well.

        :note:
            You may read the contents of the current line in
            :attr:`self._cur_line <_cur_line>`.
        NrY   )rd   r.  r,  r-  r2  rY   rY   rZ   r)    s   $zRemoteProgress.updaterH   NNrI   )$ri   
__module____qualname____doc__r  int__annotations__ranger%  r'  r  r  r   r!  r"  r#  r$  
STAGE_MASKOP_MASKr&  r(  	__slots__recompiler  r  r  r$   r3  r&   r   r5  r  r2   r*  r)  rY   rY   rY   rZ   r   3  sL   
 


Y
r   c                       sD   e Zd ZdZdZdeddf fddZded	eddfd
dZ  Z	S )r   a  A :class:`RemoteProgress` implementation forwarding updates to any callable.

    :note:
        Like direct instances of :class:`RemoteProgress`, instances of this
        :class:`CallableRemoteProgress` class are not themselves directly callable.
        Rather, instances of this class wrap a callable and forward to it. This should
        therefore not be confused with :class:`git.types.CallableProgress`.
    	_callablefnrH   Nc                    s   || _ t   d S r   )rE  superr  )rd   rF  	__class__rY   rZ   r       zCallableRemoteProgress.__init__re   rf   c                 O   s   | j |i | d S r   rD  rj   rY   rY   rZ   r)    s   zCallableRemoteProgress.update)
ri   r9  r:  r;  rA  r&   r  r#   r)  __classcell__rY   rY   rH  rZ   r     s
    	r   c                
   @   s   e Zd ZdZedZedZdZdZ	dZ
dZdZd	Zd
Zdee d	ee dd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defddZdefddZededd fddZe	d'dededed  dd fd!d"Zed'ded  dd fd#d$Zed'ded  dd fd%d&ZdS )(r   zActors hold information about a person acting on the repository. They can be
    committers and authors or anything with a name and an email as mentioned in the git
    log entries.z<(.*)>z(.*) <(.*?)>GIT_AUTHOR_NAMEGIT_AUTHOR_EMAILGIT_COMMITTER_NAMEGIT_COMMITTER_EMAILrF   emailrF   rP  rH   Nc                 C      || _ || _d S r   rQ  )rd   rF   rP  rY   rY   rZ   r       
zActor.__init__otherc                 C   s   | j |j ko| j|jkS r   rQ  rd   rT  rY   rY   rZ   __eq__  s   zActor.__eq__c                 C   s
   | |k S r   rY   rU  rY   rY   rZ   __ne__     
zActor.__ne__c                 C   s   t | j| jfS r   )hashrF   rP  r  rY   rY   rZ   __hash__     zActor.__hash__c                 C   s   | j r| j S dS r8  )rF   r  rY   rY   rZ   __str__"  r[  zActor.__str__c                 C   s   d| j | jf S )Nz<git.Actor "%s <%s>">rQ  r  rY   rY   rZ   __repr__%  r[  zActor.__repr__stringc                 C   sP   | j |}|r| \}}t||S | j|}|r#t|ddS t|dS )zCreate an :class:`Actor` from a string.

        :param string:
            The string, which is expected to be in regular git format::

                John Doe <jdoe@example.com>

        :return:
            :class:`Actor`
        rb   N)name_email_regexsearchr   r   name_only_regexgroup)clsr^  r   rF   rP  rY   rY   rZ   _from_string(  s   

zActor._from_stringenv_name	env_emailconfig_reader)Nr6   r7   c                    s   t dd}d dtffdd dtf fdd}d|| j|fd|| j ffD ]G\}}}}	ztj| }
t|||
 W q' tyn   |d ur`z|d	|}
W n t	yY   |	 }
Y nw t|||
 t
||slt|||	  Y q'w |S )
NrI   rH   c                      s    st    S r   )r   rY   )user_idrY   rZ   default_emailK  s   z(Actor._main_actor.<locals>.default_emailc                      s      dd S )N@r   )r   rY   )ri  rY   rZ   default_nameQ  r[  z'Actor._main_actor.<locals>.default_namerF   rP  user)r   r   	conf_name
conf_emailrP   rQ   setattrrR   r   r   getattr)rc  re  rf  rg  actorrk  attrevarcvarrG   valrY   )ri  rh  rZ   _main_actorA  s.   



zActor._main_actorc                 C      |  | j| j|S )a  
        :return:
            :class:`Actor` instance corresponding to the configured committer. It
            behaves similar to the git implementation, such that the environment will
            override configuration values of `config_reader`. If no value is set at all,
            it will be generated.

        :param config_reader:
            ConfigReader to use to retrieve the values from in case they are not set in
            the environment.
        )rv  env_committer_nameenv_committer_emailrc  rg  rY   rY   rZ   	committeri  s   zActor.committerc                 C   rw  )zSame as :meth:`committer`, but defines the main author. It may be specified
        in the environment, but defaults to the committer.)rv  env_author_nameenv_author_emailrz  rY   rY   rZ   authorx  s   zActor.authorr   ) ri   r9  r:  r;  rB  rC  ra  r_  r|  r}  rx  ry  rm  rn  rA  r,   r   r  r#   r   rV  rW  r<  rZ  r\  r]  classmethodrd  r2   rv  r{  r~  rY   rY   rY   rZ   r     sD    

'r   c                   @   sL   e Zd ZdZdZdedeeef ddfddZ	e
d	d
dedd fddZdS )r   a  Represents stat information as presented by git at the end of a merge. It is
    created from the output of a diff operation.

    Example::

     c = Commit( sha1 )
     s = c.stats
     s.total         # full-stat-dict
     s.files         # dict( filepath : stat-dict )

    ``stat-dict``

    A dictionary with the following keys and values::

      deletions = number of deleted lines as int
      insertions = number of inserted lines as int
      lines = total number of lines changed as int, or deletions + insertions
      change_type = type of change as str, A|C|D|M|R|T|U|X|B

    ``full-stat-dict``

    In addition to the items in the stat-dict, it features additional information::

     files = number of changed files as int
    totalfilesr  r  rH   Nc                 C   rR  r   r  )rd   r  r  rY   rY   rZ   r    rS  zStats.__init__rg   r9   textc                 C   s   dddddi d}|  D ]Z}|d\}}}}|dkr!t|p"d}	|dkr+t|p,d}
|d d  |	7  < |d d  |
7  < |d d	  |	|
 7  < |d d
  d7  < |	|
|	|
 |d}||d
 | < qt|d |d
 S )zCreate a :class:`Stats` object from output retrieved by
        :manpage:`git-diff(1)`.

        :return:
            :class:`git.Stats`
        r   )
insertions	deletionslinesr  r  	-r  r  r  r  r  rb   )r  r  r  change_type)
splitlinesr   r<  rU   r   )rc  rg   r  hshr  r  raw_insertionsraw_deletionsfilenamer  r  
files_dictrY   rY   rZ   _list_from_string  s$   
zStats._list_from_string)ri   r9  r:  r;  rA  rA   r'   r>   r:   r  r  r   r  rY   rY   rY   rZ   r     s    r   c                   @   sb   e Zd ZdZdZdeddfddZdedefd	d
Z	de
fddZde
fddZdefddZdS )r   a  Wrapper around a file-like object that remembers the SHA1 of the data written to
    it. It will write a sha when the stream is closed or if asked for explicitly using
    :meth:`write_sha`.

    Only useful to the index file.

    :note:
        Based on the dulwich project.
    )r   sha1r   rH   Nc                 C   s   || _ td| _d S )N    )r   r    r  )rd   r   rY   rY   rZ   r    rJ  zIndexFileSHA1Writer.__init__datac                 C   s   | j | | j|S r   )r  r)  r   r   )rd   r  rY   rY   rZ   r     s   zIndexFileSHA1Writer.writec                 C   s   | j  }| j| |S r   )r  digestr   r   rd   sharY   rY   rZ   	write_sha  s   
zIndexFileSHA1Writer.write_shac                 C   s   |   }| j  |S r   )r  r   closer  rY   rY   rZ   r    s   
zIndexFileSHA1Writer.closec                 C   s
   | j  S r   )r   tellr  rY   rY   rZ   r    rX  zIndexFileSHA1Writer.tell)ri   r9  r:  r;  rA  r)   r  r$   r<  r   r  r  r  r  rY   rY   rY   rZ   r     s    
r   c                   @   sj   e Zd ZdZdZdeddfddZddd	Zdefd
dZ	de
fddZdddZdddZdddZdS )r   a  Provides methods to obtain, check for, and release a file based lock which
    should be used to handle concurrent access to the same file.

    As we are a utility class to be derived from, we only use protected methods.

    Locks will automatically be released on destruction.
    
_file_path
_owns_lock	file_pathrH   Nc                 C   s   || _ d| _d S )NFr  )rd   r  rY   rY   rZ   r    rS  zLockFile.__init__c                 C   s   |    d S r   )_release_lockr  rY   rY   rZ   __del__     zLockFile.__del__c                 C   s
   d| j  S )z:return: Path to lockfilez%s.lock)r  r  rY   rY   rZ   _lock_file_path  s   
zLockFile._lock_file_pathc                 C   s   | j S )z
        :return:
            True if we have a lock and if the lockfile still exists

        :raise AssertionError:
            If our lock-file does not exist.
        )r  r  rY   rY   rZ   	_has_lock  s   zLockFile._has_lockc              
   C   s   |   rdS |  }t|rtd| j|f zt|dd W d   n1 s*w   Y  W n tyC } ztt||d}~ww d| _	dS )zCreate a lock file as flag for other instances, mark our instance as
        lock-holder.

        :raise IOError:
            If a lock was already present or a lock file could not be written.
        NzILock for file %r did already exist, delete %r in case the lock is illegalw)modeT)
r  r  r   r   IOErrorr  openOSErrorr   r  )rd   	lock_filer   rY   rY   rZ   _obtain_lock_or_raise  s&   

zLockFile._obtain_lock_or_raisec                 C   s   |   S )zThe default implementation will raise if a lock cannot be obtained.

        Subclasses may override this method to provide a different implementation.
        )r  r  rY   rY   rZ   _obtain_lock  s   zLockFile._obtain_lockc                 C   s>   |   sdS |  }zt| W n	 ty   Y nw d| _dS )z Release our lock if we have one.NF)r  r  r   r  r  )rd   lfprY   rY   rZ   r  !  s   
zLockFile._release_lockr7  )ri   r9  r:  r;  rA  r>   r  r  r   r  r   r  r  r  r  rY   rY   rY   rZ   r     s    



r   c                	       sL   e Zd ZdZdZdejfdedede	ddf fd	d
Z
d fddZ  ZS )r
   a  The lock file will block until a lock could be obtained, or fail after a
    specified timeout.

    :note:
        If the directory containing the lock was removed, an exception will be raised
        during the blocking period, preventing hangs as the lock can never be obtained.
    )_check_interval_max_block_timeg333333?r  check_interval_smax_block_time_srH   Nc                    s   t  | || _|| _dS )a  Configure the instance.

        :param check_interval_s:
            Period of time to sleep until the lock is checked the next time.
            By default, it waits a nearly unlimited time.

        :param max_block_time_s:
            Maximum amount of seconds we may lock.
        N)rG  r  r  r  )rd   r  r  r  rH  rY   rZ   r  ;  s   
zBlockingLockFile.__init__c              
      s   t   }|t| j }	 zt   W dS  ty\ } z<t   }tt| 	 s9d| 	 || f }t||||krLd|| | 	 f }t||t 
| j W Y d}~nd}~ww q)zThis method blocks until it obtained the lock, or raises :exc:`IOError` if it
        ran out of time or if the parent directory was not available anymore.

        If this method returns, you are guaranteed to own the lock.
        TzVDirectory containing the lockfile %r was not readable anymore after waiting %g secondsz Waited %g seconds for lock at %rN)timer*  r  rG  r  r  r   r   r   r  sleepr  )rd   	starttimemaxtimer   curtimemsgrH  rY   rZ   r  N  s0   

zBlockingLockFile._obtain_lockr7  )ri   r9  r:  r;  rA  r\   maxsizer>   r*  r<  r  r  rK  rY   rY   rH  rZ   r
   0  s    r
   c                       s   e Zd ZdZdZddededdf fdd	Zddededd
fddZdede	fddZ
dedefddZdeeeeef defddZdeeeeef dd
fddZ  ZS )r	   a  List of iterable objects allowing to query an object by id or by named index::

     heads = repo.heads
     heads.master
     heads['master']
     heads[0]

    Iterable parent objects:

    * :class:`Commit <git.objects.Commit>`
    * :class:`Submodule <git.objects.submodule.base.Submodule>`
    * :class:`Reference <git.refs.reference.Reference>`
    * :class:`FetchInfo <git.remote.FetchInfo>`
    * :class:`PushInfo <git.remote.PushInfo>`

    Iterable via inheritance:

    * :class:`Head <git.refs.head.Head>`
    * :class:`TagReference <git.refs.tag.TagReference>`
    * :class:`RemoteReference <git.refs.remote.RemoteReference>`

    This requires an ``id_attribute`` name to be set which will be queried from its
    contained items to have a means for comparison.

    A prefix can be specified which is to be used in case the id returned by the items
    always contains a prefix that does not matter to the user, so it can be left out.
    _id_attr_prefixrI   id_attrprefixrH   zIterableList[T_IterableObj]c                    s   t  | S r   )rG  __new__)rc  r  r  rH  rY   rZ   r    r  zIterableList.__new__Nc                 C   rR  r   r  )rd   r  r  rY   rY   rZ   r    rS  zIterableList.__init__rr  c              	   C   sb   zt | |}|r|W S W n ttfy   Y nw zt| tt| W dS  ttfy0   Y dS w )NTF)list__contains__AttributeError	TypeErrorrp  r3   r   )rd   rr  rvalrY   rY   rZ   r    s   zIterableList.__contains__c                 C   s8   | j | }| D ]}t|| j|kr|  S qt| |S r   )r  rp  r  r  __getattribute__)rd   rr  itemrY   rY   rZ   __getattr__  s   
zIterableList.__getattr__r  c              
   C   sz   t |tttfsJ dt |trt| |S t |tr tdzt| |W S  ty< } z
t	d| j
|  |d }~ww )N-Index of IterableList should be an int or strzIndex should be an int or strzNo item found with id %r)r   r<  r   slicer  __getitem__r
  rp  r  
IndexErrorr  )rd   r  r   rY   rY   rZ   r    s   

zIterableList.__getitem__c                 C   s   t |ttfsJ dtt|}t |ts;d}| j| }t| D ]\}}t|| j|kr0|} nq |dkr;td| t	
| | d S )Nr  zItem with name %s not found)r   r<  r   r3   r  r  rp  r  r  r  __delitem__)rd   r  delindexrF   ir  rY   rY   rZ   r    s   


zIterableList.__delitem__)rI   )ri   r9  r:  r;  rA  r   r  r  objectr   r  rC   r  r2   r@   r<  r  r  r  rK  rY   rY   rH  rZ   r	   r  s    &r	   c                   @   sf   e Zd ZU dZdZeed< eeddde	de	de
e fd	d
Zeddde	de	dee fddZdS )r   a  Defines an interface for iterable items, so there is a uniform way to retrieve
    and iterate items within the git repository.

    Subclasses:

    * :class:`Submodule <git.objects.submodule.base.Submodule>`
    * :class:`Commit <git.objects.Commit>`
    * :class:`Reference <git.refs.reference.Reference>`
    * :class:`PushInfo <git.remote.PushInfo>`
    * :class:`FetchInfo <git.remote.FetchInfo>`
    * :class:`Remote <git.remote.Remote>`
    rY   _id_attribute_rg   r9   re   rf   rH   c                 O      t d)aS  Find (all) items of this type.

        Subclasses can specify `args` and `kwargs` differently, and may use them for
        filtering. However, when the method is called with no additional positional or
        keyword arguments, subclasses are obliged to to yield all items.

        :return:
            Iterator yielding Items
        To be implemented by SubclassNotImplementedErrorrc  rg   re   rf   rY   rY   rZ   
iter_items  s   zIterableObj.iter_itemsc                 O   ,   t | j}|| j|g|R i | |S )a  Find (all) items of this type and collect them into a list.

        For more information about the arguments, see :meth:`iter_items`.

        :note:
            Favor the :meth:`iter_items` method as it will avoid eagerly collecting all
            items. When there are many items, that can slow performance and increase
            memory usage.

        :return:
            list(Item,...) list of item instances
        r	   r  extendr  rc  rg   re   rf   out_listrY   rY   rZ   
list_items  s   
zIterableObj.list_itemsN)ri   r9  r:  r;  rA  r   r=  r  r   r#   r*   rC   r  r	   r  rY   rY   rY   rZ   r     s   
 "$r   c                   @   s*   e Zd ZdZdedededdfddZdS )	IterableClassWatcherzbMetaclass that issues :exc:`DeprecationWarning` when :class:`git.util.Iterable`
    is subclassed.rF   basesclsdictrH   Nc                 C   s2   |D ]}t |tu rtjd| dtdd qd S )Nz!GitPython Iterable subclassed by zq. Iterable is deprecated due to naming clash since v3.1.18 and will be removed in 4.0.0. Use IterableObj instead.   )
stacklevel)typer  warningswarnDeprecationWarning)rc  rF   r  r  baserY   rY   rZ   r    s   
zIterableClassWatcher.__init__)ri   r9  r:  r;  r   r/   r'   r  rY   rY   rY   rZ   r  	  s    r  c                	   @   sT   e Zd ZdZdZdZedddededefd	d
ZedddededefddZ	dS )IterablezDeprecated, use :class:`IterableObj` instead.

    Defines an interface for iterable items, so there is a uniform way to retrieve
    and iterate items within the git repository.
    rY   z5attribute that most suitably identifies your instancerg   r9   re   rf   rH   c                 O   r  )zDeprecated, use :class:`IterableObj` instead.

        Find (all) items of this type.

        See :meth:`IterableObj.iter_items` for details on usage.

        :return:
            Iterator yielding Items
        r  r  r  rY   rY   rZ   r  %  s   zIterable.iter_itemsc                 O   r  )a  Deprecated, use :class:`IterableObj` instead.

        Find (all) items of this type and collect them into a list.

        See :meth:`IterableObj.list_items` for details on usage.

        :return:
            list(Item,...) list of item instances
        r  r  rY   rY   rZ   r  2  s   
zIterable.list_itemsN)
ri   r9  r:  r;  rA  r  r  r#   r  r  rY   rY   rY   rZ   r    s     r  )	metaclass)r   )Fr   ).)T)r\   __all__r]   r   abcr   
contextlib	functoolsr   r   loggingrP   os.pathrv   r   r   rB  r   r{   r   r  urllib.parser   r   r  
gitdb.utilr   r   r   r   r   r   r    r!   r"   typingr#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   git.cmdr5   
git.configr6   r7   
git.remoter8   git.repo.baser9   	git.typesr:   r;   r<   r=   r>   r?   r@   rA   rB   rC   	getLoggerri   rS   r   r   r[   r^   r   r_   r`   r   contextmanagerrr   ru   r   r   r<  r   r   r   r   r   r   r   r   r   r   rC  Ir   r=  r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   r   r
   r	   r   r  r  r  rY   rY   rY   rZ   <module>   s   


,P,


"!		 
&"
	 $" 9 @#NBb4