
    /_i              	          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mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlmZmZ 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/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6 e2rd dl7m8Z8 d dl9m:Z:m;Z; d dl<m=Z= d dl>m?Z? d dl@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZI  e3de4d   d      ZJ e
j                  eL      ZMdeNdeOdeOfdZPdeNdeOdeOfdZQ eQdd      ZR eQdd      ZS e3d      ZTde(deTf   de(deTf   fdZUej                  deEde*eEddf   fd        ZWej                  deNd!eNde*d"   fd#       ZXd$eEddfd%ZYd$eEddfd&ZZdnd'e'd(e'd)e[de[fd*Z\d+eEd,eEdeEfd-Z]e j                  dk(  rd$eEdeEfd.Z^d$eEdeNfd/Z_e^Z`n
d$eEdeNfd0Z_e_Z`d+eEd,eEdeEfd1Zadod$eEd3eOdeOfd4Zbde0eN   fd5Zcdpd6eNd$e.eE   de-eN   fd7Zdd8e.eN   d$eNdeNfd9Ze ej                  d:      d; d2f ej                  d<      eed2f ej                  d=      eed2f ej                  d>ej                        d? df ej                  d@      dA d2ffZhe1e1e/eN   e(eOf   df   eidB<   d$eNdeNfdCZj ej                  dD      Zkd$eEdeNfdEZli Zme)eNe.eO   f   eidF<   dGeNdeOfdHZne6dGddeDd2   fdI       Zoe6dGeEdeOfdJ       ZodGe4deEf   deOfdKZodeNfdLZpdMe4ej                  dNf   dOe%ddfdPZre6dqd,ddQeOddfdR       Zse6dqd,eEdQeOdeNfdS       Zsdrd,e4deEf   dQeOde.eE   fdTZsdUe0eN   de-eN   fdVZt G dW dX      Zu G dY dZeu      Zv G d[ d\      Zw G d] d^      Zx G d_ d`      Zy G da db      Zz G dc ddez      Z{ G de dfe-eJ         Z|eI G dg dheF             Z} G di dje~      Z G dk dlem      Zy)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)Path)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)rH   rI   valueadjusted_values       G/var/www/html/land_sniper/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]   )rH   rI   s     r\   _read_win_env_flagra      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selfr:   argskwargsrJ   c                 r    | j                   j                  r dj                  z         | g|i |S )Nz/Method '%s' cannot operate on bare repositories)repobare__name__)ri   rj   rk   rh   re   s      r\   wrapperzunbare_repo.<locals>.wrapper   s;    99>>+,]`d`m`m,mnnD*4*6**rb   )excrh   r   r%   rd   )re   rp   rh   s   ` @r\   r   r      sA     /
4[+h +s +c +a + + Nrb   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)rS   getcwdchdir)rr   old_dirs     r\   cwdrw      sA      iikGHHW
s   *A!A A!AA!rZ   )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)rS   getenvrT   )rH   rZ   	old_values      r\   	patch_envr{      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|   _excinforJ   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)rS   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,rb   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`   rS   r   remover|   s    r\   rmfiler      s:     zz$<<7"HHT5!
		$ rb   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 rb   apc                     t        j                  |       }|D ]X  }t        j                  |      }|s|j                  d      r	||dd z  }5|dk(  s|j                  d      r||z  }Q|d|z   z  }Z |S )zmJoin path tokens together similar to osp.join, but always use ``/`` instead of
    possibly ``\`` on Windows./rg   NrL   )rS   fspath
startswithendswith)r   r   r|   bs       r\   r   r     s}     99Q<D 	IIaL<<AabEMDRZ4==-AIDC!GOD	 Krb   c                 P    t        j                  |       } | j                  dd      S )Nr   \rS   r   replacer   s    r\   r   r   $  s     yy||C&&rb   c                 P    t        j                  |       } | j                  dd      S )Nr   r   r   r   s    r\   r   r   (  s     yy||D#&&rb   c                 ,    t        j                  |       S N)rS   r   r   s    r\   r   r   /  s    yyrb   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**++rb   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isdirrS   makedirs)r|   r   s     r\   r   r   >  s4     {{4 99T?
D4(rb   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     B1QWWYBs   r   )z.BATz.COMz.EXE )rS   rT   gettuplesplitpathsepr_   r`   )r   s    r\   _get_exe_extensionsr   Q  sI    jjnnY-GBbjj(ABBB		 'rb   programc                    t               dt        dt        ffd}g }|st        j                  d   }t        j
                  |      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.
    fpathrJ   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$     Bwcf5;;=CYCYZ]C^Bws   ),)r   r   rS   accessX_OKr_   r`   any)r   winprog_extss   `r\   is_execzpy_where.<locals>.is_execk  sW    JJu 		%) 'w|+;wsBwjvBw?w		
rb   PATH")r   strboolrS   rT   r   r   r   rX   r   joinappend)	r   r|   r   progsfolderexe_pathefr   s	           @r\   py_wherer   [  s     '(L
s 
t 
 Ezz&!))D/''

3 $c"xx0HZ<"PaXq#9"PP $1:LLO$	$ L #Qs   Cdrivec                 ~   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                  |      }|j                  dd      S )Nz/proc/cygdrive/r   r   )
r   isabsnormpath
expandvars
expandusercygpathrY   rS   r   r   )r   r|   r   p_strs       r\   
_cygexpathr     s    
yyu GS\\#..1E"FG99Q<AJ*/++-;AIIaLE==s##rb   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*f rb   z\\\\\?\\(\w):[/\\](.*)z(\w):[/\\](.*)z	file:(.*)c                     | S r   r   )r   s    r\   r   r     s    	 rb   z(\w{2,}:.*)c                     | S r   r   )urls    r\   r   r     s    c rb   _cygpath_parsersc                     t        j                  |       } | 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)rS   r   r   r   matchgroupsr   r   )r|   regexparserrecurser   s        r\   r   r     s|    99T?D??@A&6 	*"E67KK%Eu||~."4=D K	* dD)DKrb   z(?:/proc)?/cygdrive/(\w)(/.*)?c                     t        j                  |       } t        j                  |       }|r,|j	                         \  }}|j                         d|xs d} | j                  dd      S )N:rL   r   r   )rS   r   _decygpath_regexr   r   r   r   )r|   mr   r   s       r\   	decygpathr     sY    99T?Dt$A88:y++-b9<<T""rb   _is_cygwin_cachegit_executablec                    t         j                  |       }|d}	 t        j                  |       }|s't	        |       }|rt        j                  |d         nd}t        j
                  |d      }t        |      j                         r$t        j                  |t        j                        s$t        j                  d| d       |t         | <   |S 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   rL   unamez&Failed checking if running in CYGWIN: z is not an executableT)stdoutuniversal_newlinesCYGWINz/Failed checking if running in CYGWIN due to: %r)r   r   r   r   r   r   r   r   rS   r   r   rV   debug
subprocessPopenPIPEcommunicate	Exception)	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O++-"))Irww2O FykQfgh3< 0   &&	{:??_cdG"..0LIq I-I ,5(	  	QMMKRPP	Qs   B4D >D 	E"D==Ec                      y r   r   r   s    r\   is_cygwin_gitr        ;>rb   c                      y r   r   r  s    r\   r  r    s    58rb   c                     t         j                  dt        j                  d|        t        j                  dk7  ry| yt	        t        |             S )Nzsys.platform=z, git_executable=cygwinF)rV   r   r_   r`   r
  r   r  s    r\   r  r    sJ    MMM#,,!11B>BTUV
||x		c.122rb   c                  X    t        j                         dt        j                         S )zM:return: String identifying the currently active system user as ``name@node``@)getpassgetuserr`   noder   rb   r\   r   r     s    oo'99rb   proczGit.AutoInterruptrk   c                 (     | j                   di | y)zXWait for the process (clone, fetch, pull or push) and handle its errors
    accordingly.Nr   )wait)r  rk   s     r\   finalize_processr    s     DIIrb   expand_varsc                      y r   r   r   r  s     r\   expand_pathr    r  rb   c                      y r   r   r  s     r\   r  r    s     rb   c                 
   t        | t              r| j                         S 	 t        j                  |       } |rt        j
                  |       } t        j                  t        j                  |             S # t        $ r Y y w xY wr   )	
isinstancer   resolver   r   r   r   abspathr  r  s     r\   r  r    se    !Tyy{NN1q!A||CKKN++ s   AA6 6	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_codesrg   zdone.z, )	_cur_line	_seen_opserror_linesother_linesz%(remote: )?([\w\s]+):\s+()(\d+)()(.*)z2(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)rJ   Nc                 <    g | _         d | _        g | _        g | _        y r   )r4  r3  r5  r6  ri   s    r\   __init__zRemoteProgress.__init__[  s     $&(,&(&(rb   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 filesrL   )r!  bytesdecoder3  r   r5  r   re_op_relativer   re_op_absoluteline_droppedr6  r   COUNTINGCOMPRESSINGWRITING	RECEIVING	RESOLVINGFINDING_SOURCESCHECKING_OUTr4  BEGINrX   r   
DONE_TOKENENDr   TOKEN_SEPARATORupdatefloat)ri   r:  line_str	cur_count	max_countr   op_code_remoteop_name_percentmessages              r\   _parse_progress_linez#RemoteProgress._parse_progress_linea  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*%	**%	*		
rb   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.
        r:  rJ   Nc                 B    j                  | j                               S r   )rV  rstrip)r:  ri   s    r\   r   z3RemoteProgress.new_message_handler.<locals>.handler  s    ,,T[[];;rb   )r&   )ri   r   s   ` r\   new_message_handlerz"RemoteProgress.new_message_handler  s    	<& 	<T 	<
 rb   c                      y)zICalled whenever a line could not be understood and was therefore dropped.Nr   )ri   r:  s     r\   r@  zRemoteProgress.line_dropped  s    rb   rQ  rO  rP  rU  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   )ri   rQ  rO  rP  rU  s        r\   rL  zRemoteProgress.update  s    H 	rb   rJ   NNrL   )$ro   
__module____qualname____doc__r2  int__annotations__rangerH  rJ  rA  rB  rC  rD  rE  rF  rG  
STAGE_MASKOP_MASKrI  rK  	__slots__recompiler?  r>  r9  r&   rV  r(   r   rZ  r@  r4   rM  rL  )r   xs   00r\   r   r   ;  s/   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fnrJ   Nc                 0    || _         t        | 	          y r   )rm  superr9  )ri   rn  	__class__s     r\   r9  zCallableRemoteProgress.__init__  s    rb   rj   rk   c                 (     | j                   |i | y r   rl  )ri   rj   rk   s      r\   rL  zCallableRemoteProgress.update  s    ''rb   )
ro   r_  r`  ra  rg  r(   r9  r%   rL  __classcell__rq  s   @r\   r   r     s<     I8  (C (3 (4 (rb   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_EMAILrH   emailrH   rz  rJ   Nc                      || _         || _        y r   r{  )ri   rH   rz  s      r\   r9  zActor.__init__  s    	
rb   otherc                 j    | j                   |j                   k(  xr | j                  |j                  k(  S r   r{  ri   r}  s     r\   __eq__zActor.__eq__!  s'    yyEJJ&D4::+DDrb   c                     | |k(   S r   r   r  s     r\   __ne__zActor.__ne__$  s    EM""rb   c                 D    t        | j                  | j                  f      S r   )hashrH   rz  r8  s    r\   __hash__zActor.__hash__'  s    TYY

+,,rb   c                 6    | j                   r| j                   S dS r^  )rH   r8  s    r\   __str__zActor.__str__*  s     IItyy-2-rb   c                 <    d| j                   d| j                  dS )Nz<git.Actor "z <z>">r{  r8  s    r\   __repr__zActor.__repr__-  s    *.))TZZ@@rb   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`
        rg   N)name_email_regexsearchr   r   name_only_regexgroup)clsr  r   rH   rz  s        r\   _from_stringzActor._from_string0  st       ''/((*KD%u%%##**62AQWWQZ..&&rb   env_name	env_emailconfig_reader)Nr8   r9   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)NrL   rJ   c                        s
t                 S r   )r   )user_ids   r\   default_emailz(Actor._main_actor.<locals>.default_emailS  s    %-Nrb   c                  6             j                  d      d   S )Nr  r   )r   )r  s   r\   default_namez'Actor._main_actor.<locals>.default_nameY  s     ?((-a00rb   rH   rz  user)r   r   	conf_name
conf_emailrS   rT   setattrrU   r   r  getattr)r  r  r  r  actorr  attrevarcvarrI   valr  r  s              @@r\   _main_actorzActor._main_actorI  s     b"	s 		1c 	1 Xs}}l;i?*
 	4%D$g4jj&tS)	4&   	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.committerq  s$     s55s7N7NP]^^rb   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.author  s#     s22C4H4H-XXrb   r   ) ro   r_  r`  ra  rh  ri  r  r  r  r  r  r  r  r  rg  r.   r   r9  r%   r   r  r  rb  r  r  r  classmethodr  r4   r  r  r  r   rb   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rb   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  rJ   Nc                      || _         || _        y r   r  )ri   r  r  s      r\   r9  zStats.__init__  s    

rb   rm   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  rg   )r  r  r  change_type)
splitlinesr   rb  rX   r   )r  rm   r  hshr:  r  raw_insertionsraw_deletionsfilenamer  r  
files_dicts               r\   _list_from_stringzStats._list_from_string  s    %&AAN
 OO% 	8DEIZZPTEUB[.-'3.F3~3FK!J%,C]1CHqIL&*4&L%2%L!Z)%;;!L!Q&!(&#i/*	$J .8CL)*	8 S\3w<00rb   )ro   r_  r`  ra  rg  rC   r)   r@   r<   r9  r  r   r  r   rb   r\   r   r     s[    4 #Ih tHh4F/G D  1V 13 17 1 1rb   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   rJ   Nc                 2    || _         t        d      | _        y )Nrb   )r   r"   r  )ri   r   s     r\   r9  zIndexFileSHA1Writer.__init__  s    SM	rb   datac                 n    | j                   j                  |       | j                  j                  |      S r   )r  rL  r   r   )ri   r  s     r\   r   zIndexFileSHA1Writer.write  s'    		vv||D!!rb   c                 p    | j                   j                         }| j                  j                  |       |S r   )r  digestr   r   ri   shas     r\   	write_shazIndexFileSHA1Writer.write_sha  s)    ii S
rb   c                 Z    | j                         }| j                  j                          |S r   )r  r   closer  s     r\   r  zIndexFileSHA1Writer.close  s     nn
rb   c                 6    | j                   j                         S r   )r   tellr8  s    r\   r  zIndexFileSHA1Writer.tell  s    vv{{}rb   )ro   r_  r`  ra  rg  r+   r9  r&   rb  r   r<  r  r  r  r   rb   r\   r   r     sX     I"" " ""& "S "5 
u 
c rb   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_pathrJ   Nc                      || _         d| _        y )NFr  )ri   r  s     r\   r9  zLockFile.__init__  s    #rb   c                 $    | j                          y r   )_release_lockr8  s    r\   __del__zLockFile.__del__  s    rb   c                      d| j                   z  S )z:return: Path to lockfilez%s.lock)r  r8  s    r\   _lock_file_pathzLockFile._lock_file_path  s    DOO,,rb   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  r8  s    r\   	_has_lockzLockFile._has_lock   s     rb   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  )ri   	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  r8  s    r\   _obtain_lockzLockFile._obtain_lock"  s    
 ))++rb   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  )ri   lfps     r\   r  zLockFile._release_lock)  sO    ~~ ""$	3K    		s   6 	A	A	r]  )ro   r_  r`  ra  rg  r@   r9  r  r   r  r   r  r  r  r  r   rb   r\   r   r     sM     -I (  t  - -4 0, rb   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_srJ   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)rp  r9  r  r  )ri   r  r  r  rq  s       r\   r9  zBlockingLockFile.__init__C  s"     	#//rb   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)timerM  r  rp  r  r  r   r   r   r  sleepr  )ri   	starttimemaxtimer   curtimemsgrq  s         r\   r  zBlockingLockFile._obtain_lockV  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]  )ro   r_  r`  ra  rg  r_   maxsizer@   rM  rb  r9  r  rs  rt  s   @r\   r   r   8  sP     7I
 #& #	00  0 	0
 
0&   rb   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prefixrJ   zIterableList[T_IterableObj]c                 "    t         |   |       S r   )rp  __new__)r  r  r  rq  s      r\   r   zIterableList.__new__  s    ws##rb   Nc                      || _         || _        y r   r  )ri   r  r  s      r\   r9  zIterableList.__init__  s    rb   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  r5   r   )ri   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__)ri   r  items      r\   __getattr__zIterableList.__getattr__  sL    ||d" 	DtT]]+t3	 $$T400rb   r-  c                    t        |t              rt        j                  | |      S t        |t              rt        d      	 t        | t        t        |            S # t        $ r }t        d| j                   |       |d }~ww xY w)NzIndex should be an int or strzNo item found with id )r!  rb  r  __getitem__slicer+  r  r5   r   r  
IndexErrorr  )ri   r-  r   s      r\   r  zIterableList.__getitem__  s    eS!##D%00u%<==XtT#u%566! X #9$,,w!OPVWWXs   A 	B&BBc                    t        t        |      }t        |t              rTd}| j                  |z   }t        |       D ]"  \  }}t        || j                        |k(  s |} n |dk(  rt        d|z        t        j                  | |       y )NzItem with name %s not found)r5   rb  r!  r   r  r'  r  r  r  r  __delitem__)ri   r-  delindexrH   ir
  s         r\   r  zIterableList.__delitem__  s    U#eS!H<<%'D$T? 44/47 H 2~ !>!EFF 	x(rb   )rL   )ro   r_  r`  ra  rg  r   r   r9  objectr   r  rE   r  r4   rB   rb  r  r  r  rs  rt  s   @r\   r
   r
   z  s    8 (I$c $3 $8U $ S $  D $1 1 1	X}c5#'E!F 	X= 	X)}c5#'E!F )4 )rb   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_rm   r;   rj   rk   rJ   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  rm   rj   rk   s       r\   
iter_itemszIterableObj.iter_items  s     ""ABBrb   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  rm   rj   rk   out_lists        r\   
list_itemszIterableObj.list_items  s:     ".c.@.@!At=d=f=>rb   N)ro   r_  r`  ra  rg  r   rc  r  r   r%   r,   rE   r  r
   r#  r   rb   r\   r	   r	     s     ICf CS CC CH]D[ C  C f S C LQ^D_  rb   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.rH   basesclsdictrJ   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  rH   r&  r'  bases        r\   r9  zIterableClassWatcher.__init__  sC     		DDz117v >0 0 ' 		rb   )ro   r_  r`  ra  r   r1   r)   r9  r   rb   r\   r%  r%    s(    
C 
 
 
 
rb   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 instancerm   r;   rj   rk   rJ   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Brb   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_items6  s:     %S%7%78t=d=f=>rb   N)
ro   r_  r`  ra  rg  r  r  r%   r  r#  r   rb   r\   r1  r1    sw     ILN
Cf 
CS 
CC 
CC 
C 
C f S C C  rb   r1  )	metaclass)i   )Fr   ).)T)r_   __all__r`   r   abcr   
contextlib	functoolsr   r  loggingrS   os.pathr|   r   pathlibr   rh  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/   r0   r1   r2   r3   r4   r5   r6   git.cmdr7   
git.configr8   r9   
git.remoter:   git.repo.baser;   	git.typesr<   r=   r>   r?   r@   rA   rB   rC   rD   rE   	getLoggerro   rV   r   r   r]   ra   r   rc   rd   r   contextmanagerrw   r{   r   r   rb  r   r   r   r   r   r   r   r   r   r   ri  Ir   rc  r   r   r   r   r
  r  r   r   r  r  r/  r   r   r   r   r   r   r   r
   r	   r+  r%  r1  r   rb   r\   <module>rG     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& [)| 1( 1 1h4 "%- %rb   