o
    ﯪgYw                     @   s  d gZ ddlmZ ddlZddlmZ ddlZddlZddlZddl	m
Z
mZ ddl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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#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 ej4dkrddl)m5Z5 nddl6m5Z5 ddl7m8Z8 e1rddl9m:Z: ddl;m<Z< e=e>Z?G dd  d ej@e$ee#ZAdS )Commit    )defaultdictN)BytesIO)PopenPIPE)altzonedaylight	localtimetimetimezone)IStream)Git)Diffable)ActorStatsfinalize_process
hex_to_bin   )base)Tree)SerializableTraversableIterableObjaltz_to_utctz_strfrom_timestampparse_actor_and_date
parse_date)
AnyDictIOIteratorListSequenceTupleTYPE_CHECKINGUnioncast)      )Literal)PathLike)SymbolicReference)Repoc                       s  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ed  e
d
< 											dRd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dZedd ded fddZedddd defdd Zd!edd fd"d#Zd$eddf fd%d&Zedejfd'd(Zedejfd)d*Z edeeef fd+d,Z!dSd.ee"ee" f d!edefd/d0Z#edefd1d2Z$e	-dSddd3eed d4f d.ee"ee" f d!ede%d  f
d5d6Z&dSd.ee"ee" f d!ede%d  fd7d8Z'ede(fd9d:Z)ede*eef fd;d<Z+ede,eeef  fd=d>Z-ede*ee,e f fd?d@Z.edddAee/e0f de%d  fdBdCZ1e		D				dTdddeeef dedEede,d  f dFe2dedef dedef dGedeejf dHedeejf dd fdIdJZ3dKe4dd fdLdMZ5dKe4dd fdNdOZ6ede,e fdPdQZ7  Z8S )Ur   a1  Wraps a git commit object.

    See :manpage:`gitglossary(7)` on "commit object":
    https://git-scm.com/docs/gitglossary#def_commit_object

    :note:
        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hexshar8   Nrepor+   binshar0   r1   r2   r3   r4   r5   r6   r7   r9   r:   returnc                    s   t  || || _|durt|tsJ dt| |dur"|| _|dur)|| _|dur0|| _|dur7|| _	|dur>|| _
|durE|| _|	durL|	| _|
durS|
| _|durZ|| _|dura|| _|durj|| _dS dS )a  Instantiate a new :class:`Commit`. All keyword arguments taking ``None`` as
        default will be implicitly set on first query.

        :param binsha:
            20 byte sha1.

        :param tree:
            A :class:`~git.objects.tree.Tree` object.

        :param author:
            The author :class:`~git.util.Actor` object.

        :param authored_date: int_seconds_since_epoch
            The authored DateTime - use :func:`time.gmtime` to convert it into a
            different format.

        :param author_tz_offset: int_seconds_west_of_utc
            The timezone that the `authored_date` is in.

        :param committer:
            The committer string, as an :class:`~git.util.Actor` object.

        :param committed_date: int_seconds_since_epoch
            The committed DateTime - use :func:`time.gmtime` to convert it into a
            different format.

        :param committer_tz_offset: int_seconds_west_of_utc
            The timezone that the `committed_date` is in.

        :param message: string
            The commit message.

        :param encoding: string
            Encoding of the message, defaults to UTF-8.

        :param parents:
            List or tuple of :class:`Commit` objects which are our parent(s) in the
            commit dependency graph.

        :return:
            :class:`Commit`

        :note:
            Timezone information is in the same format and in the same sign as what
            :func:`time.altzone` returns. The sign is inverted compared to git's UTC
            timezone.
        Nz(Tree needs to be a Tree instance, was %s)super__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__ N/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/git/objects/commit.pyr@   m   s6   ?
zCommit.__init__)r   .c                 C   s
   t |jS N)tupler8   )clsr.   rE   rE   rF   _get_intermediate_items   s   
zCommit._get_intermediate_itemsc                 C   s>   t  }|| | }|d |jt| j||}|jS )zCalculate the sha of a commit.

        :param repo:
            :class:`~git.repo.base.Repo` object the commit should be part of.

        :param commit:
            :class:`Commit` object for which to generate the sha.
        r   )	r   
_serializetellseekodbstorer   r/   r=   )rI   r<   r.   stream	streamlenistreamrE   rE   rF   _calculate_sha_   s   

zCommit._calculate_sha_kwargsc                    sf    fdd j D }|D ]}| j vrtdq||  j j jfi |}  j||_|S )zCreate new commit object from an existing commit object.

        Any values provided as keyword arguments will replace the corresponding
        attribute in the new object.
        c                    s   i | ]}|t  |qS rE   )getattr).0krB   rE   rF   
<dictcomp>   s    z"Commit.replace.<locals>.<dictcomp>zinvalid attribute name)	__slots__
ValueErrorupdaterD   r<   NULL_BIN_SHArS   r=   )rB   rT   attrsattrname
new_commitrE   rX   rF   replace   s   

zCommit.replaceattrc                    sJ   |t jv r| jj| j\}}| _}| t|	  d S t
 | d S rG   )r   rZ   r<   rN   rP   r=   size_deserializer   readr?   _set_cache_)rB   rb   _binsha	_typenamerP   rC   rE   rF   rf      s   
zCommit._set_cache_c                 C      t | j| jS rG   )r   r2   r3   rX   rE   rE   rF   authored_datetime      zCommit.authored_datetimec                 C   ri   rG   )r   r5   r6   rX   rE   rE   rF   committed_datetime   rk   zCommit.committed_datetimec                 C   s0   t | jtr| jddd S | jddd S )z):return: First line of the commit message
r   r      
)rA   r7   strsplitrX   rE   rE   rF   summary  s   zCommit.summary pathsc                 K   sH   |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:
            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 :manpage:`git-rev-list(1)`. They must not
            alter the output style of the command, or parsing will yield incorrect
            results.

        :return:
            An int defining the number of reachable commits
        --)lenr<   gitrev_listr;   
splitlines)rB   rs   rT   rE   rE   rF   count
  s   $ zCommit.countc                 C   s   | j j| S )z
        :return:
            String describing the commits hex sha based on the closest
            `~git.refs.reference.Reference`.

        :note:
            Mostly useful for UI purposes.
        )r<   rv   name_revrX   rE   rE   rF   rz     s   
zCommit.name_revrevr*   c                 K   sj   d|v rt ddg}|r"t|ttjfr|f}nt|}|| |jj||fddi|}| 	||S )a  Find all commits matching the given criteria.

        :param repo:
            The :class:`~git.repo.base.Repo`.

        :param rev:
            Revision specifier. See :manpage:`git-rev-parse(1)` for viable options.

        :param paths:
            An optional path or list of paths. If set only :class:`Commit`\s that
            include the path or paths will be considered.

        :param kwargs:
            Optional keyword arguments to :manpage:`git-rev-list(1)` where:

            * ``max_count`` is the maximum number of commits to fetch.
            * ``skip`` is the number of commits to skip.
            * ``since`` selects all commits since some date, e.g. ``"1970-01-01"``.

        :return:
            Iterator yielding :class:`Commit` items.
        prettyz<--pretty cannot be used as parsing expects single sha's onlyrt   
as_processT)
r[   rA   ro   osr)   rH   extendrv   rw   _iter_from_process_or_stream)rI   r<   r{   rs   rT   	args_list	paths_tupprocrE   rE   rF   
iter_items+  s   
zCommit.iter_itemsc                 K   s8   | dd}|dkrd}||d< | j| j| |fi |S )a  Iterate _all_ parents of this commit.

        :param paths:
            Optional path or list of paths limiting the :class:`Commit`\s to those that
            contain at least one of the paths.

        :param kwargs:
            All arguments allowed by :manpage:`git-rev-list(1)`.

        :return:
            Iterator yielding :class:`Commit` objects which are parents of ``self``
        skipr   r   )getr   r<   )rB   rs   rT   r   rE   rE   rF   iter_parents_  s
   zCommit.iter_parentsc                 C   s   dt t dtfdd}| js'| jjj| jdddddd dd	 }||}n| jjj| jd
 j| jddddd }||}t	
| 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:
            :class:`Stats`
        linesr>   c                 S   sb   d}t | | t| d d  D ]\}}|dd d }|d\}}}|d||||f 7 }q|S )Nrr      	r   z%s	%s	%s	%s
)zipru   rp   )r   text	file_infolinechange_type
insertions	deletionsfilenamerE   rE   rF   process_lines}  s   "z#Commit.stats.<locals>.process_linesrt   T)numstat
no_renamesrootrawr   Nr   )r   r   r   )r    ro   r8   r<   rv   	diff_treer;   rx   diffr   _list_from_string)rB   r   r   r   rE   rE   rF   statst  s   	

zCommit.statsc                 C   s$   t jdtdd dd | j D S )al  Deprecated. Get the trailers of the message as a dictionary.

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

        :return:
            Dictionary containing whitespace stripped trailer information.
            Only contains the latest instance of each trailer key.
        zWCommit.trailers is deprecated, use Commit.trailers_list or Commit.trailers_dict insteadr   )
stacklevelc                 S   s   i | ]	\}}||d  qS )r   rE   )rV   rW   vrE   rE   rF   rY     s    z#Commit.trailers.<locals>.<dictcomp>)warningswarnDeprecationWarningtrailers_dictitemsrX   rE   rE   rF   trailers  s   zCommit.trailersc                 C   s   g d}| j jj|dtd}|t| j d d}|	 }|s%g S g }|
dD ]}|
dd\}}||	 |	 f q,|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 :manpage:`git-interpret-trailers(1)`.

        This function 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.
        )rv   zinterpret-trailersz--parseT)r}   rR   r   utf8rm   :r   )r<   rv   executer   communicatero   r7   encodedecodestriprp   append)rB   cmdr   trailertrailer_listtkeyvalrE   rE   rF   trailers_list  s   !zCommit.trailers_listc                 C   s.   t t}| jD ]\}}|| | q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 :manpage:`git-interpret-trailers(1)`.

        This function 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)rB   dr   r   rE   rE   rF   r     s   #zCommit.trailers_dictproc_or_streamc                 c   s    t |drtt|}|jdur|j}nt |dr tt|}|}|j}	 | }|s*n'| }t|dkr<|dd\}}t|dksHJ d| | |t	|V  q$t |dratt|}t
| dS dS )a  Parse out commit information into a list of :class:`Commit` objects.

        We expect one line per commit, and parse the actual commit information directly
        from our lighting fast object database.

        :param proc:
            :manpage:`git-rev-list(1)` process instance - one sha per line.

        :return:
            Iterator supplying :class:`Commit` objects
        waitNreadlineT(   r   zInvalid line: %s)hasattrr%   r   stdoutr   r   r   ru   rp   r   r   )rI   r<   r   rP   r   r   r;   _rE   rE   rF   r      s0   






z#Commit._iter_from_process_or_streamFparent_commitsheadauthor_datecommit_datec
                 C   s   |du rz|j jg}W n ty   g }Y nw |D ]}
t|
| s*td|
d|  q| }tj}|p8t|}|p?t	|}t
t }toLt jdk}|rQtnt}|| jd}|rct|\}}n|rlt|\}}n||}}|| jd}|	rt|	\}}n|rt|\}}n||}}| jd\}}|||| j}t|tstdt|tr||}| || j||||||||||}| |||_|rddl}z|j j ||d W |S  ty   |j!j"j#||j j$|d	| d}|j j%|d
| d Y |S w |S )a  Commit the given tree, creating a :class:`Commit` object.

        :param repo:
            :class:`~git.repo.base.Repo` object the commit should be part of.

        :param tree:
            :class:`~git.objects.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 :class:`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.
            Otherwise 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:
            :class:`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 :manpage:`git-commit-tree(1)`
            for more information.
        NzParent commit 'z' must be of type r   rr   .z)conf_encoding could not be coerced to str)logmsgzcommit (initial): %szcommit: Switching to %s)&r   r.   r[   rA   config_readerr~   environr   r4   r1   intr
   r   r	   tm_isdstr   r   r   env_author_dater   env_committer_dateconf_encodingrp   	get_valuedefault_encodingro   	TypeErrorr0   r]   rS   r=   git.refs
set_commitrefsHeadcreaterefset_reference)rI   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   r`   rv   masterrE   rE   rF   create_from_tree1  s   ;






zCommit.create_from_treerP   c           	      C   sT  |j }|d| j d | jD ]}|d| d q| j}|j}| j}d}||d||j| jt	| j
f | j |j}||d||j| jt	| jf | j | j| jkrb|d| j d z"| dr|d	 | jd
d
D ]}|d| d
 d quW n	 ty   Y nw |d t| jtr|| j| j | S || j | S )Nztree %s
asciiz
parent %s
z%s %s <%s> %s %s
r1   r4   zencoding %s
r:   s   gpgsigrm    rn   )writer0   r   r8   r1   namer4   emailr2   r   r3   r9   r5   r6   r   __getattribute__r:   rstriprp   AttributeErrorrA   r7   ro   )	rB   rP   r   r   aanamecfmtsiglinerE   rE   rF   rK     s`   


zCommit._serializec              	   C   s  |j }t| jt|  d tjd> d| _g | _d }	 | }|ds'|}n| j	t
| | jt| d d qt| j| _|}| }| }|dre| }|d	r`| }|d	sX|dsP| j| _d| _|}| }|r|d
d dkr||d	d d  | jd| _nD|d
d dkr||d	d d  d }	d}
	 | }|sn|d
d d	kr| }d}
n	|	|dd  7 }	q|	d| jd| _|
rqr|  }|stzt|| jd\| _| _| _W n ty   tjd|| jdd Y nw zt|| jd\| _| _| _W n ty#   tjd|| jdd Y nw | | _z| j| jd| _W | S  tyK   tjd| j| jdd Y | S w )Nr      rr   Ts   parentr   r   s	   mergetag     r   
   s	   encoding ignore   s   gpgsig rn   Fra   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   rp   tree_idr0   r8   
startswithr   r/   r   rH   r   r9   r:   r   findr   r   r1   r2   r3   UnicodeDecodeError_loggererrorr4   r5   r6   re   r7   )rB   rP   r   	next_lineparent_lineauthor_linecommitter_lineencbufsigis_next_headersigbufrE   rE   rF   rd     s   &
*



$





zCommit._deserializec                 C   s8   g }| j rtd| j tj}|D ]	}|t|  q|S )a  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 :class:`~git.util.Actor` objects).
        z^Co-authored-by: (.*) <(.*?)>$)r7   refindall	MULTILINEr   r   )rB   
co_authorsresultsr1   rE   rE   rF   r
  x  s   
zCommit.co_authors)NNNNNNNNNNN)rr   )NFNNNN)9__name__
__module____qualname____doc__r   r   r   r   r/   r(   __annotations__rZ   _id_attribute_r!   bytesr$   r   r   r   floatro   r@   classmethodr"   rJ   rS   r   ra   rf   propertydatetimerj   rl   rq   r)   ry   rz   r   r   r   r   r   r   r   r    r   r   r   r   r   boolr   r   rK   rd   r
  __classcell__rE   rE   rC   rF   r   C   s   
 





	



Z	$(33'$0


	
 ";j)B__all__collectionsr   r  ior   loggingr~   r  
subprocessr   r   sysr
   r   r   r	   r   r   gitdbr   git.cmdr   git.diffr   git.utilr   r   r   r   rr   r   r0   r   utilr   r   r   r   r   r   typingr   r   r   r   r    r!   r"   r#   r$   r%   version_infor(   typing_extensions	git.typesr)   r   r*   git.repor+   	getLoggerr  r   Objectr   rE   rE   rE   rF   <module>   s8    0

