
    64%eq                        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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 dd
lmZmZmZmZmZmZ d dlmZmZmZmZmZ d dl Z d dl!m"Z" d dl#Z#d dl$m%Z% d dl&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 d dl1m2Z2m3Z3 e.rd dl4m5Z5 d dl6m7Z7  e#j8        d          Z9e9:                     e#j;                               dZ< G d dej=        eee          Z>dS )    N)PopenPIPE)IStream)
hex_to_binActorStatsfinalize_process)Diffable)Git   )Tree)base)SerializableTraversableIterableObj
parse_datealtz_to_utctz_strparse_actor_and_datefrom_timestamp)timedaylightaltzonetimezone	localtime)BytesIO)defaultdict)
AnyIOIteratorListSequenceTupleUnionTYPE_CHECKINGcastDict)PathLikeLiteral)Repo)SymbolicReferencezgit.objects.commit)Commitc                   Z    e Zd ZU dZdZdZdZdZdZe	d         e
d<   dZd	Z	 	 	 	 	 	 	 	 	 	 	 d=dddedeed
f         deed
f         deed
f         ded
ef         deed
f         deed
f         ded
ef         deeed
f         deed          d
f         deed
f         deed
f         dd
f fdZedd ded         fd            Zedddd defd            Zdedd fdZd edd
f fd!Zedej        fd"            Zedej        fd#            Z edeeef         fd$            Z!d>d&ee"ee"         f         dedefd'Z#edefd(            Z$e	 d>ddd)eed d*f         d&ee"ee"         f         dede%d          f
d+            Z&d>d&ee"ee"         f         dede%d          fd,Z'ede(fd-            Z)ede*eef         fd.            Z+ede,eeef                  fd/            Z-ede*ee,e         f         fd0            Z.eddd1ee/e0f         de%d          fd2            Z1e	 	 	 	 	 	 d?dddeeef         ded4ed
e,d          f         d5e2ded
ef         ded
ef         d6ed
eej        f         d7ed
eej        f         dd fd8            Z3d9e4dd fd:Z5d9e4dd fd;Z6ede,e         fd<            Z7 xZ8S )@r*   zWraps a git Commit object.

    This class will act lazily on some of its attributes and will query the
    value on demand only if it involves calling the git binary.GIT_AUTHOR_DATEGIT_COMMITTER_DATEzi18n.commitencodingzUTF-8committype)treeauthorauthored_dateauthor_tz_offset	committercommitted_datecommitter_tz_offsetmessageparentsencodinggpgsighexshaNrepor(   binshar0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   returnc                    t          t          |                               ||           || _        |/t	          |t
                    sJ dt          |          z              ||| _        ||| _        ||| _	        ||| _
        ||| _        ||| _        |	|	| _        |
|
| _        ||| _        ||| _        |	|| _        dS dS )a  Instantiate a new Commit. All keyword arguments taking None as default will
        be implicitly set on first query.

        :param binsha: 20 byte sha1
        :param parents: tuple( Commit, ... )
            is a tuple of commit ids or actual Commits
        :param tree: Tree object
        :param author: Actor
            is the author Actor object
        :param authored_date: int_seconds_since_epoch
            is the authored DateTime - use time.gmtime() to convert it into a
            different format
        :param author_tz_offset: int_seconds_west_of_utc
            is the timezone that the authored_date is in
        :param committer: Actor
            is the committer string
        :param committed_date: int_seconds_since_epoch
            is the committed DateTime - use time.gmtime() to convert it into a
            different format
        :param committer_tz_offset: int_seconds_west_of_utc
            is the timezone that the committed_date is in
        :param message: string
            is the commit message
        :param encoding: string
            encoding of the message, defaults to UTF-8
        :param parents:
            List or tuple of Commit objects which are our parent(s) in the commit
            dependency graph
        :return: git.Commit

        :note:
            Timezone information is in the same format and in the same sign
            as what time.altzone returns. The sign is inverted compared to git's
            UTC timezone.Nz(Tree needs to be a Tree instance, was %s)superr*   __init__r=   
isinstancer   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   )selfr<   r=   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   	__class__s                 2lib/python3.11/site-packages/git/objects/commit.pyrA   zCommit.__init__`   s    d 	fd$$T6222dD))bb+UX\]aXbXb+bbbbDI DK$!.D'$4D! &DN%"0D*':D$"DL"DL$DM DKKK     )r*   .c                 *    t          |j                  S N)tupler8   )clsr.   s     rE   _get_intermediate_itemszCommit._get_intermediate_items   s    V^$$$rF   c                    t                      }|                    |           |                                }|                    d           |j                            t          | j        ||                    }|j        S )zCalculate the sha of a commit.

        :param repo: Repo object the commit should be part of
        :param commit: Commit object for which to generate the sha
        r   )	r   
_serializetellseekodbstorer   r/   r=   )rJ   r<   r.   stream	streamlenistreams         rE   _calculate_sha_zCommit._calculate_sha_   sf     &!!!KKMM	A(..9f!E!EFF~rF   kwargsc                      fd j         D             }|D ]}| j         vrt          d          |                    |             j         j         j        fi |}                      j        |          |_        |S )zCreate new commit object from existing commit object.

        Any values provided as keyword arguments will replace the
        corresponding attribute in the new object.
        c                 2    i | ]}|t          |          S  )getattr).0krC   s     rE   
<dictcomp>z"Commit.replace.<locals>.<dictcomp>   s%    ===GD!$$===rF   zinvalid attribute name)	__slots__
ValueErrorupdaterD   r<   NULL_BIN_SHArU   r=   )rC   rV   attrsattrname
new_commits   `    rE   replacezCommit.replace   s     >===dn=== 	; 	;Ht~-- !9::: . 	V#T^DIt/@JJEJJ
 00JGG
rF   attrc                 <   |t           j        v rd| j        j                            | j                  \  }}| _        }|                     t          |	                                                     d S t          t           |                               |           d S rH   )r*   r^   r<   rP   rR   r=   size_deserializer   readr@   _set_cache_)rC   rf   _binsha	_typenamerR   rD   s        rE   rk   zCommit._set_cache_   s    6###48IM4H4H4U4U1GY	6gfkkmm4455555&$++D11111rF   c                 6    t          | j        | j                  S rH   )r   r2   r3   rC   s    rE   authored_datetimezCommit.authored_datetime   s    d0$2GHHHrF   c                 6    t          | j        | j                  S rH   )r   r5   r6   ro   s    rE   committed_datetimezCommit.committed_datetime   s    d143KLLLrF   c                     t          | j        t                    r!| j                            dd          d         S | j                            dd          d         S )z):return: First line of the commit message
r   r      
)rB   r7   strsplitro   s    rE   summaryzCommit.summary   sR     dlC(( 	3<%%dA..q11<%%eQ//22rF    pathsc                     |r>t           | j        j        j        | j        d|fi |                                          S t           | j        j        j        | j        fi |                                          S )a  Count the number of commits reachable from this commit

        :param paths:
            is an optional path or a list of paths restricting the return value
            to commits actually containing the paths

        :param kwargs:
            Additional options to be passed to git-rev-list. They must not alter
            the output style of the command, or parsing will yield incorrect results
        :return: int defining the number of reachable commits--)lenr<   gitrev_listr;   
splitlines)rC   rz   rV   s      rE   countzCommit.count   s}      	`-ty}-dk4QQ&QQ\\^^___)49=)$+@@@@KKMMNNNrF   c                 @    | j         j                            |           S )z
        :return:
            String describing the commits hex sha based on the closest Reference.
            Mostly useful for UI purposes)r<   r~   name_revro   s    rE   r   zCommit.name_rev   s     y}%%d+++rF   revr)   c                    d|v rt          d          dg}|rIt          |t          t          j        f          r|f}nt          |          }|                    |            |j        j        ||fddi|}| 	                    ||          S )an  Find all commits matching the given criteria.

        :param repo: is the Repo
        :param rev: revision specifier, see git-rev-parse for viable options
        :param paths:
            is an optional path or list of paths, if set only Commits that include the path
            or paths will be considered
        :param kwargs:
            optional keyword arguments to git rev-list where
            ``max_count`` is the maximum number of commits to fetch
            ``skip`` is the number of commits to skip
            ``since`` all commits since i.e. '1970-01-01'
        :return: iterator yielding Commit itemsprettyz<--pretty cannot be used as parsing expects single sha's onlyr|   
as_processT)
r_   rB   rv   osr&   rI   extendr~   r   _iter_from_process_or_stream)rJ   r<   r   rz   rV   	args_list	paths_tupprocs           rE   
iter_itemszCommit.iter_items  s    * v[\\\ &*F	 	(%#r{!344 )"H		!%LL	Y''' !tx iKKDKFKK//d;;;rF   c                 r    |                     dd          }|dk    rd}||d<    | j        | j        | |fi |S )aA  Iterate _all_ parents of this commit.

        :param paths:
            Optional path or list of paths limiting the Commits to those that
            contain at least one of the paths
        :param kwargs: All arguments allowed by git-rev-list
        :return: Iterator yielding Commit objects which are parents of selfskipr   r   )getr   r<   )rC   rz   rV   r   s       rE   iter_parentszCommit.iter_parents1  sN     zz&!$$199Dvtty$@@@@@rF   c                    | j         st| j        j                            | j        dddd          }d}|                                dd         D ])}|                    d          \  }}}||d|d|dz  }*|}n9| j        j                            | j         d	         j        | j        ddd
          }t          j	        | j        |          S )zCreate a git stat from changes between this commit and its first parent
        or from all changes done if this is the very first commit.

        :return: git.Statsr|   T)numstat
no_renamesrootry   r   N	rt   r   )r   r   )
r8   r<   r~   	diff_treer;   r   rw   diffr   _list_from_string)rC   texttext2line
insertions	deletionsfilenames          rE   statszCommit.statsA  s     | 	p9=**4;dW[bf*ggDE))!""- L L48JJt4D4D1Y:::yyy(((KKDD9=%%dl1o&<dk4Y]jn%ooD&ty$777rF   c                 H    d | j                                         D             S )aM  Get the trailers of the message as a dictionary

        :note: This property is deprecated, please use either ``Commit.trailers_list`` or ``Commit.trailers_dict``.

        :return:
            Dictionary containing whitespace stripped trailer information.
            Only contains the latest instance of each trailer key.
        c                 &    i | ]\  }}||d          S )r   rY   )r[   r\   vs      rE   r]   z#Commit.trailers.<locals>.<dictcomp>\  s"    ???DAq1Q4???rF   )trailers_dictitemsro   s    rE   trailerszCommit.trailersR  s(     @?D$6$<$<$>$>????rF   c                    g d}| j         j                            |dt                    }|                    t          | j                                                            d                             d          }|	                                }|sg S g }|
                    d          D ]V}|
                    dd          \  }}|                    |	                                |	                                f           W|S )	a  Get the trailers of the message as a list

        Git messages can contain trailer information that are similar to RFC 822
        e-mail headers (see: https://git-scm.com/docs/git-interpret-trailers).

        This functions calls ``git interpret-trailers --parse`` onto the message
        to extract the trailer information, returns the raw trailer data as a list.

        Valid message with trailer::

            Subject line

            some body information

            another information

            key1: value1.1
            key1: value1.2
            key2 :    value 2 with inner spaces


        Returned list will look like this::

            [
                ("key1", "value1.1"),
                ("key1", "value1.2"),
                ("key2", "value 2 with inner spaces"),
            ]


        :return:
            List containing key-value tuples of whitespace stripped trailer information.
        )r~   zinterpret-trailersz--parseT)r   rT   r   utf8rt   :r   )r<   r~   executer   communicaterv   r7   encodedecodestriprw   append)rC   cmdr   trailertrailer_listtkeyvals           rE   trailers_listzCommit.trailers_list^  s    F 766"&)-"7"7VZ"7"["[''DL(9(9(@(@(B(BCCAFMMfUU--// 	It$$ 	< 	<AwwsAHCciikk :;;;;rF   c                     t          t                    }| j        D ] \  }}||                             |           !t	          |          S )a  Get the trailers of the message as a dictionary

        Git messages can contain trailer information that are similar to RFC 822
        e-mail headers (see: https://git-scm.com/docs/git-interpret-trailers).

        This functions calls ``git interpret-trailers --parse`` onto the message
        to extract the trailer information. The key value pairs are stripped of
        leading and trailing whitespaces before they get saved into a dictionary.

        Valid message with trailer::

            Subject line

            some body information

            another information

            key1: value1.1
            key1: value1.2
            key2 :    value 2 with inner spaces


        Returned dictionary will look like this::

            {
                "key1": ["value1.1", "value1.2"],
                "key2": ["value 2 with inner spaces"],
            }


        :return:
            Dictionary containing whitespace stripped trailer information.
            Mapping trailer keys to a list of their corresponding values.
        )r   listr   r   dict)rC   dr   r   s       rE   r   zCommit.trailers_dict  sL    H * 	 	HCcFMM#AwwrF   proc_or_streamc              #   N  K   t          |d          r$t          t          |          }|j        |j        }n't          |d          rt          t          |          }|}|j        }	  |            }|sn||                                }t          |          dk    r|                    dd          \  }}t          |          dk    sJ d|z               | |t          |                    V  t          |d          r&t          t          |          }t          |           dS dS )a;  Parse out commit information into a list of Commit objects
        We expect one-line per commit, and parse the actual commit information directly
        from our lighting fast object database

        :param proc: git-rev-list process instance - one sha per line
        :return: iterator returning Commit objectswaitNreadlineT(   r   zInvalid line: %s)hasattrr$   r   stdoutr   r   r   r}   rw   r   r	   )rJ   r<   r   rR   r   r   r;   _s           rE   r   z#Commit._iter_from_process_or_stream  sE      >6** 	$!%88N$0'.^Z00 	$!"n55N#F?	08::D ZZ\\F6{{R JJtQ//	 v;;"$$$&86&A$$$#dJv../////	0 >6** 	-!%88N^,,,,,	- 	-rF   Fparent_commitsheadauthor_datecommit_datec
                 n   |!	 |j         j        g}n<# t          $ r g }Y n.w xY w|D ]'}
t          |
|           st          d|
d|            (|                                }t
          j        }|pt          j        |          }|pt          j	        |          }t          t                                }t          ot                      j        dk    }|rt          nt           }|                    | j        d          }|rt'          |          \  }}n|rt'          |          \  }}n||}}|                    | j        d          }|	rt'          |	          \  }}n|rt'          |          \  }}n||}}| j                            d          \  }}|                    ||| j                  }t          |t2                    st5          d          t          |t2                    r|                    |          } | || j        ||||||||||          }|                     ||          |_        |rddl}	 |j                              ||           n_# t          $ rR |j!        j"        #                    ||j         j$        |d	|z            }|j         %                    |d
|z             Y nw xY w|S )a2  Commit the given tree, creating a commit object.

        :param repo: Repo object the commit should be part of
        :param tree: Tree object or hex or bin sha
            the tree of the new commit
        :param message: Commit message. It may be an empty string if no message is provided.
            It will be converted to a string , in any case.
        :param parent_commits:
            Optional Commit objects to use as parents for the new commit.
            If empty list, the commit will have no parents at all and become
            a root commit.
            If None , the current head commit will be the parent of the
            new commit object
        :param head:
            If True, the HEAD will be advanced to the new commit automatically.
            Else the HEAD will remain pointing on the previous commit. This could
            lead to undesired results when diffing files.
        :param author: The name of the author, optional. If unset, the repository
            configuration is used to obtain this value.
        :param committer: The name of the committer, optional. If unset, the
            repository configuration is used to obtain this value.
        :param author_date: The timestamp for the author field
        :param commit_date: The timestamp for the committer field

        :return: Commit object representing the new commit

        :note:
            Additional information about the committer and Author are taken from the
            environment or from the git configuration, see git-commit-tree for
            more informationNzParent commit 'z' must be of type r   ry   .z)conf_encoding could not be coerced to str)logmsgzcommit (initial): %szcommit: Switching to %s)&r   r.   r_   rB   config_readerr   environr   r4   r1   intr   r   r   tm_isdstr   r   r   env_author_dater   env_committer_dateconf_encodingrw   	get_valuedefault_encodingrv   	TypeErrorr0   ra   rU   r=   git.refs
set_commitrefsHeadcreaterefset_reference)rJ   r<   r0   r7   r   r   r1   r4   r   r   pcrenv	unix_timeis_dstoffsetauthor_date_strauthor_timeauthor_offsetcommitter_date_strcommitter_timecommitter_offsetenc_section
enc_optionr   rd   r~   masters                               rE   create_from_treezCommit.create_from_tree  sJ   V !$"&)"2!3 $ $ $!#$
 $ U U!!S)) U$%Sq%S%Sc%S%STTTU !!j4!4!4	+5<++ KK	6ikk2Q6"0''#"5r:: 	;)3K)@)@&K 	;)3O)D)D&K)2FK !WWS%;R@@ 	A/9+/F/F,N,, 	A/9:L/M/M,N,,/8&,N #&"3"9"9#">">Z[*c>RSS--- 	IGHHH dC   	#99T??D S
 

  //jAA
 	[ OOO[	$$Z$@@@@ 	[ 	[ 	[ --IM1G;	 .   	''7PSY7Y'ZZZZZ	[ s    !!9I AJ21J2rR   c           
      B   |j         } |d| j        z                      d                     | j        D ]#} |d|z                      d                     $| j        }|j        }| j        }d} ||d||j        | j        t          | j
                  fz                      | j                             |j        } ||d||j        | j        t          | j                  fz                      | j                             | j        | j        k    r& |d| j        z                      d                     	 |                     d          r_ |d	           | j                            d
                              d
          D ]&} |d|z   d
z                       d                     'n# t&          $ r Y nw xY w |d           t)          | j        t,                    r) || j                            | j                             n || j                   | S )Nztree %s
asciiz
parent %s
z%s %s <%s> %s %s
r1   r4   zencoding %s
r:   s   gpgsigrt    ru   )writer0   r   r8   r1   namer4   emailr2   r   r3   r9   r5   r6   r   __getattribute__r:   rstriprw   AttributeErrorrB   r7   rv   )	rC   rR   r   r   aanamecfmtsiglines	            rE   rM   zCommit._serializew  sh   {TY&..w77888 	7 	7AE=1$,,W556666KN"G&%d&;<< fT]##	
 	
 	
 G'%d&>?? fT]##	
 	
 	
 =D111E?T]2::7CCDDD	$$X.. Bi   #{11$77==dCC B BGE3=4/77@@AAAA 	 	 	D	 	e dlC(( 	 E$,%%dm445555E$,s   <A4F1 1
F>=F>c           
      X   |j         }t          | j        t           |                                            d                   t          j        dz  d          | _        g | _        d}	  |            }|                    d          s|}no| j        	                     t          |           | j        t          |                                d                             d                                         t          | j                  | _        |} |            } |            }|                    d	          rS |            }|                    d
          r |            }|                    d
          |                    d	          S| j        | _        d| _        |}|                                }|r|dd         dk    r?||                    d
          dz   d                             | j        d          | _        n|dd         dk    r||                    d
          dz   d         dz   }	d}
	  |            }|sn3|dd         d
k    r|                                }d}
n|	|dd         z  }	@|	                    d                              | j        d          | _        |
r |                                            }|	 t'          |                    | j        d                    \  | _        | _        | _        n3# t.          $ r& t0                              d|| j        d           Y nw xY w	 t'          |                    | j        d                    \  | _        | _        | _        n3# t.          $ r& t0                              d|| j        d           Y nw xY w|                                | _        	 | j                            | j        d          | _        n8# t.          $ r+ t0                              d| j        | j        d           Y nw xY w| S )z
        :param from_rev_list: if true, the stream format is coming from the rev-list command
            Otherwise it is assumed to be a plain data stream from our object
        r      ry   NTs   parentr   s	   mergetag     r   
   s	   encoding ignore   s   gpgsig ru   Fre   z3Failed to decode author line '%s' using encoding %s)exc_infoz6Failed to decode committer line '%s' using encoding %sz/Failed to decode message '%s' using encoding %s)r   r   r<   r   rw   tree_idr0   r8   
startswithr   r/   r   rI   r   r9   r:   r   findr   r   r1   r2   r3   UnicodeDecodeErrorlogerrorr4   r5   r6   rj   r7   )rC   rR   r   	next_lineparent_lineauthor_linecommitter_lineencbufsigis_next_headersigbufs               rE   ri   zCommit._deserialize  s   
 ?Jxxzz/?/?/A/A!/D$E$Et|WYGY[]^^			l"(**K)))44 '	L
T

49jARARATATUWAXA_A_`gAhAh6i6i j jkkk	l T\**  ! HJJ	""<00 	' 

I&&t,, '$HJJ	 &&t,, ' ""<00 	' - iikk 	%1R4yL(( #CHHTNNQ$6$8$8 9 @ @PX Y YQqSZ''#((4..1,../%7!&&%XZZF! ac{d**$llnn)-6!"":%C& "jj//66t}hOO! (**""$$C'  	%,	
 %[%7%7y%Q%QRR	"%%! 	 	 	IIE	      		
 %^%:%:4=)%T%TUU	#((! 	 	 	IIH	      	 {{}}	<..t}iHHDLL! 	 	 	IIA	      	 s6   ;L -L?>L?;M? ?-N/.N/%O2 22P'&P'c                     g }| j         rFt          j        d| j         t          j                  }|D ]}|                    t          |            |S )z
        Search the commit message for any co-authors of this commit.
        Details on co-authors: https://github.blog/2018-01-29-commit-together-with-co-authors/

        :return: List of co-authors for this commit (as Actor objects).
        z^Co-authored-by: (.*) <(.*?)>$)r7   refindall	MULTILINEr   r   )rC   
co_authorsresultsr1   s       rE   r  zCommit.co_authors  sc     
< 	2j1 G
 " 2 2!!%.1111rF   )NNNNNNNNNNN)ry   )NFNNNN)9__name__
__module____qualname____doc__r   r   r   r   r/   r'   __annotations__r^   _id_attribute_bytesr"   r   r   r   floatrv   r    rA   classmethodr!   rK   rU   r   re   rk   propertydatetimerp   rr   rx   r&   r   r   r   r   r   r   r   r%   r   r   r   r   r   r   r   boolr   r   rM   ri   r  __classcell__)rD   s   @rE   r*   r*   =   s        C C (O- *M  'D'(
&&&I N #'%)*./3(,+/26+/37%)#'K! K!K! K! D$J	K!
 eTk"K! S$Y'K!  e,K! %K! c4i(K! #4;/K! sE4'(K! x)4/0K! T	"K! c4i K! 
K! K! K! K! K! K!Z %X %%:N % % % [% 6 8     [     &2 2 2 2 2 2 2 2 I8#4 I I I XI MH$5 M M M XM 3sEz* 3 3 3 X3O O58H+=!=> Os OWZ O O O O" ,# , , , X, 
 68	(< (<(< 3"556(< Xx112	(<
 (< 
(	(< (< (< [(<TA A%(82D(D"E AVY A^fgo^p A A A A  8u 8 8 8 X8  	@$sCx. 	@ 	@ 	@ X	@ /tE#s(O4 / / / X/b &tCcN3 & & & X&P (- (-eUWiHX (-]efn]o (- (- (- [(-T  7;%)(,;?;?N NN D#IN 	N
 dDN23N N dEk"N u%N 4h&778N 4h&778N 
N N N [Nd9 9X 9 9 9 9vi7 ix i i i iZ DK    X    rF   r*   )?r!  r  
subprocessr   r   gitdbr   git.utilr   r   r   r	   git.diffr
   git.cmdr   r0   r   ry   r   utilr   r   r   r   r   r   r   r   r   r   r   r   ior   loggingcollectionsr   typingr   r   r   r   r    r!   r"   r#   r$   r%   	git.typesr&   r'   git.repor(   r   r)   	getLoggerr  
addHandlerNullHandler__all__Objectr*   rY   rF   rE   <module>r5     s    				 " " " " " " " "       ? ? ? ? ? ? ? ? ? ? ? ?                                        > = = = = = = = = = = = = = 				        # # # # # #
                        ( ' ' ' ' ' ' ' +****** g,-- "w"$$ % % %
u u u u uT[0(L u u u u urF   