o
    ĎiB                     @   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.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z> e8rddl?m@Z@ ddlAmBZB ddlCmDZD eeB ZE	 e. ZFdeGde>deGfddZHdeGdeGfddZIdeGddd eGddfd!d"ZJd#eKdeKfd$d%ZLde(fd&e7e;e,d'f  d(e5eM d)e;deMf d*e:e( ddf
d+d,ZNd(e5eM de9eKeKf fd-d.ZOd/e;e,e>eKf de9e>eKf fd0d1ZPd(e5eM de9eKe4e9e>eKf d'f eMeMf fd2d3ZQ	dBd&e6e- d4d5d6eRd7eKde9eMe6d8 f f
d9d:ZSd;d8d<eKde,fd=d>ZTd4d5d?e7eM de6e, fd@dAZUdS )CzVStandalone 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   )CE_EXTENDED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)r7   r8    r=   I/home/jeff/fluffinator/venv/lib/python3.10/site-packages/git/index/fun.pyr   >   s   r   pathc                 C   s   t | d S )Nr"   )r;   splitext)r?   r=   r=   r>   _has_file_extensionC   s   rA   indexr6   argsc              
   G   s(  t | |jj}t|tjsdS tj }tt	|j
|d< d|d< |g}z+tjdkr?t|s?t||jj }d|g}t|t| |tjtj|jjd}W n tyc } zt|||d}~ww g }	g }
t||	j|
jt d|	}d|
}|jd	krt|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:
    NGIT_INDEX_FILE:
GIT_EDITORwin32zbash.exe)envstdoutstderrcwd r	   )r   repor8   osaccessX_OKenvironcopyr   fspathr?   sysplatformrA   r   relative_toworking_diras_posixr   list
subprocessPIPE	Exceptionr   r   appendr!   r<   
returncoder   r   )r7   rB   rC   hprH   cmdrelative_hpprocessexstdout_liststderr_listrI   rJ   r=   r=   r>   r   G   s@   







r   modec                 C   s8   t | rtS t| st| tkrtS t| t@ rdpd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   )rf   r=   r=   r>   r   z   s
   r   entriesr%   streamextension_dataShaStreamClsc                 C   sT  ||}|j }|j}tdd | D rdnd}|d |td|t|  | D ]s}| }	||j ||j t|j}
t	|
t
d}t|t@ }|t|ksTJ d|j ||jt@ B }|jrb|tO }|td	|j|j|j|j|j|j|j|	 |jr|td
|j || | |	 d d@ }|d|	| |    q'|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).
    c                 s   s    | ]}|j V  qd S )N)extended_flags).0entryr=   r=   r>   	<genexpr>   s    zwrite_cache.<locals>.<genexpr>         DIRC>LL)encodingz"Path %s too long to fit into index>LLLLLL20sH>H       N)tellwriteanyr(   lenctime_bytesmtime_bytesstrr?   r   r   r&   flagsCE_NAMEMASK_INVrk   r#   devinoderf   uidgidsizebinsha	write_sha)rg   rh   ri   rj   
stream_shary   rz   versionrm   beginoffsetpath_strr?   plenr   	real_sizer=   r=   r>   r      sL   



r   c                 C   s`   |  d}|dkrtd| ttttf td|  d}|\}}|dv s,J d| ||fS )z>Return tuple(version_long, num_entries) from the given stream.   rq   zInvalid index file header: %rrr   rv   )r"   rp   ro   z@Unsupported git index version %i, only 1, 2, and 3 are supported)readAssertionErrorr2   r/   intr)   )rh   type_idunpackedr   num_entriesr=   r=   r>   read_header   s   
r   rm   c                  G   sD   t | dkr| d }t|tsJ |j|jfS ttttf | } | 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	   )	r|   
isinstancer$   r?   stager2   r/   r3   r   )rm   entry_firstr=   r=   r>   r      s   r   c                 C   sP  t | \}}d}i }| j}| j}||k r| }td|dd }td|dd }	td|d\}
}}}}}}}d}|t@ rGtd|dd }|t@ }||t}| | d d@ }||| |   t||||||	|
|||||f}||||j	f< |d	7 }||k s| d
}t
|dksJ 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>8srv   rt   .   ru   rp   rw   r"      zNIndex Footer was not at least a sha on content as it was only %i bytes in sizeiN)r   r   ry   r)   r#   r&   decoder   r%   r   r|   )rh   r   r   countrg   r   ry   r   ctimemtimer   inorf   r   r   r   shar   rk   	path_sizer?   r   rm   ri   content_shar=   r=   r>   r      s8    

r   odbr4   slsir5   c                 C   sH  g }|j }|j}||k r| | }|jdkrt||d7 }|jd|}|dkr8||j|j|j|d f nH|j|| }	|}
|
|k rf| |
 }|jd|}|dks]|j|| |	kr^n|
d7 }
|
|k sEt	| |t
|d |
|d \}}||t|	f |
}||k s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?   findr]   r   rf   r   slicer   r
   r   rz   seekstorer   r   r|   getvalue)rg   r   r   r   
tree_itemsciendrm   rboundbasexioentryorboundr   _tree_entry_listsioistreamr=   r=   r>   r   +  s:   
  "

r   
tree_entryr   c                 C   s    t | d | d |t> | d fS )Nr"   r	   rp   )r$   r'   )r   r   r=   r=   r>   _tree_entry_to_baseindexentryp  s    r   	tree_shasc                 C   s  g }t |dv rt| |d dD ]
}|t|d q|S t |dkr+tdt | t| |dD ]\}}}|dur|dur|dur|d |d kr[|d |d kr[|d |d kss|d |d kr|d |d kr|d |d kr|t|d |t|d	 |t|d q1|d |d ks|d |d kr|t|d q1|t|d q1|d |d ks|d |d kr|t|d |t|d	 q1|du rq1|d |d ks|d |d kr|t|d |t|d q1|du r
|dusJ |t|d q1|du r|t|d q1|d |d ks*|d |d kr;|t|d	 |t|d q1|t|d q1|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"   rp   r   rL   r	   ro   zCannot handle %i trees at onceNr"   rp   )r|   r   r]   r   
ValueErrorr   )r   r   outrm   r   ourstheirsr=   r=   r>   aggressive_tree_merget  sN   00   
	
$r   )r	   )V__doc____all__ior
   rN   os.pathr?   r;   pathlibr   statr   r   r   r   r   r   r   rZ   rT   
gitdb.baser   	gitdb.typr   git.cmdr   r   
git.compatr   r   r   r   git.excr   r   git.objects.funr   r   r   git.utilr    r!   typr#   r$   r%   r&   r'   utilr(   r)   typingr*   r+   r,   r-   r.   r/   r0   r1   r2   	git.typesr3   git.dbr4   git.objects.treer5   r   r6   r   r   r   r   rA   r   r   r   bytesr   r   r   r   r   r   r   r   r=   r=   r=   r>   <module>   s   $,3

I$
;
E"