
    g              	          U d dl Z g dZe j                  dk(  rej                  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 e1rd 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      ZI e
j                  eK      ZLdeMdeNdeNfdZOdeMdeNdeNfdZP ePdd      ZQ ePdd      ZR e2d      ZSde'deSf   de'deSf   fdZTej                  deDde)eDddf   fd       ZVej                  deMd eMde)d!   fd"       ZWd#eDddfd$ZXd#eDddfd%ZYdmd&e&d'e&d(eZdeZfd)Z[d*eDd+eDdeDfd,Z\e j                  dk(  rd#eDdeDfd-Z]d#eDdeMfd.Z^e]Z_n
d#eDdeMfd/Z^e^Z_d*eDd+eDdeDfd0Z`dnd#eDd2eNdeNfd3Zade/eM   fd4Zbdod5eMd#e-eD   de,eM   fd6Zcd7e-eM   d#eMdeMfd8Zd ej                  d9      d: d1f ej                  d;      edd1f ej                  d<      edd1f ej                  d=ej                        d> df ej                  d?      d@ d1ffZge0e0e.eM   e'eNf   df   ehdA<   d#eMdeMfdBZi ej                  dC      Zjd#eDdeMfdDZki Zle(eMe-eN   f   ehdE<   dFeMdeNfdGZme5dFddeCd1   fdH       Zne5dFeDdeNfdI       ZndFe3deDf   deNfdJZndeMfdKZodLe3ej                  dMf   dNe$ddfdOZqe5dpd+ddPeNddfdQ       Zre5dpd+eDdPeNdeMfdR       Zrdqd+e3deDf   dPeNde-eD   fdSZrdTe/eM   de,eM   fdUZs G dV dW      Zt G dX dYet      Zu G dZ d[      Zv G d\ d]      Zw G d^ d_      Zx G d` da      Zy G db dcey      Zz G dd dee,eI         Z{eH G df dgeE             Z| G dh die}      Z~ G dj dke~l      Zy)r    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                     	 t         j                  |    }t        j	                  d|        |j                         j                         }|dv ry|dv ryt        j	                  d| ||       |S # t        $ r |cY S w xY w)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)rG   rH   valueadjusted_values       =/var/www/openai/venv/lib/python3.12/site-packages/git/util.py_read_env_flagr\   s   s    

4  OOv
 [[]((*N11--OOCT5RYZN  s   A- -A;:A;c                 D    t         j                  dk(  xr 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\   )rG   rH   s     r[   _read_win_env_flagr`      s     <<7"D~dG'DD    r   HIDE_WINDOWS_FREEZE_ERRORSTfunc.c           	      h     ddl m t               dddt        dt        dt        f fd       }|S )	ztMethods with this decorator raise :exc:`~git.exc.InvalidGitRepositoryError` if
    they encounter a bare repository.   )InvalidGitRepositoryErrorselfr9   argskwargsrI   c                 r    | j                   j                  r dj                  z         | g|i |S )Nz/Method '%s' cannot operate on bare repositories)repobare__name__)rh   ri   rj   rg   rd   s      r[   wrapperzunbare_repo.<locals>.wrapper   s;    99>>+,]`d`m`m,mnnD*4*6**ra   )excrg   r   r$   rc   )rd   ro   rg   s   ` @r[   r   r      sA     /
4[+h +s +c +a + + Nra   new_dirc              #      K   t        j                         }t        j                  |        	 |  t        j                  |       y# t        j                  |       w xY w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)rR   getcwdchdir)rq   old_dirs     r[   cwdrv      sA      iikGHHW
s   *A!A A!AA!rY   )NNNc              #     K   t        j                  |       }|t         j                  | <   	 d |t         j                  | = y|t         j                  | <   y# |t         j                  | = w |t         j                  | <   w xY ww)z=Context manager to temporarily patch an environment variable.N)rR   getenvrS   )rG   rY   	old_values      r[   	patch_envrz      sn      		$IBJJt)

4 (BJJt 

4 (BJJts   )BA (B)BBpathc                 
   dt         dt        dt        ddfd}t        j                  dk7  rt        j                  |        yt        j                  dk\  rt        j                  | |	       yt        j                  | |
       y)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.
    functionr{   _excinforI   Nc                     t        j                  |t        j                         	  | |       y# t        $ r}t
        rddlm}  |d|       | d}~ww xY w)zuCallback for :func:`shutil.rmtree`.

        This works as either a ``onexc`` or ``onerror`` style callback.
        r   )SkipTestz%FIXME: fails with: PermissionError
  N)rR   chmodstatS_IWUSRPermissionErrorr   unittestr   )r}   r{   r~   exr   s        r[   handlerzrmtree.<locals>.handler   sQ     	t||$	TN 	(-!GtLMSUU	s   / 	AAAr   )      )onexc)onerror)r'   r?   r$   r^   r_   shutilr   version_info)r{   r   s     r[   r   r      sg    ( ( c d " ||wd			W	$d'*dG,ra   c                     t        j                  |       r?t        j                  dk(  rt	        j
                  | d       t	        j                  |        yy)zWEnsure file deleted also on *Windows* where read-only files need special
    treatment.r   i  N)ospisfiler^   r_   rR   r   remover{   s    r[   rmfiler      s:     zz$<<7"HHT5!
		$ ra   sourcedestination
chunk_sizec                     d}	 | j                  |      }|j                  |       |t        |      z  }t        |      |k  r	 |S B)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chunks        r[   r   r      sO     
B
J'% 
c%ju:
"I ra   apc                     t        |       }|D ]N  }t        |      }|s|j                  d      r	||dd z  }+|dk(  s|j                  d      r||z  }G|d|z   z  }P |S )zmJoin path tokens together similar to osp.join, but always use ``/`` instead of
    possibly ``\`` on Windows./rf   NrK   )str
startswithendswith)r   r   r{   bs       r[   r   r     sp     q6DF<<AabEMDRZ4==-AIDC!GOD  Kra   c                 <    t        |       } | j                  dd      S )Nr   \r   replacer   s    r[   r   r   $  s    4y||C&&ra   c                 <    t        |       } | j                  dd      S )Nr   r   r   r   s    r[   r   r   (  s    4y||D#&&ra   c                     t        |       S N)r   r   s    r[   r   r   /  s    4yra   c                 ,    t        t        | g|       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   s     r[   r   r   5  s     )A**++ra   Fis_filec                     |rt        j                  |       } t        j                  |       st        j                  | d       yy)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isdirrR   makedirs)r{   r   s     r[   r   r   >  s4     {{4 99T?
D4(ra   c                      t         j                  j                  dd       } | r/t        d | j	                  t         j
                        D              S t        j                  dk(  ryy)NPATHEXTc              3   <   K   | ]  }|j                           y wr   )upper).0r   s     r[   	<genexpr>z&_get_exe_extensions.<locals>.<genexpr>T  s     B(A1QWWY(As   r   )z.BATz.COMz.EXE )rR   rS   gettuplesplitpathsepr^   r_   )r   s    r[   _get_exe_extensionsr   Q  sI    jjnnY-GBbjj(ABBB		 'ra   programc                    t               dt        dt        ffd}g }|st        j                  d   }t        |      j                  t        j                        D ]c  }|j                  d      }|st        j                  ||       }|gD cg c]  }||
 c}z   D ]  } ||      s|j                  |        e |S c c}w )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.
    fpathrI   c                      t        j                         xrT t        j                   t        j                        xr. t
        j                  dk7  xs  xs t         fdD              S )Nr   c              3   \   K   | ]#  }j                         j                  |       % y wr   )r   r   )r   extr   s     r[   r   z,py_where.<locals>.is_exec.<locals>.<genexpr>p  s'     Bwjvcf5;;=CYCYZ]C^jvs   ),)r   r   rR   accessX_OKr^   r_   any)r   winprog_extss   `r[   is_execzpy_where.<locals>.is_execk  sW    JJu 		%) 'w|+;wsBwjvBw?w		
ra   PATH")r   r   boolrR   rS   r   r   rW   r   joinappend)	r   r{   r   progsfolderexe_pathefr   s	           @r[   py_wherer   [  s     '(L
s 
t 
 Ezz&!d)//"**-c"xx0HZ<"P<aXq#9<"PP1:LLO Q	 . L #Qs   Cdrivec                 j   t        j                  |      r| s|}n}|xr; t        j                  t        j                  t        j                  |                  }t        j                  |      r| r|}n$t        |      }n| rd| j                         d|}t        |      }|j                  dd      S )Nz/proc/cygdrive/r   r   )	r   isabsnormpath
expandvars
expandusercygpathrX   r   r   )r   r{   r   p_strs       r[   
_cygexpathr     s    
yyu GS\\#..1E"FG99Q<AJ*/++-;AFE==s##ra   z*\\\\\?\\UNC\\([^\\]+)\\([^\\]+)(?:\\(.*))?c           	      8    d| d|d|j                  dd      S )N//r   r   )r   )servershare	rest_paths      r[   <lambda>r     s    &%IZIZ[_adIe*fra   z\\\\\?\\(\w):[/\\](.*)z(\w):[/\\](.*)z	file:(.*)c                     | S r   r   )r   s    r[   r   r     s    	ra   z(\w{2,}:.*)c                     | S r   r   )urls    r[   r   r     s    cra   _cygpath_parsersc                     t        |       } | j                  d      sQt        D ]<  \  }}}|j                  |       }|s ||j	                          } |rt        |       }  | S  t        d|       } | S )zJUse :meth:`git.cmd.Git.polish_url` instead, that works on any environment.)z	/cygdriver   z/proc/cygdriveN)r   r   r   matchgroupsr   r   )r{   regexparserrecurser   s        r[   r   r     ss    t9D??@A&6"E67KK%Eu||~."4=D K '7 dD)DKra   z(?:/proc)?/cygdrive/(\w)(/.*)?c                     t        |       } t        j                  |       }|r,|j                         \  }}|j	                         d|xs d} | j                  dd      S )N:rK   r   r   )r   _decygpath_regexr   r   r   r   )r{   mr   r   s       r[   	decygpathr     sU    t9Dt$A88:y++-b9<<T""ra   _is_cygwin_cachegit_executablec                    t         j                  |       }|d}	 t        j                  |       }|s't	        |       }|rt        j                  |d         nd}t        j
                  |d      }t        j                  |gt        j                  d      }|j                         \  }}d|v }|t         | <   |S # t        $ r }t        j                  d|       Y d }~/d }~ww xY w)	NFr   rK   unameT)stdoutuniversal_newlinesCYGWINz/Failed checking if running in CYGWIN due to: %r)r   r   r   r   r   r   
subprocessPopenPIPEcommunicate	ExceptionrU   debug)	r   	is_cygwingit_dirres	uname_cmdprocess	uname_out_r   s	            r[   _is_cygwin_gitr    s     $$^4I		Qkk.1G~.14#++c!f-" '2I &&	{:??_cdG"..0LIq I-I ,5(	  	QMMKRPP	Qs   BB8 8	C!CC!c                      y r   r   r   s    r[   is_cygwin_gitr        ;>ra   c                      y r   r   r
  s    r[   r  r    s    58ra   c                 X    t         j                  dk(  ry| yt        t        |             S )Nr   F)r^   r_   r  r   r
  s    r[   r  r    s*    
||w		c.122ra   c                  X    t        j                         dt        j                         S )zM:return: String identifying the currently active system user as ``name@node``@)getpassgetuserr_   noder   ra   r[   r   r     s    oo'99ra   proczGit.AutoInterruptrj   c                 (     | j                   di | y)zXWait for the process (clone, fetch, pull or push) and handle its errors
    accordingly.Nr   )wait)r  rj   s     r[   finalize_processr    s     DIIra   expand_varsc                      y r   r   r   r  s     r[   expand_pathr    r  ra   c                      y r   r   r  s     r[   r  r    s     ra   c                    t        | t        j                        r| j                         S 	 t	        j
                  |       } |rt	        j                  |       } t	        j                  t	        j                  |             S # t        $ r Y y w xY wr   )

isinstancepathlibPathresolver   r   r   r   abspathr   r  s     r[   r  r    si    !W\\"yy{NN1q!A||CKKN++ s   AB   	BBcmdlinec                    g }t        |       D ]  \  }}|j                  |       	 t        |      }|j                  |j                  <|j                  6|j                  |j                  j                  |j                  d            }|j                  6|j                  |j                  j                  |j                  d            }t        |      ||<    |S # t        $ r Y w xY w)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.
    z*****)netloc)
	enumerater   r   passwordusername_replacer%  r   r   
ValueError)r#  new_cmdlineindexto_parser   s        r[   remove_password_if_presentr.    s     K$W-x8$	8$C||#(<||'ll#***<*<S\\7*SlT||'ll#***<*<S\\7*SlT!+CK .    		s   #C 
BC  	C,+C,c                   R   e Zd ZU dZdZeed<    ee      D  cg c]  }d|z  	 c}} \	  ZZ	Z
ZZZZZZee	z  Ze ZdZdZdZ ej.                  d      Z ej.                  d	      ZddZded
dfdZd
eegdf   fdZded
dfdZ 	 	 ddede!ee"f   de!ee"df   ded
df
dZ#yc c}} w )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_codesrf   zdone.z, )	_cur_line	_seen_opserror_linesother_linesz%(remote: )?([\w\s]+):\s+()(\d+)()(.*)z2(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)rI   Nc                 <    g | _         d | _        g | _        g | _        y r   )r3  r2  r4  r5  rh   s    r[   __init__zRemoteProgress.__init__S  s     $&(,&(&(ra   linec                    t        |t              r|j                  d      }n|}|| _        | j                  j	                  d      r&| j
                  j                  | j                         yd\  }}| j                  j                  |      }|| j                  j                  |      }|s-| j                  |       | j                  j                  |       yd}|j                         \  }}}	}}}
|dk(  r|| j                  z  }n|dk(  r|| j                  z  }n{|dk(  r|| j                  z  }nf|d	k(  r|| j                   z  }nQ|d
k(  r|| j"                  z  }n<|dk(  r|| j$                  z  }n'|dk(  r|| j&                  z  }n| j                  |       y|| j(                  vr*| j(                  j                  |       || j*                  z  }|
d}
|
j-                         }
|
j/                  | j0                        r(|| j2                  z  }|
dt5        | j0                          }
|
j-                  | j6                        }
| j9                  ||xr t;        |      |xr t;        |      |
       y)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 filesrK   )r  bytesdecoder2  r   r4  r   re_op_relativer   re_op_absoluteline_droppedr5  r   COUNTINGCOMPRESSINGWRITING	RECEIVING	RESOLVINGFINDING_SOURCESCHECKING_OUTr3  BEGINrW   r   
DONE_TOKENENDr   TOKEN_SEPARATORupdatefloat)rh   r9  line_str	cur_count	max_countr   op_code_remoteop_name_percentmessages              r[   _parse_progress_linez#RemoteProgress._parse_progress_lineY  sV    dE"{{7+HH!>>$$%9:##DNN3)	9##))(3=''--h7Eh'##H- DILLNA(Iy' ((t}}$G--t'''G))t||#G++t~~%G**t~~%G))t+++G,,t(((G h'  $..(NN!!'*tzz!G ?G --/DOO,txxG5T__!5 56G-- 4 45*%	**%	*		
ra   c                 $     dt         ddf f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.
        r9  rI   Nc                 B    j                  | j                               S r   )rU  rstrip)r9  rh   s    r[   r   z3RemoteProgress.new_message_handler.<locals>.handler  s    ,,T[[];;ra   )r%   )rh   r   s   ` r[   new_message_handlerz"RemoteProgress.new_message_handler  s    	<& 	<T 	<
 ra   c                      y)zICalled whenever a line could not be understood and was therefore dropped.Nr   )rh   r9  s     r[   r?  zRemoteProgress.line_dropped  s    ra   rP  rN  rO  rT  c                      y)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>`.
        Nr   )rh   rP  rN  rO  rT  s        r[   rK  zRemoteProgress.update  s    H 	ra   rI   NNrK   )$rn   
__module____qualname____doc__r1  int__annotations__rangerG  rI  r@  rA  rB  rC  rD  rE  rF  
STAGE_MASKOP_MASKrH  rJ  	__slots__recompiler>  r=  r8  r%   rU  r'   r   rY  r?  r3   rL  rK  )r   xs   00r[   r   r   3  s5   5 M3 }-.-Aa-.
JkGJOI  RZZ HINRZZ UVN)W
 W
D W
rXseTk%:    .2$$ e$$ eT)*	$
 $ 
$C 	/s   B#r   c                   D     e Zd ZdZdZdeddf fdZdededdfd	Z x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fnrI   Nc                 0    || _         t        | 	          y r   )rl  superr8  )rh   rm  	__class__s     r[   r8  zCallableRemoteProgress.__init__  s    ra   ri   rj   c                 (     | j                   |i | y r   rk  )rh   ri   rj   s      r[   rK  zCallableRemoteProgress.update  s    ''ra   )
rn   r^  r_  r`  rf  r'   r8  r$   rK  __classcell__rp  s   @r[   r   r     s<     I8  (C (3 (4 (ra   r   c            
       b   e Zd ZdZ ej
                  d      Z ej
                  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ZdedefdZdedefdZdefdZdefdZdefdZededd fd       Ze	 ddededed   dd fd       Zedded   dd fd       Zedded   dd fd       Zy)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_EMAILrG   emailrG   ry  rI   Nc                      || _         || _        y r   rz  )rh   rG   ry  s      r[   r8  zActor.__init__  s    	
ra   otherc                 j    | j                   |j                   k(  xr | j                  |j                  k(  S r   rz  rh   r|  s     r[   __eq__zActor.__eq__  s'    yyEJJ&D4::+DDra   c                     | |k(   S r   r   r~  s     r[   __ne__zActor.__ne__  s    EM""ra   c                 D    t        | j                  | j                  f      S r   )hashrG   ry  r7  s    r[   __hash__zActor.__hash__  s    TYY

+,,ra   c                 6    | j                   r| j                   S dS r]  )rG   r7  s    r[   __str__zActor.__str__"  s     IItyy-2-ra   c                 <    d| j                   d| j                  dS )Nz<git.Actor "z <z>">rz  r7  s    r[   __repr__zActor.__repr__%  s    *.))TZZ@@ra   stringc                    | j                   j                  |      }|r|j                         \  }}t        ||      S | j                  j                  |      }|rt        |j                  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`
        rf   N)name_email_regexsearchr   r   name_only_regexgroup)clsr  r   rG   ry  s        r[   _from_stringzActor._from_string(  st       ''/((*KD%u%%##**62AQWWQZ..&&ra   env_name	env_emailconfig_reader)Nr7   r8   c                    t        dd      }d dt        ffddt        ffd}d|| j                  |fd|| j                  ffD ](  \  }}}}		 t        j
                  |   }
t        |||
       * |S # t        $ rZ |7	 |j                  d|      }
n# t        $ r
  |	       }
Y nw xY wt        |||
       t        ||      st        || |	              Y w xY w)NrK   rI   c                        s
t                 S r   )r   )user_ids   r[   default_emailz(Actor._main_actor.<locals>.default_emailK  s    %-Nra   c                  6             j                  d      d   S )Nr  r   )r   )r  s   r[   default_namez'Actor._main_actor.<locals>.default_nameQ  s     ?((-a00ra   rG   ry  user)r   r   	conf_name
conf_emailrR   rS   setattrrT   r   r   getattr)r  r  r  r  actorr  attrevarcvarrH   valr  r  s              @@r[   _main_actorzActor._main_actorA  s     b"	s 		1c 	1 Xs}}l;i?*
%D$g4jj&tS)*
&   	4 ,(+//=$ (%i(E4-ud+E43	4s6    A66CBCB(%C'B((.CCc                 P    | j                  | 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.
        )r  env_committer_nameenv_committer_emailr  r  s     r[   	committerzActor.committeri  s$     s55s7N7NP]^^ra   c                 P    | j                  | j                  | j                  |      S )zSame as :meth:`committer`, but defines the main author. It may be specified
        in the environment, but defaults to the committer.)r  env_author_nameenv_author_emailr  s     r[   authorzActor.authorx  s#     s22C4H4H-XXra   r   ) rn   r^  r_  r`  rg  rh  r  r  r  r  r  r  r  r  rf  r-   r   r8  r$   r   r  r  ra  r  r  r  classmethodr  r3   r  r  r  r   ra   r[   r   r     s   
 !bjj+O!rzz/2 (O)-/ IJ!IXc] 8C= T EC ED E#C #D #-# -. .A# A '# '' ' '0 
 NR	%% % IJ	%
 
% %N _e,X&Y _el _ _ Y5)U#V Ybi Y Yra   r   c                   P    e Zd ZdZdZdedeeef   ddfdZ	e
dd	d
edd fd       Zy)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  rI   Nc                      || _         || _        y r   r  )rh   r  r  s      r[   r8  zStats.__init__  s    

ra   rl   r:   textc                    dddddi d}|j                         D ]  }|j                  d      \  }}}}|dk7  xr t        |      xs d}	|dk7  xr t        |      xs d}
|d   dxx   |	z  cc<   |d   dxx   |
z  cc<   |d   d	xx   |	|
z   z  cc<   |d   d
xx   dz  cc<   |	|
|	|
z   |d}||d
   |j                         <    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  rf   )r  r  r  change_type)
splitlinesr   ra  rW   r   )r  rl   r  hshr9  r  raw_insertionsraw_deletionsfilenamer  r  
files_dicts               r[   _list_from_stringzStats._list_from_string  s    %&AAN
 OO%DEIZZPTEUB[.-'3.F3~3FK!J%,C]1CHqIL&*4&L%2%L!Z)%;;!L!Q&!(&#i/*	$J .8CL)* & S\3w<00ra   )rn   r^  r_  r`  rf  rB   r(   r?   r;   r8  r  r   r  r   ra   r[   r   r     s[    4 #Ih tHh4F/G D  1V 13 17 1 1ra   r   c                   X    e Zd ZdZdZdeddfdZdedefdZ	de
fd	Zde
fd
ZdefdZy)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   rI   Nc                 2    || _         t        d      | _        y )Nra   )r   r!   r  )rh   r   s     r[   r8  zIndexFileSHA1Writer.__init__  s    SM	ra   datac                 n    | j                   j                  |       | j                  j                  |      S r   )r  rK  r   r   )rh   r  s     r[   r   zIndexFileSHA1Writer.write  s'    		vv||D!!ra   c                 p    | j                   j                         }| j                  j                  |       |S r   )r  digestr   r   rh   shas     r[   	write_shazIndexFileSHA1Writer.write_sha  s)    ii S
ra   c                 Z    | j                         }| j                  j                          |S r   )r  r   closer  s     r[   r  zIndexFileSHA1Writer.close  s     nn
ra   c                 6    | j                   j                         S r   )r   tellr7  s    r[   r  zIndexFileSHA1Writer.tell  s    vv{{}ra   )rn   r^  r_  r`  rf  r*   r8  r%   ra  r   r;  r  r  r  r   ra   r[   r   r     sX     I"" " ""& "S "5 
u 
c ra   r   c                   \    e Zd ZdZdZdeddfdZddZdefdZ	de
fd	Zdd
ZddZddZy)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_pathrI   Nc                      || _         d| _        y )NFr  )rh   r  s     r[   r8  zLockFile.__init__  s    #ra   c                 $    | j                          y r   )_release_lockr7  s    r[   __del__zLockFile.__del__  s    ra   c                      d| j                   z  S )z:return: Path to lockfilez%s.lock)r  r7  s    r[   _lock_file_pathzLockFile._lock_file_path  s    DOO,,ra   c                     | 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  r7  s    r[   	_has_lockzLockFile._has_lock  s     ra   c                 J   | j                         ry| j                         }t        j                  |      rt	        d| j
                  d|d      	 t        |d      5  	 ddd       d| _	        y# 1 sw Y   xY w# t        $ r}t	        t        |            |d}~ww xY w)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.
        NzLock for file z did already exist, delete z in case the lock is illegalw)modeT)
r  r  r   r   IOErrorr  openOSErrorr   r  )rh   	lock_filer   s      r[   _obtain_lock_or_raisezLockFile._obtain_lock_or_raise  s     >>((*	::i ??I/ 
	)ic* +
  +* 	)#a&/q(	)s0   A? !A3#A? 3A<8A? ?	B"BB"c                 "    | j                         S )zThe default implementation will raise if a lock cannot be obtained.

        Subclasses may override this method to provide a different implementation.
        )r  r7  s    r[   _obtain_lockzLockFile._obtain_lock  s    
 ))++ra   c                     | j                         sy| j                         }	 t        |       d| _        y# t        $ r
 Y d| _        yw xY w)z Release our lock if we have one.NF)r  r  r   r  r  )rh   lfps     r[   r  zLockFile._release_lock!  sO    ~~ ""$	3K    		s   6 	A	A	r\  )rn   r^  r_  r`  rf  r?   r8  r  r   r  r   r  r  r  r  r   ra   r[   r   r     sM     -I (  t  - -4 0, ra   r   c            	       ^     e Zd ZdZdZdej                  fdedede	ddf fd	Z
d fd
Z x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_srI   Nc                 @    t         |   |       || _        || _        y)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)ro  r8  r  r  )rh   r  r  r  rp  s       r[   r8  zBlockingLockFile.__init__;  s"     	#//ra   c                    t        j                          }|t        | j                        z   }	 	 t        |           y# t
        $ r}t        j                          }t        j                  t        j                  | j                                     s$d| j                         ||z
  fz  }t        |      |||k\  r$d||z
  | j                         fz  }t        |      |t        j                  | j                         Y d}~nd}~ww xY w)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.
        zVDirectory containing the lockfile %r was not readable anymore after waiting %g secondsz Waited %g seconds for lock at %rN)timerL  r  ro  r  r  r   r   r   r  sleepr  )rh   	starttimemaxtimer   curtimemsgrp  s         r[   r  zBlockingLockFile._obtain_lockN  s    IIK	eD$8$899$&, +  1 ))+yyT-A-A-C!DEr,,.)+v C "#,A- g%<)+,,.@ C "#,A-

4//00'1 s   ? 	DB6DDr\  )rn   r^  r_  r`  rf  r^   maxsizer?   rL  ra  r8  r  rr  rs  s   @r[   r   r   0  sP     7I
 #& #	00  0 	0
 
0&   ra   r   c                        e Zd ZdZdZddededdf fdZddededdfd	Zd
ede	fdZ
d
edefdZdeeeeef   defdZdeeeeef   ddfdZ x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_prefixid_attrprefixrI   zIterableList[T_IterableObj]c                 "    t         |   |       S r   )ro  __new__)r  r  r  rp  s      r[   r  zIterableList.__new__  s    ws##ra   Nc                      || _         || _        y r   r  )rh   r  r  s      r[   r8  zIterableList.__init__  s    ra   r  c                     	 t         j                  | |      }|r|S 	 	 t	        | t        t        |             y# t        t        f$ r Y -w xY w# t        t        f$ r Y yw xY w)NTF)list__contains__AttributeError	TypeErrorr  r4   r   )rh   r  rvals      r[   r  zIterableList.__contains__  so    	$$T40D 	D$sD/* 	* 		 	* 		s    9 A A
AA A c                     | j                   |z   }| D ]  }t        || j                        |k(  s|c S  t        j	                  | |      S r   )r  r  r  r  __getattribute__)rh   r  items      r[   __getattr__zIterableList.__getattr__  sG    ||d"DtT]]+t3  $$T400ra   r,  c                 <   t        |t        t        t        f      sJ d       t        |t              rt        j                  | |      S t        |t              rt        d      	 t        | |      S # t        $ r!}t        d| j                  |z   z        |d }~ww xY 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  ra  r   slicer  __getitem__r*  r  r  
IndexErrorr  )rh   r,  r   s      r[   r  zIterableList.__getitem__  s    %#sE!23d5dd3eS!##D%00u%<==]tU++! ] !;t||e?S!TU[\\]s   %A1 1	B:BBc                 R   t        |t        t        f      sJ d       t        t        |      }t        |t              sTd}| j                  |z   }t        |       D ]"  \  }}t        || j                        |k(  s |} n |dk(  rt        d|z        t        j                  | |       y )Nr  zItem with name %s not found)r  ra  r   r4   r  r&  r  r  r  r  __delitem__)rh   r,  delindexrG   ir	  s         r[   r  zIterableList.__delitem__  s    %#s,].]],U#%%H<<%'D$T?44/47 H + 2~ !>!EFF 	x(ra   )rK   )rn   r^  r_  r`  rf  r   r  r8  objectr   r  rD   r
  r3   rA   ra  r  r  r  rr  rs  s   @r[   r
   r
   r  s    8 (I$c $3 $8U $ S $  D $1 1 1]}c5#'E!F ]= ])}c5#'E!F )4 )ra   r
   c                   z    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	              Zeddde	de	dee   fd
       Zy)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>`
    r   _id_attribute_rl   r:   ri   rj   rI   c                     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r  rl   ri   rj   s       r[   
iter_itemszIterableObj.iter_items  s     ""ABBra   c                 z    t        | j                        }|j                   | j                  |g|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  r  rl   ri   rj   out_lists        r[   
list_itemszIterableObj.list_items  s:     ".c.@.@!At=d=f=>ra   N)rn   r^  r_  r`  rf  r   rb  r  r   r$   r+   rD   r  r
   r#  r   ra   r[   r	   r	     s     ICf CS CC CH]D[ C  C f S C LQ^D_  ra   r	   c                   (    e Zd ZdZdedededdfdZy)IterableClassWatcherzbMetaclass that issues :exc:`DeprecationWarning` when :class:`git.util.Iterable`
    is subclassed.rG   basesclsdictrI   Nc                 v    |D ]4  }t        |      t        u st        j                  d| dt        d       6 y )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)r  rG   r&  r'  bases        r[   r8  zIterableClassWatcher.__init__  s>    DDz117v >0 0 '  ra   )rn   r^  r_  r`  r   r0   r(   r8  r   ra   r[   r%  r%  	  s(    
C 
 
 
 
ra   r%  c            	       \    e Zd ZdZdZdZedddededefd	       Zedddededefd
       Z	y)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.
    r   z5attribute that most suitably identifies your instancerl   r:   ri   rj   rI   c                     t        d      )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  s       r[   r  zIterable.iter_items%  s     ""ABBra   c                 z    t        | j                        }|j                   | j                  |g|i |       |S )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!  s        r[   r#  zIterable.list_items2  s:     %S%7%78t=d=f=>ra   N)
rn   r^  r_  r`  rf  r  r  r$   r  r#  r   ra   r[   r1  r1    sw     ILN
Cf 
CS 
CC 
CC 
C 
C f S C C  ra   r1  )	metaclass)i   )Fr   ).)T)r^   __all__r_   r   abcr   
contextlib	functoolsr   r  loggingrR   os.pathr{   r   r  rg  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/   r0   r1   r2   r3   r4   r5   git.cmdr6   
git.configr7   r8   
git.remoter9   git.repo.baser:   	git.typesr;   r<   r=   r>   r?   r@   rA   rB   rC   rD   	getLoggerrn   rU   r   r   r\   r`   r   rb   rc   r   contextmanagerrv   rz   r   r   ra  r   r   r   r   r   r   r   r   r   r   rh  Ir   rb  r   r   r   r   r  r  r   r   r  r  r.  r   r   r   r   r   r   r   r
   r	   r+  r%  r1  r   ra   r[   <module>rF     s   * <<7NN+,      	    	     - 
 
 
    * =!"
 
 
 u5V/Wcgh '

H
% t  4
ES 
E4 
ED 
E  //JDQ /0LdS  CLhsAv& 8CF+; $  i$(<=   
)C 
) 
)	2B(C 
) 
)- -d -B d  x S Z] $ x H $ <<7'X '( ''8 ' ' ,N8   *N, ,h ,8 ,( T d &Xc] #c #(!3 #tCy #L$hsm $3 $3 $. 	

@A	f
 RZZ)*Z%@RZZ!"Z%8RZZbdd#&ADIRZZ/E:E %gclHd:;S@A # # $ 2::?@ #H # # /1 $sHTN*+ 03 4 . 
 >$ >75> > 
 > 
 8( 8t 8 
 83%h"7 3D 3:S :
5!1!13F!FG SV [_  
 >4 >d >T > 
 > 
8 $   

	5x( 	t 	xPXGY 	 $s) Du up(^ ((}Y }Y@=1 =1@   FK  K \>x >D_)4& _)D 1( 1 1h4 "%- %ra   