B
    %d7                 @   s  U d dl mZmZ d dlmZ d dl mZ ddlmZ ddl	m
Z
m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mZmZmZmZmZmZmZ d dlm Z m!Z! erd dl"m#Z# d dl$m%Z% ee&e'e(f Z)eeed eed f  Z*dd Z+ee(e(ge'f e,d< dZ-e)e)e'dddZ.ee) ee)e)ge'f ddddZ/G dd de0Z1G dd de
ej2ej3ej4Z5e5e5j6e5j7< dS )    )IterableList	join_pathN)
to_bin_sha   )util)IndexObjectIndexObjUnion)Blob)	Submodule)tree_entries_from_datatree_to_stream)AnyCallableDictIterableIteratorListTupleTypeUnioncastTYPE_CHECKING)PathLikeLiteral)Repo)BytesIO)TreeN)r
   r
   c             C   s   | |k| |k  S )N )abr   r   ]/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/git/objects/tree.py<lambda>4       r!   cmp)TreeModifierr   )t1t2returnc             C   sX   | d |d  }}t |t | }}t||}t|d | |d | }|rP|S || S )N   )lenminr#   )r%   r&   r   r   Zlen_alen_bmin_lenZmin_cmpr   r   r    git_cmp9   s    
r-   )r   r#   r'   c             C   s  t | dk rd S t | d }| d | }| |d  }t|| t|| d}d}d}xd|t |k r|t |k r||| || dkr|| | |< |d }n|| | |< |d }|d }qVW x,|t |k r|| | |< |d }|d }qW x.|t |k r|| | |< |d }|d }qW d S )Nr(   r   r   )r)   
merge_sort)r   r#   midZlefthalfZ	righthalfijkr   r   r    r.   F   s2    


r.   c               @   s   e Zd ZdZdZee ddddZee	ddd	Z
d d
ddZdee	eed dddZee	eddddZeddddZdS )r$   zA utility class providing methods to alter the underlying cache in a list-like fashion.

    Once all adjustments are complete, the _cache, which really is a reference to
    the cache of a tree, will be sorted. Assuring it will be in a serializable state_cacheN)cacher'   c             C   s
   || _ d S )N)r3   )selfr4   r   r   r    __init__r   s    zTreeModifier.__init__)namer'   c             C   s,   x&t | jD ]\}}|d |kr|S qW dS )z7:return: index of an item with name, or -1 if not foundr(   )	enumerater3   )r5   r7   r0   tr   r   r    _index_by_nameu   s    zTreeModifier._index_by_name)r'   c             C   s   t | jt | S )zCall this method once you are done modifying the tree information.
        It may be called several times, but be aware that each call will cause
        a sort operation

        :return self:)r.   r3   r-   )r5   r   r   r    set_done   s    zTreeModifier.set_doneF)shamoder7   forcer'   c             C   s   d|krt d|d? tjkr*t d| t|}| |}|||f}|dkr\| j| n>|rl|| j|< n.| j| }|d |ks|d |krt d| | S )	aA  Add the given item to the tree. If an item with the given name already
        exists, nothing will be done, but a ValueError will be raised if the
        sha and mode of the existing item do not match the one you add, unless
        force is True

        :param sha: The 20 or 40 byte sha of the item to add
        :param mode: int representing the stat compatible mode of the item
        :param force: If True, an item with your name and information will overwrite
            any existing item with the same name, no matter which information it has
        :return: self/z$Name must not contain '/' characters   z(Invalid object type according to mode %or8   r   r   z)Item %r existed with different properties)
ValueErrorr   _map_id_to_typer   r;   r3   append)r5   r=   r>   r7   r?   indexitemZex_itemr   r   r    add   s    


zTreeModifier.add)binshar>   r7   r'   c             C   s<   t |trt |trt |ts"t|||f}| j| dS )zAdd the given item to the tree, its correctness is assumed, which
        puts the caller into responsibility to assure the input is correct.
        For more information on the parameters, see ``add``

        :param binsha: 20 byte binary shaN)
isinstancebytesintstrAssertionErrorr3   rD   )r5   rH   r>   r7   Z
tree_cacher   r   r    add_unchecked   s    "
zTreeModifier.add_uncheckedc             C   s   |  |}|dkr| j|= dS )z0Deletes an item with the given name if it existsr8   N)r;   r3   )r5   r7   rE   r   r   r    __delitem__   s    
zTreeModifier.__delitem__)F)__name__
__module____qualname____doc__	__slots__r   TreeCacheTupr6   rL   rK   r;   r<   rJ   boolrG   rN   rO   r   r   r   r    r$   i   s   
$r$   c                   sZ  e Zd ZU dZdZed ed< dZdZdZ	dZ
dZeee	ee
eiZeeee f ed	< ed
> dfdeeeedf d fddZeeeed ed f dddZedd fddZee ee dddZeedddZ eedddZ!e"e#d  d d!d"Z$e"e#e d d#d$Z%e"e&d d%d&Z'd'd( d)d( d*d+d,d-d,fe(eee)f ege*f e(eee)f ege*f ee*e*ee*eee ee) f d. fd/d0Z+e,e,e-e d1 fd2d3Z.eee#e d4d5d6Z/ee d d7d8Z0ed d9d:Z1eeee2f ed;d<d=Z3eeef e*d;d>d?Z4ee d d@dAZ5dBd dCdDdEZ6dBd dCdFdGZ7  Z8S )Hr   zTree objects represent an ordered list of Blobs and other Trees.

    ``Tree as a list``::

        Access a specific blob using the
        tree['filename'] notation.

        You may as well access by index
        blob = tree[0]
    treetyper3         
      rC   rA   Nr   )reporH   r>   pathc                s   t t| |||| d S )N)superr   r6   )r5   r]   rH   r>   r^   )	__class__r   r    r6      s    zTree.__init__)r   .r   )index_objectr'   c             C   s   |j dkrt||jS dS )NrW   r   )rX   tuple_iter_convert_to_objectr3   )clsra   r   r   r    _get_intermediate_items   s    
zTree._get_intermediate_items)attrr'   c                s<   |dkr(| j j| j}t| | _ntt| 	| d S )Nr3   )
r]   ZodbstreamrH   r   readr3   r_   r   _set_cache_)r5   rf   Zostream)r`   r   r    ri      s    zTree._set_cache_)iterabler'   c             c   sz   xt|D ]l\}}}t | j|}y | j|d?  | j|||V  W q tk
rp } ztd||f |W dd}~X Y qX qW dS )zwIterable yields tuples of (binsha, mode, name), which will be converted
        to the respective object representationrA   z0Unknown mode %o found in tree data for path '%s'N)r   r^   rC   r]   KeyError	TypeError)r5   rj   rH   r>   r7   r^   er   r   r    rc      s     zTree._iter_convert_to_object)filer'   c       	   	   C   s   d}d|kr| }| }| d}xLt|D ]@\}}|| }|jdkrH|}q(|t|d krdt|| |S q(W || krt|| |S xL| jD ]B}|d |kr| j|d d?  | j|d |d t| j	|d S qW t|| dS )	zFind the named object in this tree's contents

        :return: ``git.Blob`` or ``git.Tree`` or ``git.Submodule``
        :raise KeyError: if given file or tree does not exist in treezBlob or Tree named %r not foundr@   rW   r   r(   rA   r   N)
splitr9   rX   r)   rk   r3   rC   r]   r   r^   )	r5   rn   msgrW   rF   tokensr0   tokeninfor   r   r    join  s(    

&z	Tree.joinc             C   s
   |  |S )zFor PY3 only)rt   )r5   rn   r   r   r    __truediv__(  s    zTree.__truediv__)r'   c             C   s   dd | D S )z?:return: list(Tree, ...) list of trees directly below this treec             S   s   g | ]}|j d kr|qS )rW   )rX   ).0r0   r   r   r    
<listcomp>/  s    zTree.trees.<locals>.<listcomp>r   )r5   r   r   r    trees,  s    z
Tree.treesc             C   s   dd | D S )z?:return: list(Blob, ...) list of blobs directly below this treec             S   s   g | ]}|j d kr|qS )blob)rX   )rv   r0   r   r   r    rw   4  s    zTree.blobs.<locals>.<listcomp>r   )r5   r   r   r    blobs1  s    z
Tree.blobsc             C   s
   t | jS )aM  
        :return: An object allowing to modify the internal cache. This can be used
            to change the tree's contents. When done, make sure you call ``set_done``
            on the tree modifier, or serialization behaviour will be incorrect.
            See the ``TreeModifier`` for more information on how to alter the cache)r$   r3   )r5   r   r   r    r4   6  s    z
Tree.cachec             C   s   dS )NTr   )r0   dr   r   r    r!   A  r"   zTree.<lambda>c             C   s   dS )NFr   )r0   r{   r   r   r    r!   B  r"   r8   TFr   )	predicateprunedepthbranch_first
visit_onceignore_selfas_edger'   c          
      s0   t ttt tt f tt| ||||||S )zFor documentation, see util.Traversable._traverse()
        Trees are set to visit_once = False to gain more performance in the traversal)r   r   r   r   TraversedTreeTupr_   r   	_traverse)r5   r|   r}   r~   r   r   r   r   )r`   r   r    traverse?  s    
zTree.traverse)argskwargsr'   c                s   t t| j||S )z
        :return: IterableList with the results of the traversal as produced by
            traverse()
            Tree -> IterableList[Union['Submodule', 'Tree', 'Blob']]
        )r_   r   Z_list_traverse)r5   r   r   )r`   r   r    list_traverseb  s    zTree.list_traverse)r0   r1   r'   c             C   s   t | | j|| S )N)listrc   r3   )r5   r0   r1   r   r   r    __getslice__l  s    zTree.__getslice__c             C   s   |  | jS )N)rc   r3   )r5   r   r   r    __iter__o  s    zTree.__iter__c             C   s
   t | jS )N)r)   r3   )r5   r   r   r    __len__r  s    zTree.__len__)rF   r'   c             C   sj   t |trF| j| }| j|d d?  | j|d |d t| j|d S t |trZ| |S t	d| d S )Nr   rA   r   r(   zInvalid index type: %r)
rI   rK   r3   rC   r]   r   r^   rL   rt   rl   )r5   rF   rs   r   r   r    __getitem__u  s    

2

zTree.__getitem__c             C   s^   t |tr.xN| jD ]}|j|d krdS qW n,| j}x$| jD ]}|t||d kr<dS q<W dS )Nr   Tr(   F)rI   r   r3   rH   r^   r   )r5   rF   rs   r^   r   r   r    __contains__  s    

zTree.__contains__c             C   s   t | | jS )N)reversedrc   r3   )r5   r   r   r    __reversed__  s    zTree.__reversed__r   )rg   r'   c             C   s   t | j|j | S )a
  Serialize this tree into the stream. Please note that we will assume
        our tree data to be in a sorted state. If this is not the case, serialization
        will not generate a correct tree representation as these are assumed to be sorted
        by algorithms)r   r3   write)r5   rg   r   r   r    
_serialize  s    zTree._serializec             C   s   t | | _| S )N)r   rh   r3   )r5   rg   r   r   r    _deserialize  s    zTree._deserialize)9rP   rQ   rR   rS   rX   r   __annotations__rT   	commit_idZblob_idZ
symlink_idtree_idr
   r	   rC   r   rK   r   r   rJ   r   r   r6   classmethodr   re   rL   ri   r   rU   r   rc   rt   ru   propertyr   rx   rz   r$   r4   r   r   rV   r   r   r   r   r   r   r   slicer   r   r   r   r   __classcell__r   r   )r`   r    r      sT   
$ 	"
:"
r   )8Zgit.utilr   r   Zgit.diffdiffZgit_diffr    r   baser   r   ry   r	   Zsubmodule.baser
   Zfunr   r   typingr   r   r   r   r   r   r   r   r   r   r   Z	git.typesr   r   Zgit.repor   ior   rJ   rK   rL   rU   r   r#   r   __all__r-   r.   objectr$   ZDiffableZTraversableZSerializabler   rC   r   r   r   r   r    <module>   s.    4	"#Z e