
                  	          S r SSKrSSKJr  SSKJr  SSKrSSKrSSKrSSK	J
r
JrJrJr  SSKrSSKrSSKJr  SSKJrJrJrJrJrJrJr  SSKJr  S	rS
rSrSrSr Sr!Sr"Sr#Sr$Sr%Sr&Sr'Sr(Sr)Sr* " S S\5      r+S r,S r-S r.S r/S r0S r1S  r2S!\3S"\3S#\44S$ jr5SHS%\6S&\
\6   4S' jjr7S( r8S) r9S* r:S+ r;S, r< " S- S.\=5      r> " S/ S0\=5      r? " S1 S2\?5      r@S3 rA " S4 S5\?5      rB " S6 S7\" S7/ S8Q5      5      rCSIS9 jrDS: rES; rFS< rGS= rHSJS> jrI " S? S@\?5      rJSA rKSISB jrLSC rMSD rN " SE SF\?5      rO\O\J\@\B4rP0 rQ\P H!  rR\R\Q\RR                  '   \R\Q\RR                  '   M#     \DrU\FrV SSGKWJDrDJFrF  g! \X a     gf = f)KzAccess to base git objects.    N)BytesIO)
namedtuple)OptionalDictUnionType)sha1)ChecksumMismatchNotBlobErrorNotCommitErrorNotTagErrorNotTreeErrorObjectFormatExceptionFileFormatException)GitFiles(   0000000000000000000000000000000000000000   trees   parents   authors	   committers   encodings   mergetags   gpgsigs   objects   type   tags   taggeri   l    s   -----BEGIN PGP SIGNATURE-----c                       \ rS rSrSrSrg)EmptyFileExceptionN   z+An unexpectedly empty file was encountered. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       "lib/third_party/dulwich/objects.pyr   r   N   s    5r   r   c                 <    [         R                  " U 5      [        :H  $ )zXCheck if a mode indicates a submodule.

Args:
  m: Mode to check
Returns: a ``boolean``
)statS_IFMTS_IFGITLINK)ms    r   S_ISGITLINKr%   R   s     ;;q>[((r   c                 v    [         R                  " 5       nUR                  U 5      nX!R                  5       -  nU$ N)zlibdecompressobj
decompressflush)stringdcompdcompeds      r   _decompressr/   \   s3     Ev&G{{}GNr   c                 d    [         R                  " U 5      n[        U5      S:X  d
   SU-  5       eU$ )z4Takes a string and returns the hex of the sha within(   z#Incorrect length of sha1 string: %d)binasciihexlifylen)shahexshas     r   
sha_to_hexr7   c   s4    c"Fv;"LCfLLMr   c                     [        U 5      S:X  d
   SU -  5       e [        R                  " U 5      $ ! [         a3  n[	        U [
        5      (       d  e [        UR                  S   5      eSnAff = f)z(Takes a hex sha and returns a binary shar1   zIncorrect length of hexsha: %sr   N)r4   r2   	unhexlify	TypeError
isinstancebytes
ValueErrorargs)hexexcs     r   
hex_to_sharA   j   sf    s8r>A;cAA>&!!#&& &#u%%!%%&s   1 
A..A))A.c                     [        U 5      S:w  a  g [        R                  " U 5        g! [        [        R                  4 a     gf = f)Nr1   FT)r4   r2   r9   r:   Error)r?   s    r   valid_hexsharD   u   sE    
3x2~3  x~~& s   ) AAc                     [        U SS5      b  UR                  S5      nUSS nUSS n[        R                  R	                  XU5      $ )zDTakes a hex sha and returns its filename relative to the given path.encodeNascii   )getattrdecodeospathjoin)rL   r?   dirfiles       r   hex_to_filenamerP      sL    
 tXt$0jj!
bq'Cqr7D77<<4((r   c                 $   U R                  [        R                  R                  S5      SS nSU -  n[	        U5      S:X  d   U5       eUu  p4[	        U5      S:X  a  [	        U5      S:X  d   U5       eX4-   R                  S5      n[        U5        U$ )z?Takes an object filename and returns its corresponding hex sha.rH   NzInvalid object filename: %s&   rG   )rsplitrK   rL   sepr4   rF   rA   )filenamenameserrmsgbaserestr?   s         r   filename_to_hexr[      s     OOBGGKK+BC0E*X5Fu:?"F"?JDt9>c$i2o5v5-;

w
'CsOJr   num_typelengthreturnc                 n    [        U 5      R                  S-   [        U5      R                  S5      -   S-   $ )zCReturn an object header for the given numeric type and text length.    rG       )object_class	type_namestrrF   )r\   r]   s     r   object_headerre      s2    !++d2S[5G5G5PPSXXXr   name	docstringc                 0   ^  U 4S jnU 4S jn[        X2US9$ )zBA property that helps tracking whether serialization is necessary.c                 4   > [        U ST-   U5        SU l        g )N_T)setattr_needs_serialization)objvaluerf   s     r   set"serializable_property.<locals>.set   s    S4Z'#' r   c                 "   > [        U ST-   5      $ )Nrj   )rI   )rm   rf   s    r   get"serializable_property.<locals>.get   s    sC$J''r   doc)property)rf   rg   ro   rr   s   `   r   serializable_propertyrw      s    (( C),,r   c                 .    [         R                  U S5      $ )zGet the object class corresponding to the given type.

Args:
  type: Either a type name string or a numeric type.
Returns: The ShaFile subclass corresponding to the given type, or None if
    type is not a valid type name/number.
N)	_TYPE_MAPrr   )types    r   rb   rb      s     ==t$$r   c                 H    [        U 5      (       d  [        U< SU < 35      eg)zCheck if a string is a valid hex sha string.

Args:
  hex: Hex string to check
  error_msg: Error message to use in exception
Raises:
  ObjectFormatException: Raised when the string is not valid
 N)rD   r   )r?   	error_msgs     r   check_hexshar~      s$     #y#$>?? r   c                    U R                  S5      nU R                  S5      nUS:  dS  US:  dM  X2::  dH  U R                  SUS-   5      S:  d/  U R                  SUS-   5      S:  d  U R                  S5      (       d  [        U5      eg)zCheck if the specified identity is valid.

This will raise an exception if the identity is not valid.

Args:
  identity: Identity string
  error_msg: Error message to use in exception
   <   >r      N)findendswithr   )identityr}   email_start	email_ends       r   check_identityr      s     --%Kd#Iaq=#=={Q/14==y1}-2  &&#I.. 'r   c                 <    U [         :  a  [        S[         -  5      eg)zCheck if the specified time is not prone to overflow error.

This will raise an exception if the time is not valid.

Args:
  time_info: author/committer/tagger info

zDate field should not exceed %sN)MAX_TIMEr   )time_secondss    r   
check_timer      s"     h#$E$PQQ r   c                  *    SR                  U 5      S-   $ )z*Formats items into a space separated line.r`      
)rM   )itemss    r   git_liner      s    99Ue##r   c                   .    \ rS rSrSrSrS rS rS rSr	g)FixedSha   zBSHA object that behaves like hashlib's but is given a fixed value.)_hexsha_shac                     [        USS 5      b  UR                  S5      n[        U[        5      (       d  [	        SU-  5      eXl        [        U5      U l        g )NrF   rG   z!Expected bytes for hexsha, got %r)rI   rF   r;   r<   r:   r   rA   r   )selfr6   s     r   __init__FixedSha.__init__   sN    68T*6]]7+F&%((?&HIIv&	r   c                     U R                   $ )zReturn the raw SHA digest.)r   r   s    r   digestFixedSha.digest   s    yyr   c                 8    U R                   R                  S5      $ )zReturn the hex SHA digest.rG   )r   rJ   r   s    r   	hexdigestFixedSha.hexdigest   s    ||""7++r   N)
r   r   r   r   r   	__slots__r   r   r   r   r   r   r   r   r      s    L#I',r   r   c                      \ rS rSrSrSrSrSr\S 5       r	S r
S,S jrS,S jrS	 rS
 rS rS rS rS-S jrS-S jr\S 5       rS r\S 5       r\S 5       rS rS rS r\S 5       r\S 5       r\S-S j5       r\S-S j5       r\S 5       r S r!S r"S r#S r$S  r%S! r&\'S" 5       r(S# r)S$ r*\'" \)\*5      r+S% r,S& r-S' r.S( r/S) r0S* r1S+r2g).ShaFilei  zA git SHA file.)_chunked_textr   rl   Nc                    Sn[         R                  " 5       nUR                  U 5      nSnSnUS:  aM  UR                  U5      nXCR                  U5      -  nX-  n UR	                  SU5      n[        U5      nUS:  a  MM  USU nUR                  SS5      u  p [        U	5        [        U5      nU(       d  [        S	U-  5      eU" 5       $ ! [         a  n
[        SU
-  5      eSn
A
ff = f)
z<Parse a legacy object, creating it but not reading the file.i   r   ra   Nr`   r   zObject size not an integer: %sNot a known type: %s)r(   r)   r*   readr   r4   splitintr=   r   rb   )magicfbufsizedecompheaderstartendextrarc   sizee	obj_classs               r   _parse_legacy_object_header#ShaFile._parse_legacy_object_header  s     ##%""5)AgFF7OE''..FNE++eU+CKE Ag  ,,tQ/		NI !+	'(>(JKK{  	N'(H1(LMM	Ns   C 
C)C$$C)c                     [        U5      nUR                  S5      nUS:  a  [        S5      eU R                  X#S-   S 5        g)z.Parse a legacy object, setting the raw string.ra   r   zInvalid object header, no \0r   N)r/   r   r   set_raw_string)r   maptext
header_ends       r   _parse_legacy_objectShaFile._parse_legacy_object$  sE    3YYu%
>'(GHHDa!123r   c              #      #    [         R                  " U5      nUR                  U R                  5       5      v   U R	                  5        H  nUR                  U5      v   M     UR                  5       v   g7f)z\Return chunks representing the object in the experimental format.

Returns: List of strings
N)r(   compressobjcompress_headeras_raw_chunksr+   )r   compression_levelcompobjchunks       r   as_legacy_object_chunksShaFile.as_legacy_object_chunks,  s_     
 ""#45t||~..'')E""5)) *mmos   A5A7c                 >    SR                  U R                  US95      $ )zAReturn string representing the object in the experimental format.r   )r   )rM   r   )r   r   s     r   as_legacy_objectShaFile.as_legacy_object7  s%    xx((;L(M
 	
r   c                     U R                   (       a#  SU l        U R                  5       U l        SU l         U R                  $ )zhReturn chunks with serialization of the object.

Returns: List of strings, not necessarily one per line
NF)rl   r   
_serializer   r   s    r   r   ShaFile.as_raw_chunks=  s7    
 $$DI!%!2D(-D%!!!r   c                 @    SR                  U R                  5       5      $ )zLReturn raw string with serialization of the object.

Returns: String object
r   )rM   r   r   s    r   as_raw_stringShaFile.as_raw_stringH  s    
 xx**,--r   c                 "    U R                  5       $ )z/Return raw string serialization of this object.r   r   s    r   	__bytes__ShaFile.__bytes__O      !!##r   c                 ,    [        U R                  5      $ )z#Return unique hash for this object.)hashidr   s    r   __hash__ShaFile.__hash__S  s    DGG}r   c                 "    U R                  5       $ )z:Return a string representing this object, fit for display.r   r   s    r   as_pretty_stringShaFile.as_pretty_stringW  r   r   c                 p    [        U[        5      (       d  [        SU-  5      eU R                  U/U5        g)z9Set the contents of this object from a serialized string.zExpected bytes for text, got %rN)r;   r<   r:   set_raw_chunks)r   r   r5   s      r   r   ShaFile.set_raw_string[  s2    $&&=DEETFC(r   c                 v    Xl         U R                  U5        Uc  SU l        O[        U5      U l        SU l        g)z6Set the contents of this object from a list of chunks.NF)r   _deserializer   r   rl   )r   chunksr5   s      r   r   ShaFile.set_raw_chunksa  s5    #&!;DI DI$)!r   c                 x    [        U SS 5      S-	  S-  n[        U5      nU(       d  [        SU-  5      eU" 5       $ )z?Parse a new style object, creating it but not reading the file.r   r         zNot a known type %d)ordrb   r   )r   r   r\   r   s       r   _parse_object_headerShaFile._parse_object_headerk  sC     a
Oq(A- *	'(=(HII{r   c                     [        USS 5      nSnUS-  S:w  a   [        XUS-    5      nUS-  nUS-  S:w  a  M   XS nU R                  [        U5      5        g)z-Parse a new style object, setting self._text.r   r      N)r   r   r/   )r   r   byteusedraws        r   _parse_objectShaFile._parse_objectt  sl     3q8}d{q s$(+,DAID d{q  %jK,-r   c                 x    [        USS 5      n[        USS 5      nUS-  U-   nUS-  S:H  =(       a    US-  S:H  $ )Nr   r   rH            )r   )clsr   b0b1words        r   _is_legacy_objectShaFile._is_legacy_object  sJ    q_q_a2~T	d"7r	a'77r   c                    UR                  5       nU(       d  [        S5      eU R                  U5      (       a$  U R                  X!5      nUR	                  U5        U$ U R                  X!5      nUR                  U5        U$ )NzCorrupted empty file detected)r   r   r   r   r   r   r   )r   r   r   rm   s       r   _parse_fileShaFile._parse_file  sw    ffh$%DEE  %%11#9C$$S) 
 **32Cc"
r   c                 .    SU l         / U l        SU l        g)zDon't call this directlyNT)r   r   rl   r   s    r   r   ShaFile.__init__  s    	$(!r   c                 ,    [        U R                  5      er'   )NotImplementedErrorr   r   r   s     r   r   ShaFile._deserialize  s    !$"3"344r   c                 ,    [        U R                  5      er'   )r  r   r   s    r   r   ShaFile._serialize  s    !$//22r   c                 r    [        US5       nU R                  U5      sSSS5        $ ! , (       d  f       g= f)zOpen a SHA file from disk.rbN)r   	from_file)r   rL   r   s      r   	from_pathShaFile.from_path  s(     T4 A==# !  s   (
6c                 v     U R                  U5      nSUl        U$ ! [        [        4 a    [	        S5      ef = f)z'Get the contents of a SHA file on disk.Nzinvalid object header)r   r   
IndexErrorr=   r   )r   r   rm   s      r   r
  ShaFile.from_file  sD    	A//!$CCHJJ' 	A'(?@@	As    8c                 H    [        U 5      " 5       nUR                  X5        U$ )zCreates an object of the indicated type from the raw string given.

Args:
  type_num: The numeric type of the object.
  string: The raw uncompressed contents.
  sha: Optional known sha for the object
)rb   r   )type_numr,   r5   rm   s       r   from_raw_stringShaFile.from_raw_string  $     8$&6'
r   c                 H    [        U 5      " 5       nUR                  X5        U$ )zCreates an object of the indicated type from the raw chunks given.

Args:
  type_num: The numeric type of the object.
  chunks: An iterable of the raw uncompressed contents.
  sha: Optional known sha for the object
)rb   r   )r  r   r5   rm   s       r   from_raw_chunksShaFile.from_raw_chunks  r  r   c                 6    U " 5       nUR                  U5        U$ )zCreate a ShaFile from a string.r   )r   r,   rm   s      r   from_stringShaFile.from_string  s     e6"
r   c                 4    [        XS5      c  [        U5      eg)a  Check that the object has a given member variable.

Args:
  member: the member variable to check for
  error_msg: the message for an error if the member is missing
Raises:
  ObjectFormatException: with the given error_msg if member is
    missing or is None
N)rI   r   )r   memberr}   s      r   _check_has_memberShaFile._check_has_member  s!     4&.'	22 /r   c                     U R                   n U R                  U R                  5       5        SU l        U R                   nX:w  a  [        X!5      eg! [         a  n[        U5      eSnAff = f)zCheck this object for internal consistency.

Raises:
  ObjectFormatException: if the object is malformed in some way
  ChecksumMismatch: if the object was created with a SHA that does
    not match its contents
N)r   r   r   r   	Exceptionr   r
   )r   old_shanew_shar   s       r   checkShaFile.check  sn     ''	+d0023DIggG "744   	+'**	+s   2A 
A+A&&A+c                 J    [        U R                  U R                  5       5      $ r'   )re   rz   
raw_lengthr   s    r   r   ShaFile._header  s    TYY(9::r   c                 T    SnU R                  5        H  nU[        U5      -  nM     U$ )z4Returns the length of the raw string of this object.r   )r   r4   )r   retr   s      r   r'  ShaFile.raw_length  s-    '')E3u:C *
r   c                    U R                   b  U R                  (       aW  [        5       nUR                  U R	                  5       5        U R                  5        H  nUR                  U5        M     Xl         U R                   $ )z0The SHA1 object that is the name of this object.)r   rl   r	   updater   r   )r   r#  r   s      r   r5   ShaFile.sha  s[    99 9 9fGNN4<<>*++-u% .Iyyr   c                     [        U R                  5       5      nUR                  U R                  5       U R                  5       U R                  5      $ )z9Create a new copy of this SHA1 object from its raw string)rb   get_typer  r   r   )r   r   s     r   copyShaFile.copy
  s=     1	(($:L:L:NPTPWPWXXr   c                 \    U R                  5       R                  5       R                  S5      $ )zThe hex SHA of this object.rG   )r5   r   rF   r   s    r   r   
ShaFile.id  s$     xxz##%,,W55r   c                     U R                   $ )z-Return the type number for this object class.r  r   s    r   r0  ShaFile.get_type      }}r   c                     Xl         g)z*Set the type number for this object class.Nr6  )r   rz   s     r   set_typeShaFile.set_type  s    r   c                 T    SU R                   R                  < SU R                  < S3$ )N<r|   >)	__class__r   r   r   s    r   __repr__ShaFile.__repr__  s     NN33TWW==r   c                 l    [        U[        5      (       + =(       d    U R                  UR                  :g  $ )z3Check whether this object does not match the other.r;   r   r   r   others     r   __ne__ShaFile.__ne__"  s$    eW--DEHH1DDr   c                 b    [        U[        5      =(       a    U R                  UR                  :H  $ )z1Return True if the SHAs of the two objects match.rC  rD  s     r   __eq__ShaFile.__eq__&  s!    %)Adgg.AAr   c                 j    [        U[        5      (       d  [        eU R                  UR                  :  $ )z9Return whether SHA of this object is less than the other.r;   r   r:   r   rD  s     r   __lt__ShaFile.__lt__*  s'    %))Oww!!r   c                 j    [        U[        5      (       d  [        eU R                  UR                  :*  $ )zDCheck whether SHA of this object is less than or equal to the other.rL  rD  s     r   __le__ShaFile.__le__0  s'    %))Oww%((""r   c                 x    [        U[        5      (       d  [        e[        U R                  UR                  5      $ )z=Compare the SHA of this object with that of the other object.)r;   r   r:   cmpr   rD  s     r   __cmp__ShaFile.__cmp__6  s)    %))O477EHH%%r   )r   rl   r   r  )r   r'   )3r   r   r   r   r   r   rc   r  staticmethodr   r   r   r   r   r   r   r   r   r   r   r   r   classmethodr   r   r   r   r   r  r
  r  r  r  r  r$  r   r'  r5   r1  rv   r   r0  r:  rz   r@  rF  rI  rM  rP  rT  r   r   r   r   r   r     sy   AIIH 04	
	".$$)*  
. 8 8  )53 $ $
 A A 
 
 
 
  35,;	Y
 6 6
 Hh'D>EB"#&r   r   c                      ^  \ rS rSrSrSrSrSrU 4S jrS r	S r
\" \	\
S	S
9rS rS rS rS r\" \\SS
9r\S 5       rU 4S jrS rSrU =r$ )Blobi=  zA Git Blob object.r   s   blob   c                 F   > [         [        U ]  5         / U l        SU l        g NF)superrY  r   r   rl   r   r?  s    r   r   Blob.__init__E  s     dD"$$)!r   c                 "    U R                  5       $ r'   r   r   s    r   	_get_dataBlob._get_dataJ  s    !!##r   c                 &    U R                  U5        g r'   r  )r   datas     r   	_set_dataBlob._set_dataM  s    D!r   z*The text contained within the blob object.rt   c                     U R                   $ r'   r   r   s    r   _get_chunkedBlob._get_chunkedT      !!!r   c                     Xl         g r'   rh  r  s     r   _set_chunkedBlob._set_chunkedW      #r   c                     U R                   $ r'   rh  r   s    r   r   Blob._serializeZ  rk  r   c                     Xl         g r'   rh  r  s     r   r   Blob._deserialize]  ro  r   z>The text in the blob object, as chunks (not necessarily lines)c                 f    [         R                  U5      n[        X 5      (       d  [        U5      eU$ r'   )r   r  r;   r   )r   rL   blobs      r   r  Blob.from_pathf  s-      &$$$t$$r   c                 *   > [         [        U ]  5         g)uCheck this object for internal consistency.

Raises:
  ObjectFormatException: if the object is malformed in some way
N)r]  rY  r$  r^  s    r   r$  
Blob.checkm  s     	dD!r   c                    U R                   nU(       d  / $ [        U5      S:X  a  US   R                  S5      $ Sn/ nU H  nUR                  S5      n[        U5      S:  a;  UR                  U=(       d    SUS   -   5        UR	                  USS 5        US   nM^  [        U5      S:X  d  Mo  Uc  UR                  5       nM  X%R                  5       -  nM     Ub  UR                  U5        U$ )zNReturn list of lines in this blob.

This preserves the original line endings.
r   r   TNr   r   )chunkedr4   
splitlinesappendextendpop)r   r   	remainingr*  r   liness         r   r|  Blob.splitlinesu  s    
 Iv;!!9''--	E$$T*E5zA~

I,a89

52;'!"I	Uq$ %		I,I   JJy!
r   )r   rl   )r   r   r   r   r   r   rc   r  r   ra  re  rv   rd  ri  rm  r   r   r{  rW  r  r$  r|  r   __classcell__r?  s   @r   rY  rY  =  s    IIH*
$" 9"ND"$"$ LG  " r   rY  c              #   t  #    [        SR                  U 5      5      nSnSnSnS nU HL  nUR                  S5      (       a	  X6SS -  nM"  Ub  X%" U5      4v   US:X  a    O,UR                  SS5      u  p#MN     S	nUb  X%" U5      4v   S
v   U(       d  SUR	                  5       4v   UR                  5         g7f)a9  Parse a message with a list of fields and a body.

Args:
  chunks: the raw chunks of the tag or commit object.
Returns: iterator of tuples of (field, value), one per header line, in the
    order read from the text, possibly including duplicates. Includes a
    field named None for the freeform tag/commit text.
r   N Fc                 J    U (       a  U R                  S5      (       a  U SS $ U $ )z!Strip the last newline from valuer   Nr   )r   )rn   s    r   _strip_last_newline+_parse_message.<locals>._strip_last_newline  s$    U^^E**":r   r`   r   r   TNN)r   rM   
startswithr   r   close)r   r   kveofr  lines          r   _parse_messager    s      	 !AA
A
C ??4  abMA}-a011u}ZZa(FQ " =)!,-- QVVXGGIs   B6B8c                      ^  \ rS rSrSrSrSrSrU 4S jr\	S 5       r
U 4S jrS	 rS
 rS rS r\" \\5      r\" SS5      r\" SS5      r\" SS5      r\" SS5      r\" SS5      r\" SS5      rSrU =r$ )Tagi  zA Git Tag object.r   r   )	_tag_timezone_neg_utc_name_object_sha_object_class	_tag_time_tag_timezone_tagger_message
_signaturec                 p   > [         [        U ]  5         S U l        S U l        S U l        SU l        S U l        g r\  )r]  r  r   r  r  r  r  r  r^  s    r   r   Tag.__init__  s5    c4!#!%*"r   c                 f    [         R                  U5      n[        X 5      (       d  [        U5      eU$ r'   )r   r  r;   r   )r   rV   tags      r   r  Tag.from_path  s-    )###h''
r   c                   > [         [        U ]  5         U R                  SS5        U R                  SS5        U R                  SS5        U R                  (       d  [        S5      e[        U R                  S5        [        U S	S
5      (       a  [        U R                  S5        U R                  SS5        [        U R                  5        S
n[        U R                  5       H|  u  p#U[        :X  a  Ub  [        S5      eU[         :X  a  U[        :w  a  [        S5      eU["        :X  a  U[         :w  a  [        S5      eU[$        :X  a  U["        :w  a  [        S5      eUnM~     g
)rx  r  zmissing object shar  zmissing object typer  zmissing tag namezempty tag namezinvalid object shar  Nzinvalid taggerr  zmissing tag timezunexpected objectzunexpected typezunexpected tag namezunexpected tagger)r]  r  r$  r  r  r   r~   r  rI   r   r  r   r  r  r   _OBJECT_HEADER_TYPE_HEADER_TAG_HEADER_TAGGER_HEADER)r   lastfieldrj   r?  s       r   r$  	Tag.check  s/    	c4 }.BC0EFw(:;zz'(899T%%';<4D))4<<)9:{,>?4>>"&t'9'9:HE&4+;+,?@@,&4>+A+,=>>+%$,*>+,ABB.(T[-@+,?@@D ;r   c                 <   / nUR                  [        [        U R                  5      5        UR                  [        [        U R
                  R                  5      5        UR                  [        [        U R                  5      5        U R                  (       a  U R                  c*  UR                  [        [        U R                  5      5        OkUR                  [        [        U R                  [        U R                  5      R                  S5      [        U R                  U R                   5      5      5        U R"                  b,  UR                  S5        UR                  U R"                  5        U R$                  b  UR                  U R$                  5        U$ )NrG   r   )r}  r   r  r  r  r  rc   r  r  r  r  r  rd   rF   format_timezoner  r  r  r  r  s     r   r   Tag._serialize
  s   h~t/?/?@Ah|T-?-?-I-IJKh{DJJ78<<~~%h~t||DE&DNN+227;'(:(:D<V<VW	 ==$MM% MM$--(??&MM$//*r   c                 J   SU l         SU l        SU l        SU l        [	        U5       H  u  p#U[
        :X  a  X0l        M  U[        :X  a(  [        U5      nU(       d  [        SU-  5      eX@l
        MI  U[        :X  a  X0l        M[  U[        :X  a(  [        U5      u  U l         U l        u  U l        U l        M  Uc>  Uc  SU l        SU l        M   UR#                  [$        5      nUSU U l        X5S U l        M  [        SU-  5      e   g! [&         a    X0l        SU l         M  f = f)z%Grab the metadata attached to the tagNFr   zUnknown field %s)r  r  r  r  r  r  r  r  rb   r   r  r  r  r  parse_time_entryr  r  indexBEGIN_PGP_SIGNATUREr=   )r   r   r  rn   r   sig_idxs         r   r   Tag._deserialize"  s   !%*"*62LE&#( ,&(/	 /0F0NOO%."+%"
.(
 %U+	LNDT')C=$(DM&*DO:"'++.A"B
 ).hw*//+,>,FGG= 3. & /(-*./s   DD"!D"c                 2    U R                   U R                  4$ )zOGet the object pointed to by this tag.

Returns: tuple of (object class, sha).
)r  r  r   s    r   _get_objectTag._get_objectH  s    
 ""D$4$455r   c                 0    Uu  U l         U l        SU l        g NT)r  r  rl   r   rn   s     r   _set_objectTag._set_objectO  s    16.	T-$(!r   rf   zThe name of this tagtaggerz3Returns the name of the person who created this tagtag_timezLThe creation timestamp of the tag.  As the number of seconds since the epochtag_timezonez!The timezone that tag_time is in.messagez the message attached to this tag	signaturezOptional detached GPG signature)
r  r  rl   r  r  r  r  r  r  r  )r   r   r   r   r   rc   r  r   r   rW  r  r$  r   r   r  r  rv   objectrw   rf   r  r  r  r  r  r   r  r  s   @r   r  r    s    IH
I   D0$HL6) k;/F )?@D"GF %	H
 );L $I/QRG%k3TUIr   r  c                       \ rS rSrSrS rSrg)	TreeEntryif  z.Named tuple encapsulating a single tree entry.c                     [        U R                  [        5      (       d  [        SU-  5      e[	        [
        R                  " XR                  5      U R                  U R                  5      $ )z:Return a copy of this entry with the given path prepended.zExpected bytes for path, got %r)	r;   rL   r<   r:   r  	posixpathrM   moder5   )r   rL   s     r   in_pathTreeEntry.in_pathi  sH    $))U++=DEEii8$))TXXNNr   r   N)r   r   r   r   r   r  r   r   r   r   r  r  f  s    8Or   r  )rL   r  r5   c              #     #    Sn[        U 5      nX#:  a  U R                  SU5      nXU nU(       a$  UR                  S5      (       a  [        SU-  5      e [	        US5      nU R                  SU5      nXS-   U nUS-   nXS-   U n	[        U	5      S	:w  a  [        S
5      e[        U	5      n
XU
4v   X#:  a  M  gg! [
         a    [        SU-  5      ef = f7f)zParse a tree text.

Args:
  text: Serialized text to parse
Returns: iterator of tuples of (name, mode, sha)
Raises:
  ObjectFormatException: if the object was malformed in some way
r   r`      0zInvalid mode '%s'r   ra   r         zSha has invalid lengthN)r4   r  r  r   r   r=   r7   )r   strictcountr]   mode_end	mode_textr  name_endrf   r5   r6   s              r   
parse_treer  p  s      EYF
.::dE*x(	i**400'(;i(GHH	Iy!$D ::eX.qL8,2a<%(s8r>'(@AAC6""! .  	I'(;i(GHH	Is%   ACB< #AC:C<CCc              #   z   #    U  H1  u  pnSU-  R                  S5      S-   U-   S-   [        U5      -   v   M3     g7f)zSerialize the items in a tree to a text.

Args:
  items: Sorted iterable over (name, mode, sha) tuples
Returns: Serialized tree text as chunks
z%04orG   r`   ra   N)rF   rA   )r   rf   r  r6   s       r   serialize_treer    sF      $Fd]""7+d2T9EAJvDVV	
 $s   9;c              #     #    U=(       a    [         =(       d    [        n[        U R                  5       US9 HE  u  p4Uu  pV[	        U5      n[        U[        5      (       d  [        SU-  5      e[        X5U5      v   MG     g7f)a<  Iterate over a tree entries dictionary.

Args:
  name_order: If True, iterate entries in order of their name. If
    False, iterate entries in tree order, that is, treat subtree entries as
    having '/' appended.
  entries: Dictionary mapping names to (mode, sha) tuples
Returns: Iterator over (name, mode, hexsha)
)keyzExpected bytes for SHA, got %rN)	key_entry_name_order	key_entrysortedr   r   r;   r<   r:   r  )entries
name_orderkey_funcrf   entryr  r6   s          r   sorted_tree_itemsr    sk      22?iHgmmo8<4y&%((<vEFFF++ =s   A?Bc                 T    U u  p[         R                  " US   5      (       a  US-  nU$ )z>Sort key for tree entry.

Args:
  entry: (name, value) tuplee
r      /)r!   S_ISDIR)r  rf   rn   s      r   r  r    s,     MT||E!HKr   c                     U S   $ )z&Sort key for tree entry in name order.r   r   )r  s    r   r  r    s    8Or   c                     U[         R                  -  (       a  SnOSnSUUUR                  S5      U R                  US5      4-  $ )zPretty format tree entry.

Args:
  name: Name of the directory entry
  mode: Mode of entry
  hexsha: Hexsha of the referenced object
Returns: string describing the tree entry
treeru  z%04o %s %s	%s
rG   replace)r!   S_IFDIRrJ   )rf   r  r6   encodingkinds        r   pretty_format_tree_entryr    sL     dllgHi(	!  r   c                      ^  \ rS rSrSrSrSrSrU 4S jr\	S 5       r
S rS	 rS
 rS rS rS rS rSS jrS rS rU 4S jrS rS rS rSrU =r$ )Treei  zA Git tree objectr   rH   _entriesc                 8   > [         [        U ]  5         0 U l        g r'   )r]  r  r   r  r^  s    r   r   Tree.__init__  s    dD"$r   c                 f    [         R                  U5      n[        X 5      (       d  [        U5      eU$ r'   )r   r  r;   r   )r   rV   r  s      r   r  Tree.from_path  s-      *$$$x((r   c                     XR                   ;   $ r'   r  r   rf   s     r   __contains__Tree.__contains__  s    }}$$r   c                      U R                   U   $ r'   r  r  s     r   __getitem__Tree.__getitem__  s    }}T""r   c                 :    Uu  p4X44U R                   U'   SU l        g)zSet a tree entry by name.

Args:
  name: The name of the entry, as a string.
  value: A tuple of (mode, hexsha), where mode is the mode of the
    entry as an integral type and hexsha is the hex SHA of the entry as
    a string.
TNr  rl   )r   rf   rn   r  r6   s        r   __setitem__Tree.__setitem__  s#     #nd$(!r   c                 ,    U R                   U	 SU l        g r  r  r  s     r   __delitem__Tree.__delitem__  s    MM$$(!r   c                 ,    [        U R                  5      $ r'   )r4   r  r   s    r   __len__Tree.__len__  s    4==!!r   c                 ,    [        U R                  5      $ r'   )iterr  r   s    r   __iter__Tree.__iter__  s    DMM""r   c                     [        U[        5      (       a1  [        U[        5      (       a  X!p![        R                  " S[
        SS9  X#4U R                  U'   SU l        g)zAdd an entry to the tree.

Args:
  mode: The mode of the entry as an integral type. Not all
    possible modes are supported by git; see check() for details.
  name: The name of the entry, as a string.
  hexsha: The hex SHA of the entry as a string.
z'Please use Tree.add(name, mode, hexsha)rH   )category
stacklevelTN)r;   r   r<   warningswarnDeprecationWarningr  rl   )r   rf   r  r6   s       r   addTree.add  sQ     dC  Ze%<%< 4MM9+
 #ld$(!r   c                 .    [        U R                  U5      $ )zIterate over entries.

Args:
  name_order: If True, iterate in name order instead of tree
    order.
Returns: Iterator over (name, mode, sha) tuples
)r  r  )r   r  s     r   	iteritemsTree.iteritems  s     !
;;r   c                 4    [        U R                  5       5      $ )zUReturn the sorted entries in this tree.

Returns: List with (name, mode, sha) tuples
)listr  r   s    r   r   
Tree.items"  s    
 DNN$%%r   c           
           [        SR                  U5      5      n[	        U VVVs/ s H
  u  pEodXV44PM     snnn5      U l        g! [         a  n[        U5      eSnAff = fs  snnnf )zGrab the entries in the treer   N)r  rM   r=   r   dictr  )r   r   parsed_entriesr   nr$   ss          r   r   Tree._deserialize)  sa    	+'(89N HgaA1&kHI  	+'**	+
 Is   A A$
A!AA!c                 h  > [         [        U ]  5         Sn[        R                  S-  [        R                  S-  [        R
                  [        R                  [        [        R                  S-  4n[        SR                  U R                  5      S5       H  u  p4n[        USU-  5        SU;   d  US	;   a  [        S
UR                  SS5      -  5      eXB;  a  [        SU-  5      eX4U44nU(       a9  [        U5      [        U5      :  a  [        S5      eX1S   :X  a  [        SU-  5      eUnM     g)rx  Ni  i  i  r   Tzinvalid sha %sr  )r      .s   ..s   .gitzinvalid name %sutf-8r  zinvalid mode %06ozentries not sortedr   zduplicate entry %s)r]  r  r$  r!   S_IFREGS_IFLNKr  r#   r  rM   r   r~   r   rJ   r  )r   r  allowed_modesrf   r  r5   r  r?  s          r   r$  
Tree.check4  s    	dD!LL5 LL5 LLLLLL5 
  *#((43E3E*FMOD.45t|t'BB+%GY(GG  (+,?$,FGG#;'ET?Yu%55/0DEE7?/0Dt0KLLD!  Nr   c                 F    [        [        U R                  5       5      5      $ r'   )r  r  r  r   s    r   r   Tree._serializeW  s    N4>>#3455r   c                     / nU R                  5        H!  u  p#nUR                  [        X#U5      5        M#     SR                  U5      $ )Nr  )r  r}  r  rM   )r   r   rf   r  r6   s        r   r   Tree.as_pretty_stringZ  s?    "&.."2DKK0VDE #3wwt}r   c                     UR                  S5      nU R                  nSnU H:  nU(       d  M  U" U5      n[        U[        5      (       d  [	        U5      eXv   u  pTM<     XT4$ )zLook up an object in a Git tree.

Args:
  lookup_obj: Callback for retrieving object by SHA1
  path: Path to lookup
Returns: A tuple of (mode, SHA) of the resulting path.
r  N)r   r   r;   r  r   )r   
lookup_objrL   partsr5   r  prm   s           r   lookup_pathTree.lookup_path`  sf     

4 ggAS/Cc4(("3''ID#  yr   r  F)r   r   r   r   r   rc   r  r   r   rW  r  r  r  r  r  r   r  r  r  r   r   r$  r   r   r)  r   r  r  s   @r   r  r    s{    IHI  %#))"#)&<&	J!F6 r   r  c                 "   U S   S;  a  [        S[        5       -  5      eU SS n[        U SS 5      nUS:X  a  U* nUS:  =(       a    US:H  nUS:  =(       a    S=(       d    Sn[        U5      n[        US-  5      nUS-  nXES	-  US
-  -   -  U4$ )zParse a timezone text fragment (e.g. '+0100').

Args:
  text: Text to parse.
Returns: Tuple with timezone as seconds difference to UTC
    and a boolean indicating whether this was a UTC timezone
    prefixed with a negative sign (-0000).
r   s   +-z*Timezone must start with + or - (%(text)s)Nr      -r   d     <   )r=   varsr   abs)r   signoffsetunnecessary_negative_timezonesignumhoursminutess          r   parse_timezoner9  u  s     7eENOO8Dab]Ft|$*aK$@DDL!qj b%AF[FEslG$,2-.% r   c                     U S-  S:w  a  [        S5      eU S:  d  U(       a  SnU * n OSnSX S-  U S-  S-  4-  R                  S5      $ )	zFormat a timezone for Git serialization.

Args:
  offset: Timezone offset as seconds difference to UTC
  unnecessary_negative_timezone: Whether to use a minus sign for
    UTC or positive timezones (-0000 and --700 rather than +0000 / +0700).
r0  r   z#Unable to handle non-minute offset.-+z
%c%02d%02dr/  rG   )r=   rF   )r4  r5  r3  s      r   r  r    s_     {a>??z2D4-&2+1CDDLLWUUr   c                     U R                  S5      n U SUS-    nXS-   S nUR                  SS5      u  pE[        U5      n[	        U5      u  pxX&Xx44$ ! [         a    U SS4s $ f = f! [         a  n	[        U	5      eSn	A	ff = f)zParse time entry behavior

Args:
  value: Bytes representing a git commit/tag line
Raises:
  ObjectFormatException in case of parsing error (malformed
  field date)
Returns: Tuple of (author, time, (timezone, timezone_neg_utc))
s   > Nr\  r   r   rH   r`   )rindexr=   rT   r   r9  r   )
rn   rU   personrZ   timetexttimezonetexttimetimezonetimezone_neg_utcr   s
             r   r  r    s    ,ll5!'q37#1WY!%T1!58}%3L%A" (555  ,t]++,  '#A&&'s(   A ;A) A&%A&)
B3A>>Bc           	         / n/ nSnSnSnSn/ nSnSn	[        U 5       H  u  pU
[        :X  a  UnM  U
[        :X  a  UR                  U5        M0  U
[        :X  a  [        U5      nMG  U
[        :X  a  [        U5      nM^  U
[        :X  a  UnMl  U
[        :X  a)  UR                  [        R                  US-   5      5        M  U
[        :X  a  Un	M  U
c  UnM  UR                  X45        M     UUUUUUU	UU4	$ )zParse a commit object from chunks.

Args:
  chunks: Chunks to parse
Returns: Tuple of (tree, parents, author_info, commit_info,
    encoding, mergetag, gpgsig, message, extra)
N)NNr  r   )r  _TREE_HEADER_PARENT_HEADERr}  _AUTHOR_HEADERr  _COMMITTER_HEADER_ENCODING_HEADER_MERGETAG_HEADERr  r  _GPGSIG_HEADER)r   parentsr   r  author_infocommit_infor  mergetagr  gpgsigr  rn   s               r   parse_commitrR    s    GED,K,KHHGF&v.L Dn$NN5!n$*51K''*51K&&H&&OOCOOEEM:;n$F]GLL%(' /* 	
 
r   c                   V  ^  \ rS rSrSrSrSrSrU 4S jr\	S 5       r
S rU 4S	 jrS
 r\" SS5      rS rS r\" \\SS9rS r\" \SS9r\" SS5      r\" SS5      r\" SS5      r\" SS5      r\" SS5      r\" SS5      r\" SS 5      r\" S!S"5      r\" S#S$5      r\" S%S&5      rS'r U =r!$ )(Commiti  zA git commit objects   commitr   )_parents	_encoding_extra_author_timezone_neg_utc_commit_timezone_neg_utc_commit_time_author_time_author_timezone_commit_timezone_author
_committer_treer  	_mergetag_gpgsigc                    > [         [        U ]  5         / U l        S U l        / U l        S U l        / U l        SU l        SU l	        g r\  )
r]  rT  r   rU  rV  ra  rb  rW  rX  rY  r^  s    r   r   Commit.__init__  sC    fd$&(-%(-%r   c                 f    [         R                  U5      n[        X 5      (       d  [        U5      eU$ r'   )r   r  r;   r   )r   rL   commits      r   r  Commit.from_path  s-    ""4(&&& &&r   c           
          [        U5      u	  U l        U l        nnU l        U l        U l        U l        U l        Uu  U l        U l	        u  U l
        U l        Uu  U l        U l        u  U l        U l        g r'   )rR  r`  rU  rV  ra  rb  r  rW  r^  r[  r\  rX  r_  rZ  r]  rY  )r   r   rN  rO  s       r   r   Commit._deserialize  s~      
	
JMNNLMK 		
LBT"D$A 		
OBT"D$Ar   c                 x  > [         [        U ]  5         U R                  SS5        U R                  SS5        U R                  SS5        U R                  SS5        U R                  S	S
5        U R                   H  n[        US5        M     [        U R                  S5        [        U R                  S5        [        U R                  S5        [        U R                  5        [        U R                  5        Sn[        U R                  5       H  u  p4U[        :X  a  Ub  [!        S5      eU["        :X  a  U["        [        4;  a  [!        S5      eU[$        :X  a  U[        ["        4;  a  [!        S5      eU[&        :X  a  U[$        :w  a  [!        S5      eU[(        :X  a  U[&        :w  a  [!        S5      eUnM     g)rx  r`  zmissing treer^  zmissing authorr_  zmissing committerr[  zmissing author timerZ  zmissing commit timezinvalid parent shazinvalid tree shazinvalid authorzinvalid committerNzunexpected treezunexpected parentzunexpected authorzunexpected committerzunexpected encoding)r]  rT  r$  r  rU  r~   r`  r   r^  r_  r   r[  rZ  r  r   rF  r   rG  rH  rI  rJ  )r   parentr  r  rj   r?  s        r   r$  Commit.check0  s    	fd!#w7y*:;|-@A~/DE~/DEmmF!56 $TZZ!34t||%56t(;<4$$%4$$%&t'9'9:HE$)9+,=>>.(T: . ,,?@@.(T: . ,,?@@++0F+,BCC**t7H/H+,ABBD# ;r   c                 f   / n[        U R                  [        5      (       a  U R                  R                  OU R                  nUR	                  [        [        U5      5        U R                   H"  nUR	                  [        [        U5      5        M$     UR	                  [        [        U R                  [        U R                  5      R                  S5      [        U R                  U R                   5      5      5        UR	                  [        ["        U R$                  [        U R&                  5      R                  S5      [        U R(                  U R*                  5      5      5        U R,                  (       a)  UR	                  [        [.        U R,                  5      5        U R0                   H  nUR3                  5       R5                  S5      nUR	                  [        [6        US   5      5        USS   H  nUR	                  SU-   S-   5        M     US   R9                  S5      (       d  M  US   S S US'   M     U R:                   H>  u  pxSU;   d  SU;   a  [=        S	U< S
U< 35      eUR	                  [        Xx5      5        M@     U R>                  (       ad  U R>                  R5                  S5      n	UR	                  [        [@        U	S   5      5        U	SS   H  nUR	                  [        SU5      5        M      UR	                  S5        UR	                  U RB                  5        U$ )NrG   r   r   r   r`   r   s    
rR   znewline in extra data: z -> r   )"r;   r`  r  r   r}  r   rF  rU  rG  rH  r^  rd   r[  rF   r  r\  rX  rI  r_  rZ  r]  rY  r  rJ  rP  r   r   rK  r   r   AssertionErrorrQ  rL  r  )
r   r   
tree_bytesr(  rP  mergetag_chunksr   r  r  
sig_chunkss
             r   r   Commit._serialize]  sb   &0T&B&BTZZ]]


h|Z89AMM(>156 D%%&--g6 5 5t7T7TU		
 	!D%%&--g6 5 5t7T7TU		
 ==MM(#3T]]CDH&446<<UCOMM(#3_Q5GHI(,dUlU23 - bz""6**#BZ_r
 & JJDAzUaZ$!Q%OPPMM(1.)  ;;**51JMM(>:a=AB#ABhsE23 (edmm$r   r  z%Tree that is the state of this commitc                     U R                   $ )z(Return a list of parents of this commit.)rU  r   s    r   _get_parentsCommit._get_parents  r8  r   c                     SU l         Xl        g)z%Set a list of parents of this commit.TN)rl   rU  r  s     r   _set_parentsCommit._set_parents  s    $(!r   z&Parents of this commit, by their SHA1.rt   c                     U R                   $ )z%Return extra settings of this commit.)rW  r   s    r   
_get_extraCommit._get_extra  s    {{r   zExtra header fields not understood (presumably added in a newer version of git). Kept verbatim so the object can be correctly reserialized. For private commit metadata, use pseudo-headers in Commit.message, rather than this field.authorz$The name of the author of the commit	committerz'The name of the committer of the commitr  zThe commit messagecommit_timezFThe timestamp of the commit. As the number of seconds since the epoch.commit_timezonezThe zone the commit time is inauthor_timezOThe timestamp the commit was written. As the number of seconds since the epoch.author_timezonez'Returns the zone the author time is in.r  zEncoding of the commit message.rP  zAssociated signed tag.rQ  zGPG Signature.)r^  r[  r\  rX  rZ  r]  rY  r_  rV  rW  rb  ra  r  rl   rU  r`  )"r   r   r   r   r   rc   r  r   r   rW  r  r   r$  r   rw   r  rt  rw  rv   rM  rz  r   r|  r}  r  r~  r  r  r  r  rP  rQ  r   r  r  s   @r   rT  rT    s(   IHI$.  .)Z.` !)PQD
 4G DE #8-STF%>I $I/CDG'SK
 ,;O (	#K ,DO %Z1RSH$Z1IJH"8-=>Fr   rT  )r  r  r'   r+  )r  )Yr   r2   ior   collectionsr   rK   r  r!   typingr   r   r   r   r	  r(   hashlibr	   dulwich.errorsr
   r   r   r   r   r   r   dulwich.filer   ZERO_SHArF  rG  rH  rI  rJ  rK  rL  r  r  r  r  r#   r   r  r   r%   r/   r7   rA   rD   rP   r[   r   r<   re   rd   rw   rb   r~   r   r   r   r  r   r   rY  r  r  r  r  r  r  r  r  r  r  r9  r  r  rR  rT  OBJECT_CLASSESry   r   rc   r  _parse_tree_py_sorted_tree_items_pydulwich._objectsImportErrorr   r   r   <module>r     s3  , "   " 	         !         6 6, 6)&
)
YC Y Y Y

- 
- 
-%
@/,R$
,v ,,w&f w&t	Q7 Qh3l\V' \V~O
;(?@ O#<

,(	
*]7 ]@:V$620fY?W Y?z 	 	C"Icmm!Icll  ) 	>> 		s   (E1 1E:9E: