o
    Uh7                     @   sP  d 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m	Z	 ddl
mZ ddlmZmZmZmZm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mZm Z m!Z! dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)G dd deZ*e	G dd dZ+e	G dd dZ,G dd dZ-G dd de.Z/de0de1e0e0f fdd Z2d!d" Z3d#d$ Z4dd%d&Z5d'e6de+fd(d)Z7d*e+d'e6ddfd+d,Z8G d-d. d.e.Z9d/edee+ fd0d1Z:de;e0ee,e-f f fd2d3Z<	dd/ed4e=e+ d'ee6 ddfd5d6Z>	dd/ed4e;e0ee,e-f f d'ee6 ddfd7d8Z?d9e6de6fd:d;Z@G d<d= d=ZAd>ed?ee1e0e0e6f  de0fd@dAZBd>edBeAde0fdCdDZC	EddFee0 dGee0ge1e0e6f f d>edHee0 dee1e1ee0 ee0 f e1ee6 ee6 f e1ee0 ee0 f f  f
dIdJZD	ddKe0d9ee6 fdLdMZEejFdNkrG dOdP dPeGZHdddQdRdSZInejIZIdTdUddVdWed9e6dXe0fdYdZZJd[ZKd\e0deLfd]d^ZMd\e0deLfd_d`ZNeMfde0deLfdadbZOdTeMdfdceePe0f ddeePe0f d>edee0dfeLddfdgdhZQddie0d9e6fdjdkZRddie0fdldmZSdeePe0f dee0 fdndoZTdpe0deLfdqdrZU	ddBeAdceePe0f fdsdtZVejWXduZYdce0dpe0fdvdwZZdieePe0f de0fdxdyZ[de0dee, fdzd{Z\	dde0d>ee dee, fd|d}Z]	dd~ee0 dce0d>ee dee1e0ee, f  fddZ^	dd~ee0 dce0dee1e0ee0 ee6 f  fddZ_dBeAdce0ddfddZ`G dd dZadS )z%Parser for the git index file format.    N)IterableIterator)	dataclass)Enum)AnyBinaryIOCallableOptionalUnion   )GitFile)iter_tree_contents)S_IFGITLINKS_ISGITLINKBlobObjectIDTree
hex_to_sha
sha_to_hex)ObjectContainer
SHA1Reader
SHA1Writeri 0     i  i   i @  i       c                   @   s   e Zd ZdZdZdZdZdS )Stager   r   r      N)__name__
__module____qualname__NORMALMERGE_CONFLICT_ANCESTORMERGE_CONFLICT_THISMERGE_CONFLICT_OTHER r#   r#   a/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/dulwich/index.pyr   H   s
    r   c                   @   s   e Zd ZU eed< eeeeeef f ed< eeeeeef f ed< eed< eed< eed< eed< eed< eed	< eed
< eed< eed< de	fddZ
dS )SerializedIndexEntrynamectimemtimedevinomodeuidgidsizeshaflagsextended_flagsreturnc                 C      t | jt@ t? S Nr   r0   FLAG_STAGEMASKFLAG_STAGESHIFTselfr#   r#   r$   stage^      zSerializedIndexEntry.stageN)r   r   r   bytes__annotations__r
   intfloattupler   r:   r#   r#   r#   r$   r%   O   s   
 r%   c                   @   s   e Zd ZU eeeeeef f ed< eeeeeef f ed< eed< eed< eed< eed< eed< eed< eed	< d
Z	eed< d
Z
eed< ededd fddZdededefddZdefddZedefddZddeddfddZdS )
IndexEntryr'   r(   r)   r*   r+   r,   r-   r.   r/   r   r0   r1   
serializedr2   c                 C   s4   | |j |j|j|j|j|j|j|j|j|j	|j
dS )Nr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   rC   )clsrB   r#   r#   r$   from_serializedp   s   zIndexEntry.from_serializedr&   r:   c                 C   sN   | j t @ }||jt> O }t|| j| j| j| j| j	| j
| j| j| j|| jdS )N)r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   )r0   r6   valuer7   r%   r'   r(   r)   r*   r+   r,   r-   r.   r/   r1   )r9   r&   r:   	new_flagsr#   r#   r$   	serialize   s    zIndexEntry.serializec                 C   r3   r4   r5   r8   r#   r#   r$   r:      r;   zIndexEntry.stagec                 C   s   t | jt@ S )z>Return True if the skip-worktree bit is set in extended_flags.)boolr1   EXTENDED_FLAG_SKIP_WORKTREEr8   r#   r#   r$   skip_worktree      zIndexEntry.skip_worktreeTskipNc                 C   sV   |r|  j tO  _ |  jtO  _dS |  j t M  _ | j dkr)|  jt M  _dS dS )zHelper method to set or clear the skip-worktree bit in extended_flags.
        Also sets FLAG_EXTENDED in self.flags if needed.
        r   N)r1   rJ   r0   FLAG_EXTENDED)r9   rM   r#   r#   r$   set_skip_worktree   s   
zIndexEntry.set_skip_worktreeT)r   r   r   r
   r>   r?   r@   r=   r<   r0   r1   classmethodr%   rE   r   rH   r:   propertyrI   rK   rO   r#   r#   r#   r$   rA   b   s&   
 rA   c                	   @   sd   e Zd ZU dZee ed< ee ed< ee ed< 			d	dee dee dee ddfddZdS )
ConflictedIndexEntryz'Index entry that represents a conflict.ancestorthisotherNr2   c                 C   s   || _ || _|| _d S r4   )rT   rU   rV   )r9   rT   rU   rV   r#   r#   r$   __init__   s   
zConflictedIndexEntry.__init__)NNN)r   r   r   __doc__r	   rA   r=   rW   r#   r#   r#   r$   rS      s"   
 rS   c                   @   s   e Zd ZdZdS )UnmergedEntriesz$Unmerged entries exist in the index.N)r   r   r   rX   r#   r#   r#   r$   rY      s    rY   pathr2   c                 C   s6   z|  dd\}}W ||fS  ty   d| f Y S w )zSplit a /-delimited path into a directory part and a basename.

    Args:
      path: The path to split.

    Returns:
      Tuple with directory name and basename
       /r       )rsplit
ValueError)rZ   dirnamebasenamer#   r#   r$   	pathsplit   s   	ra   c                  G   s   d dd | D S )zJoin a /-delimited path.r[   c                 S   s   g | ]}|r|qS r#   r#   ).0pr#   r#   r$   
<listcomp>   s    zpathjoin.<locals>.<listcomp>)join)argsr#   r#   r$   pathjoin   s   rg   c                 C   s   t d| dS )zRead a cache time.

    Args:
      f: File-like object to read from
    Returns:
      Tuple with seconds and nanoseconds
    >LL   )structunpackread)fr#   r#   r$   read_cache_time   s   rn   c                 C   sp   t |tr
|df}n t |tr!t|d\}}t|t|d f}n	t |ts*t|| tjdg|R   dS )zWrite a cache time.

    Args:
      f: File-like object to write to
      t: Time to write (as int, float or tuple with secs and nsecs)
    r   g      ?i ʚ;rh   N)	
isinstancer>   r?   divmodr@   	TypeErrorwriterj   pack)rm   tsecsnsecsr#   r#   r$   write_cache_time   s   



rw   versionc                 C   s   |   }t| }t| }td| d\}}}}}	}
}}|t@ r4|dk r)tdtd| d\}nd}| |t@ }|dk rV|   | d	 d
@ }| || |     t||||||||	|
t	||t @ |S )zWRead an entry from a cache file.

    Args:
      f: File-like object to read from
    z>LLLLLL20sH.   r   z+extended flag set in index with version < 3z>Hr   r      ri   )
tellrn   rj   rk   rl   rN   AssertionErrorFLAG_NAMEMASKr%   r   )rm   rx   beginoffsetr'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r&   	real_sizer#   r#   r$   read_cache_entry   sH   
r   entryc                 C   s  |   }t| |j t| |j t|j|jt @ B }|jr"|t	O }|t	@ r2|dur2|dk r2t
d| td|jd@ |jd@ |j|j|j|jt|j|	 |t	@ r]| td|j | |j |dk r|   | d d	@ }| d
|| |      dS dS )zrWrite an index entry to a file.

    Args:
      f: File object
      entry: IndexEntry to write, tuple with:
    Nr   z+unable to use extended flags in version < 3s   >LLLLLL20sHl    s   >Hrz   ri   r{       )r|   rw   r'   r(   lenr&   r0   r~   r1   rN   r}   rr   rj   rs   r)   r*   r+   r,   r-   r.   r   r/   )rm   r   rx   r   r0   r   r#   r#   r$   write_cache_entry"  s8   r   c                   @   s   e Zd ZdZdddZdS )UnsupportedIndexFormatz,An unsupported index format was encountered.r2   Nc                 C   
   || _ d S r4   )index_format_version)r9   rx   r#   r#   r$   rW   I     
zUnsupportedIndexFormat.__init__r2   N)r   r   r   rX   rW   r#   r#   r#   r$   r   F  s    r   rm   c                 c   sf    |  d}|dkrtd|td|  d\}}|dvr$t|t|D ]}t| |V  q(dS )z4Read an index file, yielding the individual entries.rz      DIRCzInvalid index file header:    >LLri   )r   r   r   N)rl   r}   rj   rk   r   ranger   )rm   headerrx   num_entriesir#   r#   r$   
read_indexM  s   
r   c                 C   s   i }t | D ]M}| }|tjkrt|||j< q||jt }t	|tr0t
d|jd|tjkr<t||_q|tjkrHt||_q|tjkrSt||_q|S )zRead an index file and return it as a dictionary.
       Dict Key is tuple of path and stage number, as
            path alone is not unique
    Args:
      f: File object to read fromls.
    zNon-conflicted entry for z exists)r   r:   r   r   rA   rE   r&   
setdefaultrS   ro   r}   r    rT   r!   rU   r"   rV   )rm   retr   r:   existingr#   r#   r$   read_index_dictY  s    




r   entriesc                 C   s   |du rt }tdd |D }|r|dk rd}|dk r)|D ]}|jdkr(tdq| d | td|t| |D ]	}t| ||d	 q<dS )
zWrite an index file.

    Args:
      f: File-like object to write to
      version: Version number to write
      entries: Iterable over the entries to write
    Nc                 s   s    | ]}|j d kV  qdS )r   N)r1   )rb   er#   r#   r$   	<genexpr>  s    zwrite_index.<locals>.<genexpr>r   r   z+Attempt to use extended flags in index < v3r   r   rx   )	DEFAULT_VERSIONanyr1   r}   rr   rj   rs   r   r   )rm   r   rx   uses_extended_flagsr   r   r#   r#   r$   write_indexr  s   


r   c                 C   s   g }t |D ]F}|| }t|trB|jdur!||j|tj |jdur1||j|tj	 |j
durA||j
|tj q|||tj qt| ||d dS )ztWrite an index file based on the contents of a dictionary.
    being careful to sort by path and then by stage.
    Nr   )sortedro   rS   rT   appendrH   r   r    rU   r!   rV   r"   r   r   )rm   r   rx   entries_listkeyrF   r#   r#   r$   write_index_dict  s&   



r   r+   c                 C   sJ   t | rt jS t | rt jS t| rtS t jdB }| d@ r#|dO }|S )zCleanup a mode value.

    This will return a mode that can be stored in a tree object.

    Args:
      mode: Mode to clean up.

    Returns:
      mode
    i  @   I   )statS_ISLNKS_IFLNKS_ISDIRS_IFDIRr   r   S_IFREG)r+   r   r#   r#   r$   cleanup_mode  s   


r   c                   @   s  e Zd ZU dZeeeeef f e	d< d;deee
f ddfddZed	d
 Zde
fddZd<ddZd<ddZdefddZdedeeef fddZdee fddZdefddZdedefddZdedefddZdeeeeef  fdd Zdefd!d"Zd<d#d$Zd%ed&eeef ddfd'd(Zd%eddfd)d*Z deeeeeef f  fd+d,Z!deeeeeef f  fd-d.Z"d/eeeeef f ddfd0d1Z#d2d3 Z$	4d=d5e%d6efd7d8Z&d9d: Z'dS )>IndexzA Git Index file._bynameTfilenamer2   Nc                 C   s(   || _ d| _|   |r|   dS dS )zCreate an index object associated with the given filename.

        Args:
          filename: Path to the index file
          read: Whether to initialize the index from the given file, should it exist.
        N)	_filename_versionclearrl   )r9   r   rl   r#   r#   r$   rW     s   zIndex.__init__c                 C   s   | j S r4   )r   r8   r#   r#   r$   rZ     s   z
Index.pathc                 C   s   | j j d| jdS )N())	__class__r   r   r8   r#   r#   r$   __repr__  s   zIndex.__repr__c                 C   s@   t | jd}zt|}t|| j| jd W |  dS |  w )z(Write current contents of index to disk.wbr   N)r   r   r   r   r   r   closer9   rm   r#   r#   r$   rr     s
   zIndex.writec                 C   sz   t j| js	dS t| jd}z(t|}| t| |t j	| j|
  d  |jdd W |  dS |  w )z)Read current contents of index from disk.Nrb   T)allow_empty)osrZ   existsr   r   r   updater   rl   getsizer|   	check_shar   r   r#   r#   r$   rl     s    z
Index.readc                 C   
   t | jS )z%Number of entries in this index file.)r   r   r8   r#   r#   r$   __len__     
zIndex.__len__r   c                 C   s
   | j | S )zRetrieve entry by relative path and stage.

        Returns: Either a IndexEntry or a ConflictedIndexEntry
        Raises KeyError: if the entry does not exist
        r   r9   r   r#   r#   r$   __getitem__  s   
zIndex.__getitem__c                 C   r   )z0Iterate over the paths and stages in this index.)iterr   r8   r#   r#   r$   __iter__  r   zIndex.__iter__c                 C   s
   || j v S r4   r   r   r#   r#   r$   __contains__  r   zIndex.__contains__rZ   c                 C      | | }t |trt|jS )z6Return the (git object) SHA1 for the object at a path.)ro   rS   rY   r/   r9   rZ   rF   r#   r#   r$   get_sha1     
zIndex.get_sha1c                 C   r   )z4Return the POSIX file mode for the object at a path.)ro   rS   rY   r+   r   r#   r#   r$   get_mode  r   zIndex.get_modec                 c   s:    | D ]}| | }t |trt||jt|jfV  qdS )z=Iterate over path, sha, mode tuples for use with commit_tree.N)ro   rS   rY   r/   r   r+   )r9   rZ   r   r#   r#   r$   iterobjects  s   
zIndex.iterobjectsc                 C   s$   | j  D ]
}t|tr dS qdS )NTF)r   valuesro   rS   )r9   rF   r#   r#   r$   has_conflicts  s
   
zIndex.has_conflictsc                 C   s
   i | _ dS )z$Remove all contents from this index.Nr   r8   r#   r#   r$   r   $  r   zIndex.clearr&   rF   c                 C   s   t |tsJ || j|< d S r4   )ro   r<   r   )r9   r&   rF   r#   r#   r$   __setitem__(  s   zIndex.__setitem__c                 C   s   | j |= d S r4   r   )r9   r&   r#   r#   r$   __delitem__.     zIndex.__delitem__c                 C      t | j S r4   r   r   itemsr8   r#   r#   r$   	iteritems1  rL   zIndex.iteritemsc                 C   r   r4   r   r8   r#   r#   r$   r   6  s   zIndex.itemsr   c                 C   s   |  D ]\}}|| |< qd S r4   )r   )r9   r   r   rF   r#   r#   r$   r   9  s   
zIndex.updatec                 c   s    | j  E d H  d S r4   )r   keysr8   r#   r#   r$   paths?  s   zIndex.pathsFtreewant_unchangedc                 #   s.     fdd}t   ||||dE dH  dS )a  Find the differences between the contents of this index and a tree.

        Args:
          object_store: Object store to use for retrieving tree contents
          tree: SHA1 of the root tree
          want_unchanged: Whether unchanged files should be reported
        Returns: Iterator over tuples with (oldpath, newpath), (oldmode,
            newmode), (oldsha, newsha)
        c                    s    |  }|j t|jfS r4   )r/   r   r+   )rZ   r   r8   r#   r$   lookup_entryO  s   z-Index.changes_from_tree.<locals>.lookup_entry)r   N)changes_from_treer   )r9   object_storer   r   r   r#   r8   r$   r   B  s   zIndex.changes_from_treec                 C   s   t ||  S )zCreate a new tree from an index.

        Args:
          object_store: Object store to save the tree in
        Returns:
          Root tree SHA
        commit_treer   )r9   r   r#   r#   r$   commit[     zIndex.commitrP   r   F)(r   r   r   rX   dictr<   r
   rA   rS   r=   strrW   rR   rZ   r   rr   rl   r>   r   r   r   r   rI   r   r   r   r   r@   r   r   r   r   r   r   r   r   r   r   r   r   r#   r#   r#   r$   r     sV   
 


	



"

r   r   blobsc                    s^   di i fdd |D ]\}}}t |\}} |}||f||< qfdddS )zCommit a new tree.

    Args:
      object_store: Object store to add trees to
      blobs: Iterable over blob path, sha, mode entries
    Returns:
      SHA1 of the created tree.
    r\   c                    sJ   | v r|  S t | \}} |}t|tsJ i }|||< || < |S r4   )ra   ro   r<   )rZ   r_   r`   rt   newtree)add_treetreesr#   r$   r   s  s   zcommit_tree.<locals>.add_treec                    sb   t  }|   D ]\}}t|trtj} t| |}n|\}}|||| q	| |j	S r4   )
r   r   ro   r   r   r   rg   add
add_objectid)rZ   r   r`   r   r+   r/   )
build_treer   r   r#   r$   r     s   

zcommit_tree.<locals>.build_tree)ra   )r   r   rZ   r/   r+   	tree_pathr`   r   r#   )r   r   r   r   r$   r   f  s   r   indexc                 C   s   t | | S )zCreate a new tree from an index.

    Args:
      object_store: Object store to save the tree in
      index: Index file
    Note: This function is deprecated, use index.commit() instead.
    Returns: Root tree sha.
    r   )r   r   r#   r#   r$   commit_index  s   	r   Fnamesr   r   c              	   c   s    t | }|durMt||D ]>\}}}z||\}	}
W n ty0   |df|df|dffV  Y qw || |s@|	|ks@|
|krL||f||
f||	ffV  q|D ] }z||\}	}
W n	 tyb   Y qOw d|fd|
fd|	ffV  qOdS )a  Find the differences between the contents of a tree and
    a working copy.

    Args:
      names: Iterable of names in the working copy
      lookup_entry: Function to lookup an entry in the working copy
      object_store: Object store to use for retrieving tree contents
      tree: SHA1 of the root tree, or None for an empty tree
      want_unchanged: Whether unchanged files should be reported
    Returns: Iterator over tuples with (oldpath, newpath), (oldmode, newmode),
        (oldsha, newsha)
    N)setr   KeyErrorremove)r   r   r   r   r   other_namesr&   r+   r/   	other_sha
other_moder#   r#   r$   r     s*   
r   hex_shac                 C   s>   |du r	t | j}t| j| j| j| j|| j| j| j	|dddS )zCreate a new index entry from a stat value.

    Args:
      stat_val: POSIX stat_result instance
      hex_sha: Hex sha of the object
    Nr   rC   )
r   st_moderA   st_ctimest_mtimest_devst_inost_uidst_gidst_size)stat_valr   r+   r#   r#   r$   index_entry_from_stat  s   
r  win32c                       s   e Zd Zd fddZ  ZS )WindowsSymlinkPermissionErrorr2   Nc                    s   t t| |d| | d S )Nz>Unable to create symlink; do you have developer mode enabled? )superPermissionErrorrW   )r9   errnomsgr   r   r#   r$   rW     s
   
z&WindowsSymlinkPermissionError.__init__r   )r   r   r   rW   __classcell__r#   r#   r
  r$   r    s    r  )dir_fdc             
   C   sB   z
t j| |||dW S  ty  } z
t|j|j|j|d }~ww )N)target_is_directoryr  )r   symlinkr  r  r  strerrorr   )srcdstr  r  r   r#   r#   r$   r    s   r  Tutf-8)honor_filemodetree_encoding
symlink_fnblobtarget_pathc          	      C   s   zt |}W n ty   d}Y nw |  }t|r:|r#t | tjdkr2|	|}|	|}|p5t
|| nQ|duri|jt|krit|d}| |krZ|W  d   S W d   n1 sdw   Y  t|d}|| W d   n1 s~w   Y  |rt || t |S )a  Build a file or symlink on disk based on a Git object.

    Args:
      blob: The git object
      mode: File mode
      target_path: Path to write to
      honor_filemode: An optional flag to honor core.filemode setting in
        config file, default is core.filemode=True, change executable bit
      symlink: Function to use for creating symlinks
    Returns: stat object for the file
    Nr  r   r   )r   lstatFileNotFoundErroras_raw_stringr   r   unlinksysplatformdecoder  r  r   openrl   rr   chmod)	r  r+   r  r  r  r  oldstatcontentsrm   r#   r#   r$   build_file_from_blob  s4   





r#  )   .git   .s   ..r\   elementc                 C   s   |   tvS r4   )lowerINVALID_DOTNAMES)r&  r#   r#   r$   validate_path_element_default;  r   r)  c                 C   s*   |  d }|tv rdS |dkrdS dS )Ns   . Fs   git~1T)rstripr'  r(  )r&  strippedr#   r#   r$   validate_path_element_ntfs?  s   r,  c                 C   s&   |  d}|D ]	}||s dS qdS )z2Default path validator that just checks for .git/.r[   FT)split)rZ   element_validatorpartsrc   r#   r#   r$   validate_pathH  s   
r0  	root_path
index_pathtree_idr  c                 C   s*  t |dd}t| tst| } t||D ]y}t|j|sqt| |j}	tj	tj
|	s7ttj
|	 t|jrMtj|	sGt|	 t|	}
n||j }t|tsYJ t||j|	||d}
|rjt|jr|j|
j|
j|
j|
j|
j|
j|
j|
j|
jf
}|
|}
t|
|j||j< q|  dS )a  Generate and materialize index from a tree.

    Args:
      tree_id: Tree to materialize
      root_path: Target dir for materialized index files
      index_path: Target path for generated index
      object_store: Non-empty object store holding tree contents
      honor_filemode: An optional flag to honor core.filemode setting in
        config file, default is core.filemode=True, change executable bit
      validate_path_element: Function to validate path elements to check
        out; default just refuses .git and .. directories.

    Note: existing index is wiped and contents are not merged
        in a working dir. Suitable only for fresh clones.
    F)rl   )r  r  N) r   ro   r<   r   fsencoder   r0  rZ   _tree_to_fs_pathr   r_   makedirsr   r+   isdirmkdirr  r/   r   r#  r   r   st_nlinkr   r   r  st_atimer   r   r   r  rr   )r1  r2  r   r3  r  validate_path_elementr  r   r   	full_pathstobjst_tupler#   r#   r$   build_index_from_treeR  sJ   




	
r@  fs_pathc                 C   s   t | tsJ t }t|r*tjdkr"tt	| 
||_|S t| |_|S t| d}| |_W d   |S 1 s@w   Y  |S )zCreate a blob from a path and a stat object.

    Args:
      fs_path: Full file system path to file
      mode: File mode
    Returns: A `Blob` object
    r  r   N)ro   r<   r   r   r   r  r  r   readlinkfsdecodeencodedatar  rl   )rA  r+   r  r  rm   r#   r#   r$   blob_from_path_and_mode  s   


rF  c                 C   s   t | |j|S )zCreate a blob from a path and a stat object.

    Args:
      fs_path: Full file system path to file
      st: A stat object
    Returns: A `Blob` object
    )rF  r   )rA  r=  r  r#   r#   r$   blob_from_path_and_stat  r   rG  c                 C   sn   ddl m} ddlm} t| tst| } z|| }W n
 |y&   Y dS w z| W S  t	y6   Y dS w )zRead the head commit of a submodule.

    Args:
      path: path to the submodule
    Returns: HEAD sha, None if not a valid head/repository
    r   )NotGitRepository)RepoN)
errorsrH  reporI  ro   r   r   rC  headr   )rZ   rH  rI  rK  r#   r#   r$   read_submodule_head  s   


rM  r   c                 C   s4   t jt j| drt| }|j|krdS dS dS )a  Check if a directory has changed after getting an error.

    When handling an error trying to create a blob from a path, call this
    function. It will check if the path is a directory. If it's a directory
    and a submodule, check the submodule head to see if it's has changed. If
    not, consider the file as changed as Git tracked a file and not a
    directory.

    Return true if the given path should be considered as changed and False
    otherwise or if the path is not a directory.
    r$  TF)r   rZ   r   re   rM  r/   )r   r   rL  r#   r#   r$   _has_directory_changed  s   
rN  c              	   c   s    t |tst|}|  D ][\}}t||}t |tr!|V  qz3t|}t	|j
r7t||r5|V  W qt|j
sEt|j
sEW qt||}|durS|||}W n ty`   |V  Y qw |j|jkrj|V  qdS )zWalk through an index and check for differences against working tree.

    Args:
      index: index to check
      root_path: path in which to find files
    Returns: iterator over paths with unstaged changes
    N)ro   r<   r   r4  r   r5  rS   r  r   r   r   rN  S_ISREGr   rG  r  r   r/   )r   r1  filter_blob_callbackr   r   r<  r=  r  r#   r#   r$   get_unstaged_changes  s6   








rQ  asciic                 C   s6   t |tsJ tdkr|dt}n|}tj| |S )zConvert a git tree path to a file system path.

    Args:
      root_path: Root filesystem path
      tree_path: Git tree path as bytes

    Returns: File system path.
    r[   )ro   r<   os_sep_bytesreplacer   rZ   re   )r1  r   sep_corrected_pathr#   r#   r$   r5  !  s
   	r5  c                 C   s:   t | tst| }n| }tdkr|td}|S |}|S )zConvert a file system path to a git tree path.

    Args:
      fs_path: File system path.

    Returns:  Git tree path as bytes
    r[   )ro   r<   r   r4  rS  rT  )rA  fs_path_bytesr   r#   r#   r$   _fs_to_tree_path2  s   
rW  c                 C   s<   t jt j|drt|}|d u rd S t| |tdS d S )Nr$  )r+   )r   rZ   r   re   rM  r  r   )r=  rZ   rL  r#   r#   r$   index_entry_from_directoryE  s   rX  c                 C   sr   t | tsJ t| }t|jrt|| S t|js#t	|jr7t
| |}|dur1|| t||jS dS )ag  Create an index from a filesystem path.

    This returns an index value for files, symlinks
    and tree references. for directories and
    non-existent files it returns None

    Args:
      path: Path to create an index entry for
      object_store: Optional object store to
        save new blobs in
    Returns: An index entry; None for directories
    N)ro   r<   r   r  r   r   r   rX  rO  r   rG  r   r  r   )rZ   r   r=  r  r#   r#   r$   index_entry_from_pathN  s   



rY  r   c              
   c   sP    | D ]"}t ||}zt||d}W n ttfy   d}Y nw ||fV  qdS )zIterate over current versions of index entries on disk.

    Args:
      paths: Paths to iterate over
      root_path: Root path to access from
      object_store: Optional store to save new blobs in
    Returns: Iterator over path, index_entry
    r   N)r5  rY  r  IsADirectoryError)r   r1  r   rZ   rc   r   r#   r#   r$   iter_fresh_entriesk  s   
r\  c                 c   sL    t | ||dD ]\}}|du r|r|ddfV  q||jt|jfV  qdS )a8  Iterate over versions of objects on disk referenced by index.

    Args:
      root_path: Root path to access from
      include_deleted: Include deleted entries with sha and
        mode set to None
      object_store: Optional object store to report new items to
    Returns: Iterator over path, sha, mode
    rZ  N)r\  r/   r   r+   )r   r1  include_deletedr   rZ   r   r#   r#   r$   iter_fresh_objects  s   r^  c                 C   s$   t | |D ]
\}}|r|| |< qdS )zRefresh the contents of an index.

    This is the equivalent to running 'git commit -a'.

    Args:
      index: Index to update
      root_path: Root filesystem path
    N)r\  )r   r1  rZ   r   r#   r#   r$   refresh_index  s
   	r_  c                   @   s:   e Zd ZdZdeeef ddfddZdd Zd	d
 Z	dS )locked_indexzPLock the index while making modifications.

    Works as a context manager.
    rZ   r2   Nc                 C   r   r4   )_path)r9   rZ   r#   r#   r$   rW     r   zlocked_index.__init__c                 C   s    t | jd| _t| j| _| jS )Nr   )r   ra  _filer   _indexr8   r#   r#   r$   	__enter__  s   zlocked_index.__enter__c                 C   s^   |d ur| j   d S zt| j }t|| jj W n ty(   | j   Y d S w |  d S r4   )rb  abortr   r   rc  r   BaseExceptionr   )r9   exc_type	exc_value	tracebackrm   r#   r#   r$   __exit__  s   

zlocked_index.__exit__)
r   r   r   rX   r
   r<   r   rW   rd  rj  r#   r#   r#   r$   r`    s
    r`  r   r4   r   )r  )FN)brX   r   r   rj   r  collections.abcr   r   dataclassesr   enumr   typingr   r   r   r	   r
   filer   r   r   objectsr   r   r   r   r   r   r   rs   r   r   r   r6   r7   r~   
FLAG_VALIDrN   rJ   EXTENDED_FLAG_INTEND_TO_ADDr   r   r%   rA   rS   	ExceptionrY   r<   r@   ra   rg   rn   rw   r>   r   r   r   r   r   r   listr   r   r   r   r   r   r   r  r  r  r  r  r#  r(  rI   r)  r,  r0  r   r@  rF  rG  rM  rN  rQ  seprD  rS  r5  rW  rX  rY  r\  r^  r_  r`  r#   r#   r#   r$   <module>   sR  $	I
.$
!
 #
,
5

1	


N

,

 

