a
    _Df`A                  	   @   s  d Z g dZddlmZ ddlZddlmZ ddlm	Z	 ddl
mZmZmZmZmZmZmZ ddlZddlZddlmZ ddlmZ dd	lmZmZ dd
lmZmZmZmZ ddl m!Z!m"Z" ddl#m$Z$m%Z%m&Z& ddl'm(Z(m)Z) ddl*m+Z+m,Z,m-Z-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; ddl<m=Z= e7rjddl>m?Z? ddl@mAZA ddlBmCZC eeB ZDe- ZEeFe=eFdddZGeFeFdddZHeFdeFddddZIeJeJd d!d"ZKde(fe6e:e+d#f  e4eL e:deLf e9e( dd$d%d&ZMe4eL e8eJeJf d'd(d)ZNe:e+e=eJf e8e=eJf d*d+d,ZOe4eL e8eJe3e8e=eJf d#f eLeLf d'd-d.ZPd:e5e, d/eQeJe8eLe5d0 f d1d2d3ZRd0eJe+d4d5d6ZSd/e6eL e5e+ d7d8d9ZTdS );zVStandalone functions to accompany the index implementation and make it more
versatile.)write_cache
read_cachewrite_tree_from_cache	entry_keystat_mode_to_index_modeS_IFGITLINKrun_commit_hook	hook_path    )BytesION)Path)S_IFDIRS_IFLNKS_IFMTS_IFREGS_ISDIRS_ISLNKS_IXUSR)IStream)str_tree_type)handle_process_outputsafer_popen)defencforce_bytes
force_textsafe_decode)HookExecutionErrorUnmergedEntriesError)traverse_tree_recursivetraverse_trees_recursivetree_to_stream)IndexFileSHA1Writerfinalize_process   )BaseIndexEntry
IndexEntryCE_NAMEMASKCE_STAGESHIFT)packunpack)	DictIOListSequenceTYPE_CHECKINGTupleTypeUnioncast)PathLike)GitCmdObjectDB)TreeCacheTup)	IndexFile)namegit_dirreturnc                 C   s   t |d| S )zK:return: path to the given named hook in the given git repository directoryhooks)ospjoin)r6   r7    r<   Z/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/git/index/fun.pyr   >   s    r   )pathr8   c                 C   s   t | d S )Nr"   )r:   splitext)r>   r<   r<   r=   _has_file_extensionC   s    r@   r5   )r6   indexargsr8   c              
   G   s4  t | |jj}t|tjs dS tj }tt	|j
|d< d|d< |g}zVtjdkr|t|s|t||jj }d|g}t|t| |tjtj|jjd}W n0 ty } zt|||W Y d}~nhd}~0 0 g }	g }
t||	j|
jt d|	}d|
}|jd	kr0t|t}t|t}t||j||dS )
a:  Run the commit hook of the given name. Silently ignore hooks that do not exist.

    :param name:
        Name of hook, like ``pre-commit``.

    :param index:
        :class:`~git.index.base.IndexFile` instance.

    :param args:
        Arguments passed to hook file.

    :raise git.exc.HookExecutionError:
    NZGIT_INDEX_FILE:Z
GIT_EDITORwin32zbash.exe)envstdoutstderrcwd r	   )r   repor7   osaccessX_OKenvironcopyr   strr>   sysplatformr@   r   relative_toZworking_diras_posixr   list
subprocessPIPE	Exceptionr   r   appendr!   r;   
returncoder   r   )r6   rA   rB   hprE   cmdZrelative_hpprocessexZstdout_listZstderr_listrF   rG   r<   r<   r=   r   G   s:    


"



r   )moder8   c                 C   s8   t | rtS t| s t| tkr$tS t| t@ r2dp4dB S )zZConvert the given mode from a stat call to the corresponding index mode and
    return it.i  i  )r   r   r   r   r   r   r   )r_   r<   r<   r=   r   z   s
    r   r$   )entriesstreamextension_dataShaStreamClsr8   c                 C   s  ||}|j }|j}d}|d |td|t|  | D ]}| }	||j ||j t|j}
t|
t	d}t|t
@ }|t|ksJ d|j ||jt@ B }|td|j|j|j|j|j|j|j|	 || | |	 d d@ }|d	|	| |    q8|d
ur|| |  d
S )a  Write the cache represented by entries to a stream.

    :param entries:
        **Sorted** list of entries.

    :param stream:
        Stream to wrap into the AdapterStreamCls - it is used for final output.

    :param ShaStreamCls:
        Type to use when writing to the stream. It produces a sha while writing to it,
        before the data is passed on to the wrapped stream.

    :param extension_data:
        Any kind of data to write as a trailer, it must begin a 4 byte identifier,
        followed by its size (4 bytes).
          DIRC>LL)encodingz"Path %s too long to fit into index>LLLLLL20sH       N)tellwriter'   lenZctime_bytesZmtime_bytesrP   r>   r   r   r%   flagsCE_NAMEMASK_INVdevinoder_   uidgidsizebinshaZ	write_sha)r`   ra   rb   rc   Z
stream_sharl   rm   versionentrybeginoffsetZpath_strr>   plenro   	real_sizer<   r<   r=   r      sD    




r   )ra   r8   c                 C   sX   |  d}|dkrtd| ttttf td|  d}|\}}|dv sPJ ||fS )z>Return tuple(version_long, num_entries) from the given stream.   re   zInvalid index file header: %rrf   ri   r"   rd   )readAssertionErrorr1   r.   intr(   )ra   Ztype_idunpackedrw   num_entriesr<   r<   r=   read_header   s    
r   )rx   r8   c                  G   sH   t | dkr.| d }t|ts"J |j|jfS ttttf | } | S dS )z
    :return:
        Key suitable to be used for the
        :attr:`index.entries <git.index.base.IndexFile.entries>` dictionary.

    :param entry:
        One instance of type BaseIndexEntry or the path and the stage.
    r"   r	   N)	rn   
isinstancer#   r>   stager1   r.   r2   r   )rx   Zentry_firstr<   r<   r=   r      s    r   c                 C   s,  t | \}}d}i }| j}| j}||k r| }td|dd }td|dd }	td|d\}
}}}}}}}|t@ }||t}| | d d@ }||| |   t||||||	|
||||f}||||jf< |d7 }q | d}t	|d	ksJ d
t	| |dd }|dd }||||fS )a  Read a cache file from the given stream.

    :return:
        tuple(version, entries_dict, extension_data, content_sha)

        * *version* is the integer version number.
        * *entries_dict* is a dictionary which maps IndexEntry instances to a path at a
          stage.
        * *extension_data* is ``""`` or 4 bytes of type + 4 bytes of size + size bytes.
        * *content_sha* is a 20 byte sha on all cache file contents.
    r	   z>8sri   rh   .   rj   r"      zNIndex Footer was not at least a sha on content as it was only %i bytes in sizeiN)
r   r~   rl   r(   r%   decoder   r$   r   rn   )ra   rw   r   countr`   r~   rl   ry   ctimemtimerq   inor_   rs   rt   ru   sharo   Z	path_sizer>   r{   rx   rb   Zcontent_shar<   r<   r=   r      s0    
	

r   r3   r4   )r`   odbslsir8   c                 C   s<  g }|j }|j}||k r| | }|jdkr2t||d7 }|jd|}|dkrp||j|j|j|d f q|j|| }	|}
|
|k r| |
 }|jd|}|dks|j|| |	krq|
d7 }
qt	| |t
|d |
|d \}}||t|	f |
}qt }t||j |d |ttt| |}|j|fS )aN  Create a tree from the given sorted list of entries and put the respective
    trees into the given object database.

    :param entries:
        **Sorted** list of :class:`~git.index.typ.IndexEntry`\s.

    :param odb:
        Object database to store the trees in.

    :param si:
        Start index at which we should start creating subtrees.

    :param sl:
        Slice indicating the range we should process on the entries list.

    :return:
        tuple(binsha, list(tree_entry, ...))

        A tuple of a sha and a list of tree entries being a tuple of hexsha, mode, name.
    r	   r"   /r   N)startstopr   r   r>   findrY   rv   r_   r   slicer   r
   r   rm   seekstorer   r   rn   getvalue)r`   r   r   r   Z
tree_itemsciendrx   ZrboundbasexiZoentryZorboundr   Z_tree_entry_listsioZistreamr<   r<   r=   r   %  s6    
 
 
r   )
tree_entryr   r8   c                 C   s    t | d | d |t> | d fS )Nr"   r	   rd   )r#   r&   )r   r   r<   r<   r=   _tree_entry_to_baseindexentryj  s    r   )r   	tree_shasr8   c                 C   s  g }t |dv r:t| |d dD ]}|t|d q |S t |dkrVtdt | t| |dD ]<\}}}|dur|dur|durl|d |d kr|d |d kr|d |d ks|d |d kr$|d |d kr$|d |d kr$|t|d |t|d	 |t|d nF|d |d ksH|d |d krZ|t|d n|t|d nD|d |d ks|d |d kr|t|d |t|d	 nP|du rnD|d |d ks|d |d kr|t|d |t|d qb|du r.|dusJ |t|d qb|du rJ|t|d qb|d |d ksn|d |d kr|t|d	 |t|d qb|t|d qb|S )
a7  
    :return:
        List of :class:`~git.index.typ.BaseIndexEntry`\s representing the aggressive
        merge of the given trees. All valid entries are on stage 0, whereas the
        conflicting ones are left on stage 1, 2 or 3, whereas stage 1 corresponds to the
        common ancestor tree, 2 to our tree and 3 to 'their' tree.

    :param tree_shas:
        1, 2 or 3 trees as identified by their binary 20 byte shas. If 1 or two, the
        entries will effectively correspond to the last given tree. If 3 are given, a 3
        way merge is performed.
    r}   r   rI   r	      zCannot handle %i trees at onceNr"   rd   )rn   r   rY   r   
ValueErrorr   )r   r   outrx   r   ZoursZtheirsr<   r<   r=   aggressive_tree_mergen  sT    


0$$
$	

$r   )r	   )U__doc____all__ior
   rK   os.pathr>   r:   pathlibr   statr   r   r   r   r   r   r   rV   rQ   Z
gitdb.baser   Z	gitdb.typr   Zgit.cmdr   r   Z
git.compatr   r   r   r   Zgit.excr   r   Zgit.objects.funr   r   r   Zgit.utilr    r!   typr#   r$   r%   r&   utilr'   r(   typingr)   r*   r+   r,   r-   r.   r/   r0   r1   Z	git.typesr2   Zgit.dbr3   Zgit.objects.treer4   r   r5   r   rp   rP   r   r@   r   r   r   bytesr   r   r   r   r   r   r   r   r<   r<   r<   r=   <module>   sd   $,3
E"8 E