U
    楡c                     @   s   d dl mZ d dlmZmZ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mZ d dlmZmZmZ erd dlmZ d d	lmZ dd
lmZ ddlmZ ddlm Z  d dl!m"Z" ed Z#dZ$dZ%G dd deZ&G dd de&Z'dS )    )WorkTreeRepositoryUnsupported)	LazyMixinjoin_path_nativestream_copy
bin_to_hexN   )get_object_type_by_name)AnyTYPE_CHECKINGUnion)PathLike
Commit_ishLit_commit_ish)Repo)OStream)Tree)Blob)	Submodule)	Reference)r   r   r   zSCreated object %r whose python type %r disagrees with the actual git object type %r)ObjectIndexObjectc                       s$  e Zd ZU dZdZdZejejej	ej
fZdZdZeedf ed< ded fd	d
Zedeedf edddZedeedddZedd fddZeedddZeedddZedddZedddZeddd Z e!edd!d"Z"e!d#dd$d%Z#d#d d&d'd(Z$  Z%S ))r   z@Implements an Object which may be Blobs, Trees, Commits and TagsZ(0000000000000000000000000000000000000000s                       )repobinshasizeNtyper   )r   r   c                    s>   t t|   || _|| _t|dks:td|t|f dS )zInitialize an object by identifying it by its binary sha.
        All keyword arguments will be set on demand if None.

        :param repo: repository this object is located in

        :param binsha: 20 byte SHA1   z,Require 20 byte binary sha, got %r, len = %iN)superr   __init__r   r   lenAssertionError)selfr   r   	__class__ 4/tmp/pip-unpacked-wheel-_pbxsds5/git/objects/base.pyr   8   s    zObject.__init__r   )r   idreturnc                 C   s   | t|S )a  
        :return: New Object instance of a type appropriate to the object type behind
            id. The id of the newly created object will be a binsha even though
            the input id may have been a Reference or Rev-Spec

        :param id: reference, rev-spec, or hexsha

        :note: This cannot be a __new__ method as it would always call __init__
            with the input id which is not necessarily a binsha.)Z	rev_parsestr)clsr   r%   r#   r#   r$   newG   s    z
Object.new)r   sha1r&   c                 C   sB   || j krtd||S |j|}t|j||j}|j|_|S )z
        :return: new object instance of a type appropriate to represent the given
            binary sha1
        :param sha1: 20 byte binary sha1s   commit)NULL_BIN_SHAr   odbinfor   r   r   )r(   r   r*   oinfoinstr#   r#   r$   new_from_shaT   s    
zObject.new_from_shaattrr&   c                    s6   |dkr"| j j| j}|j| _ntt| | dS )zRetrieve object informationr   N)r   r,   r-   r   r   r   r   _set_cache_)r    r2   r.   r!   r#   r$   r3   c   s    
zObject._set_cache_)otherr&   c                 C   s   t |dsdS | j|jkS )z/:return: True if the objects have the same SHA1r   Fhasattrr   r    r4   r#   r#   r$   __eq__l   s    
zObject.__eq__c                 C   s   t |dsdS | j|jkS )z6:return: True if the objects do not have the same SHA1r   Tr5   r7   r#   r#   r$   __ne__r   s    
zObject.__ne__r&   c                 C   s
   t | jS )zE:return: Hash of our id allowing objects to be used in dicts and sets)hashr   r    r#   r#   r$   __hash__x   s    zObject.__hash__c                 C   s   | j S )z=:return: string of our SHA1 as understood by all git commands)hexshar<   r#   r#   r$   __str__|   s    zObject.__str__c                 C   s   d| j j| jf S )z::return: string with pythonic representation of our objectz<git.%s "%s">)r"   __name__r>   r<   r#   r#   r$   __repr__   s    zObject.__repr__c                 C   s   t | jdS )z6:return: 40 byte hex version of our 20 byte binary shaascii)r   r   decoder<   r#   r#   r$   r>      s    zObject.hexshar   c                 C   s   | j j| jS )z:return:  File Object compatible stream to the uncompressed raw data of the object
        :note: returned streams must be read in order)r   r,   streamr   r<   r#   r#   r$   data_stream   s    zObject.data_stream)ostreamr&   c                 C   s   | j j| j}t|| | S )zWrites our data directly to the given output stream
        :param ostream: File object compatible stream object.
        :return: self)r   r,   rD   r   r   )r    rF   Zistreamr#   r#   r$   stream_data   s    
zObject.stream_data)&r@   
__module____qualname____doc__ZNULL_HEX_SHAr+   dbtypZstr_blob_typeZstr_tree_typeZstr_commit_typeZstr_tag_typeTYPES	__slots__r   r   r   __annotations__bytesr   classmethodr'   r   r)   r0   r3   r	   boolr8   r9   intr=   r?   rA   propertyr>   rE   rG   __classcell__r#   r#   r!   r$   r   (   s4   
	r   c                       s   e Zd ZdZdZdZddeedef ede	f dd fddZ
ed	d
dZedd fddZeed	ddZee	d	ddZ  ZS )r   zeBase for all objects that can be part of the index file , namely Tree, Blob and
    SubModule objects)pathmoderU   Nr   )r   r   rV   rU   r&   c                    s2   t t| || |dk	r || _|dk	r.|| _dS )aJ  Initialize a newly instanced IndexObject

        :param repo: is the Repo we are located in
        :param binsha: 20 byte sha1
        :param mode:
            is the stat compatible file mode as int, use the stat module
            to evaluate the information
        :param path:
            is the path to the file in the file system, relative to the git repository root, i.e.
            file.ext or folder/other.ext
        :note:
            Path may not be set of the index object has been created directly as it cannot
            be retrieved without knowing the parent tree.N)r   r   r   rV   rU   )r    r   r   rV   rU   r!   r#   r$   r      s
    zIndexObject.__init__r:   c                 C   s
   t | jS )z
        :return:
            Hash of our path as index items are uniquely identifiable by path, not
            by their data !)r;   rU   r<   r#   r#   r$   r=      s    zIndexObject.__hash__r1   c                    s6   |t jkr"td|t| jf ntt | | d S )Nz[Attribute '%s' unset: path and mode attributes must have been set during %s object creation)r   rM   AttributeErrorr   r@   r   r3   )r    r2   r!   r#   r$   r3      s    
zIndexObject._set_cache_c                 C   s   t | jS )zA:return: Name portion of the path, effectively being the basename)ospbasenamerU   r<   r#   r#   r$   name   s    zIndexObject.namec                 C   s(   | j jdk	rt| j j| jS tddS )a	  
        :return:
            Absolute path to this index object in the file system ( as opposed to the
            .path field which is a path relative to the git repository ).

            The returned path will be native to the system and contains '' on windows.Nz"Working_tree_dir was None or empty)r   Zworking_tree_dirr   rU   r   r<   r#   r#   r$   abspath   s    zIndexObject.abspath)NN)r@   rH   rI   rJ   rM   Z_id_attribute_rO   r   rR   r   r   r=   r'   r3   rS   rZ   r[   rT   r#   r#   r!   r$   r      s$     

r   )(Zgit.excr   Zgit.utilr   r   r   r   Z	gitdb.typtyprK   os.pathrU   rX   utilr   typingr	   r
   r   Z	git.typesr   r   r   Zgit.repor   Z
gitdb.baser   treer   Zblobr   Zsubmodule.baser   Zgit.refs.referencer   ZIndexObjUnionZ_assertion_msg_format__all__r   r   r#   r#   r#   r$   <module>   s$   q