o
     {g                     @  s@  d dl mZ dgZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dlZd dlZd dlZd dlZd dlZd dlmZ d dlmZ d dlmZmZ d dlmZmZ d d	lmZ d d
lmZ d dlmZm Z m!Z! d dl"m#Z# d dl$m%Z%m&Z&m'Z' d dl(m)Z)m*Z*m+Z+m,Z, d dl-m.Z.m/Z/m0Z0 d dl1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7 ddl8m9Z9m:Z:m;Z;m<Z<m=Z= d dl>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZE d dlFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZSmTZTmUZUmVZV d dl>mWZWmXZX eQr
d dl$mYZY d dlZm[Z[ d dl\m]Z] d dl-m^Z^ d dl1m_Z_ e`eaZbG dd deNZcG dd dZddS )    )annotationsRepoN)Path)LooseObjectDB)	BadObject)Githandle_process_output)defencsafe_decode)GitConfigParser)GitCmdObjectDB)GitCommandErrorInvalidGitRepositoryErrorNoSuchPathError	IndexFile)	Submodule
RootModuleCommit)HEADHead	ReferenceTagReference)Remoteadd_progressto_progress_instance)Actorcygpathexpand_pathfinalize_process
hex_to_binremove_password_if_present   )find_submodule_git_dirfind_worktree_git_dir
is_git_dir	rev_parsetouch)CallableProgress
Commit_ishLit_config_levelsPathLikeTBDTree_ishassert_never)AnyBinaryIOCallableDictIteratorListMapping
NamedTupleOptionalSequenceTYPE_CHECKINGTextIOTupleTypeUnioncast)ConfigLevels_Tup	TypedDict)Tree)UpdateProgress)SymbolicReference)RemoteProgress)IterableListc                   @  s.   e Zd ZU ded< ded< ded< ded< dS )	
BlameEntryzDict[str, Commit]commitrangelinenosOptional[str]	orig_pathorig_linenosN__name__
__module____qualname____annotations__ rR   rR   j/var/www/bot.gig.net.ua/public_html/telegram/P1/HellBot/venv/lib/python3.10/site-packages/git/repo/base.pyrF   b   s
   
 rF   c                   @  s  e Zd ZU dZdZeddZded< 	 dZded< ded	< 	 d
Z	ded< e
dZe
dZe
dZe
dZe
dZe
dZg dZ	 dZded< 	 eZ	 deddfdd d!Zdd#d$Zdd'd(Zd	d)d*Zd	d+d,Zd
d/d0Zd
d1d2Zdd4d5Zdd7d8Zdd:d;Z e!ee d<d=Z"[[ e!dd>d?Z#e!dd@dAZ$e!ddBdCZ%e!ddEdFZ&e!ddGdHZ'e!ddJdKZ(e!ddLdMZ)e!ddOdPZ*e!ddRdSZ+e!ddUdVZ,dddZd[Z-e!dd]d^Z.dd`daZ/ddddeZ0ddgdhZ1ddidjZ2e!ddldmZ3ddodpZ4e5ddqdrZ6	s		dd dzd{Z7d!d~dZ8	s		d"d#ddZ9d$ddZ:d%ddZ;d&ddZ<d'd(ddZ=	d'd)ddZ>		d*d+ddZ?d,d-ddZ@d'd.ddZAd/ddZBd'd0ddZC		
d1d2ddZDd3ddZEd4ddZFd'd5ddZGdddZHd6ddZIe!eHeIdd=ZJ[H[Id7ddZKd8ddĄZLe!eKeLdd=ZM					d9d:dd˄ZNe!d7dd̈́ZOd;ddτZPd<ddфZQe!d=ddԄZRd>ddلZS		d?d@ddZTeUddedfdAddZVeU				dBdCddZW				dBdDddZXeU					dEdFddZY		d*dGddZZddd Z[e\Z\dddZ]dHddZ^dS (I  r   a^  Represents a git repository and allows you to query references, create commit
    information, generate diffs, create and clone repositories, and query the log.

    The following attributes are worth using:

    * :attr:`working_dir` is the working directory of the git command, which is the
      working tree directory if available or the ``.git`` directory in case of bare
      repositories.

    * :attr:`working_tree_dir` is the working tree directory, but will return ``None``
      if we are a bare repository.

    * :attr:`git_dir` is the ``.git`` repository directory, which is always set.
    zgit-daemon-export-okr   Nr+   working_dirOptional[PathLike]_working_tree_dirgit_dir _common_dirz\s+z^[0-9A-Fa-f]{40}$z^[0-9A-Fa-f]{4,40}$z5(\$(\{\s?)?[a-zA-Z_]\w*(\}\s?)?|%\s?[a-zA-Z_]\w*\s?%)z^(author|committer)z^\t(.*)$)z--upload-packz-uz--configz-c)systemuserglobal
repositoryr?   config_levelFTpathodbtType[LooseObjectDB]search_parent_directoriesboolexpand_varsreturnNonec                 C  s|  |pt d}|st  }t rtt|}|p|pt  }t|ts(t|}|r8t	| j
|r8tjddd t||}|durKt j|sKt||}d}|rt|r|}t j|| _t jddu ry| d|}|dd	ry|dd	| _d
t jv rt d
| _n;t|d}	t|	}
|
durt|
}t|	}
|
du rt|	}
|
durt|
|}|| _n|snt|\}}|sn|sQ|du rt||| _d| _ z| !d"dd| _ W n	 t#y   Y nw zt$| jd % & d ' }t| j|| _(W n t)y
   d| _(Y nw | j rd| _| jp| j*| _+| ,| j+| _-t| j*d}t.|t/r7||| j-| _0dS ||| _0dS )a  Create a new :class:`Repo` instance.

        :param path:
            The path to either the worktree directory or the .git directory itself::

                repo = Repo("/Users/mtrier/Development/git-python")
                repo = Repo("/Users/mtrier/Development/git-python.git")
                repo = Repo("~/Development/git-python.git")
                repo = Repo("$REPOSITORIES/Development/git-python.git")
                repo = Repo(R"C:\Users\mtrier\Development\git-python\.git")

            - In *Cygwin*, `path` may be a ``cygdrive/...`` prefixed path.
            - If `path` is ``None`` or an empty string, :envvar:`GIT_DIR` is used. If
              that environment variable is absent or empty, the current directory is
              used.

        :param odbt:
            Object DataBase type - a type which is constructed by providing the
            directory containing the database objects, i.e. ``.git/objects``. It will be
            used to access all object data.

        :param search_parent_directories:
            If ``True``, all parent directories will be searched for a valid repo as
            well.

            Please note that this was the default behaviour in older versions of
            GitPython, which is considered a bug though.

        :raise git.exc.InvalidGitRepositoryError:

        :raise git.exc.NoSuchPathError:

        :return:
            :class:`Repo`
        GIT_DIRzoThe use of environment variables in paths is deprecated
for security reasons and may be removed in the future!!r"   )
stacklevelNGIT_COMMON_DIRr]   coreworktreeGIT_WORK_TREE.gitFbare	commondirr   rX   objects)1osgetenvgetcwdr   	is_cygwinr   str
isinstanceresearch
re_envvarswarningswarnr   r_   existsr   r%   dirnamerV   environget_config_reader
has_optionospjoinr#   normpathr$   splitr   rW   _bareconfig_reader
getboolean	Exceptionr   	read_text
splitlinesstriprY   OSError
common_dirrT   GitCommandWrapperTypegit
issubclassr   odb)selfr_   r`   rb   rd   epathcurpathrW   gitconfdotgit
sm_gitpathtailr   rootpathrR   rR   rS   __init__   s   +




/
zRepo.__init__'Repo'c                 C  s   | S NrR   r   rR   rR   rS   	__enter__A  s   zRepo.__enter__argsr/   c                 G  s   |    d S r   )close)r   r   rR   rR   rS   __exit__D     zRepo.__exit__c                 C  s$   z|    W d S  ty   Y d S w r   )r   r   r   rR   rR   rS   __del__G  s
   zRepo.__del__c                 C  sL   | j r"| j   tjdkrt  tjj  tjdkr$t  d S d S d S )Nwin32)	r   clear_cachesysplatformgccollectgitdbutilmmanr   rR   rR   rS   r   M  s   


	z
Repo.closerhsobjectc                 C  s   t |tr| j|jkS dS )NF)rv   r   rW   r   r   rR   rR   rS   __eq__Z  s   
zRepo.__eq__c                 C  s   |  | S r   )r   r   rR   rR   rS   __ne___  r   zRepo.__ne__intc                 C  s
   t | jS r   )hashrW   r   rR   rR   rS   __hash__b  s   
zRepo.__hash__ru   c                 C  sN   t | jd}t|d}|  tW  d    S 1 s w   Y  d S )Ndescriptionrb)r   r   rW   openreadrstripdecoder	   )r   filenamefprR   rR   rS   _get_descriptionf  s   $zRepo._get_descriptiondescrc                 C  sR   t | jd}t|d}||d t W d    d S 1 s"w   Y  d S )Nr   wb
)r   r   rW   r   writeencoder	   )r   r   r   r   rR   rR   rS   _set_descriptionk  s   "zRepo._set_descriptionzthe project's description)docc                 C     | j S )z
        :return:
            The working tree directory of our git repository.
            If this is a bare repository, ``None`` is returned.
        )rV   r   rR   rR   rS   working_tree_dirt  s   zRepo.working_tree_dirc                 C  s   | j p| jS )z
        :return:
            The git dir that holds everything except possibly HEAD, FETCH_HEAD,
            ORIG_HEAD, COMMIT_EDITMSG, index, and logs/.
        )rY   rW   r   rR   rR   rS   r   }  s   zRepo.common_dirc                 C  r   )z+:return: ``True`` if the repository is bare)r   r   rR   rR   rS   rn     s   z	Repo.bare'IterableList[Head]'c                 C  
   t | S )zA list of :class:`~git.refs.head.Head` objects representing the branch heads
        in this repo.

        :return:
            ``git.IterableList(Head, ...)``
        )r   
list_itemsr   rR   rR   rS   heads     
z
Repo.headsc                 C  r   )zAlias for heads.
        A list of :class:`~git.refs.head.Head` objects representing the branch heads
        in this repo.

        :return:
            ``git.IterableList(Head, ...)``
        )r   r   rR   rR   rS   branches     	zRepo.branches'IterableList[Reference]'c                 C  r   )zA list of :class:`~git.refs.reference.Reference` objects representing tags,
        heads and remote references.

        :return:
            ``git.IterableList(Reference, ...)``
        )r   r   r   rR   rR   rS   
references  r   zRepo.referencesc                 C  r   )zAlias for references.
        A list of :class:`~git.refs.reference.Reference` objects representing tags,
        heads and remote references.

        :return:
            ``git.IterableList(Reference, ...)``
        )r   r   rR   rR   rS   refs  r   z	Repo.refs'IndexFile'c                 C  s   t | S )a6  
        :return:
            A :class:`~git.index.base.IndexFile` representing this repository's index.

        :note:
            This property can be expensive, as the returned
            :class:`~git.index.base.IndexFile` will be reinitialized.
            It is recommended to reuse the object.
        r   r   rR   rR   rS   index     z
Repo.index'HEAD'c                 C  s
   t | dS )zq
        :return:
            :class:`~git.refs.head.HEAD` object pointing to the current head reference
        r   )r   r   rR   rR   rS   head  s   
z	Repo.head'IterableList[Remote]'c                 C  r   )zA list of :class:`~git.remote.Remote` objects allowing to access and
        manipulate remotes.

        :return:
            ``git.IterableList(Remote, ...)``
        )r   r   r   rR   rR   rS   remotes  r   zRepo.remotesoriginname'Remote'c                 C  s"   t | |}| std| |S )z:return: The remote with the specified name

        :raise ValueError:
            If no remote with such a name exists.
        zRemote named '%s' didn't exist)r   r|   
ValueError)r   r   rrR   rR   rS   remote  s   
zRepo.remote'IterableList[Submodule]'c                 C  r   )z
        :return:
            git.IterableList(Submodule, ...) of direct submodules available from the
            current head
        )r   r   r   rR   rR   rS   
submodules  s   
zRepo.submodules'Submodule'c              
   C  s4   z| j | W S  ty } ztd| |d}~ww )zx:return: The submodule with the given name

        :raise ValueError:
            If no such submodule exists.
        zDidn't find submodule named %rN)r   
IndexErrorr   )r   r   erR   rR   rS   	submodule  s   zRepo.submodulekwargsr   c                 O     t j| g|R i |S )a  Create a new submodule.

        :note:
            For a description of the applicable parameters, see the documentation of
            :meth:`Submodule.add <git.objects.submodule.base.Submodule.add>`.

        :return:
            The created submodule.
        )r   addr   r   r   rR   rR   rS   create_submodule  s   
zRepo.create_submoduleIterator[Submodule]c                 O     t | j|i |S )zAn iterator yielding Submodule instances.

        See the `~git.objects.util.Traversable` interface for a description of `args`
        and `kwargs`.

        :return:
            Iterator
        )r   traverser   rR   rR   rS   iter_submodules  s   	zRepo.iter_submodulesc                 O  r   )a(  Update the submodules, keeping the repository consistent as it will
        take the previous state into consideration.

        :note:
            For more information, please see the documentation of
            :meth:`RootModule.update <git.objects.submodule.root.RootModule.update>`.
        )r   updater   rR   rR   rS   submodule_update  s   zRepo.submodule_update'IterableList[TagReference]'c                 C  r   )zA list of :class:`~git.refs.tag.TagReference` objects that are available in
        this repo.

        :return:
            ``git.IterableList(TagReference, ...)``
        )r   r   r   rR   rR   rS   tags  r   z	Repo.tagsr   c                 C  s   |  |}t| |S )a   
        :return:
            :class:`~git.refs.tag.TagReference` object, reference pointing to a
            :class:`~git.objects.commit.Commit` or tag

        :param path:
            Path to the tag reference, e.g. ``0.1.5`` or ``tags/0.1.5``.
        )_to_full_tag_pathr   )r   r_   	full_pathrR   rR   rS   tag#  s   
	
zRepo.tagc                 C  sH   t | }|tjd r|S |tjd rtjd | S tjd | S )N/)ru   
startswithr   _common_path_default_common_defaultr   )r_   path_strrR   rR   rS   r   /  s   zRepo._to_full_tag_pathr   rG   !Union['SymbolicReference', 'str']forcelogmsgrJ   'Head'c                 C  s   t | ||||S )a  Create a new head within the repository.

        :note:
            For more documentation, please see the
            :meth:`Head.create <git.refs.head.Head.create>` method.

        :return:
            Newly created :class:`~git.refs.head.Head` Reference.
        )r   create)r   r_   rG   r   r   rR   rR   rS   create_head9  s   zRepo.create_headr   'Union[str, Head]'c                 O  r   )zDelete the given heads.

        :param kwargs:
            Additional keyword arguments to be passed to :manpage:`git-branch(1)`.
        )r   delete)r   r   r   rR   rR   rS   delete_headK  s   zRepo.delete_headrefUnion[str, 'SymbolicReference']messagec                 K  s   t j| ||||fi |S )a  Create a new tag reference.

        :note:
            For more documentation, please see the
            :meth:`TagReference.create <git.refs.tag.TagReference.create>` method.

        :return:
            :class:`~git.refs.tag.TagReference` object
        )r   r   )r   r_   r  r  r   r   rR   rR   rS   
create_tagS  s   zRepo.create_tagr   c                 G  s   t j| g|R  S )z Delete the given tag references.)r   r  )r   r   rR   rR   rS   
delete_tagf  s   zRepo.delete_tagurlr   c                 K  s   t j| ||fi |S )zCreate a new remote.

        For more information, please see the documentation of the
        :meth:`Remote.create <git.remote.Remote.create>` method.

        :return:
            :class:`~git.remote.Remote` reference
        )r   r   )r   r   r  r   rR   rR   rS   create_remotej  s   	zRepo.create_remoter   c                 C  s   t | |S )zDelete the given remote.)r   remove)r   r   rR   rR   rS   delete_remoteu  s   zRepo.delete_remoter*   c              	   C  s   |d u r| j }tjdkr|dkrd}|dkrdS |dkr:tjdp,ttjddd	}tt	t|d
dS |dkrFtt	dS |dkr\| j
pN|}|sSttt|dS t|td| d S )Nr   rZ   r\   z/etc/gitconfigr[   XDG_CONFIG_HOMEHOME~z.configr   configz~/.gitconfigr]   zInvalid configuration level: )rW   r   r   rq   r~   r   r   r   r   
expanduserrY   NotADirectoryErrorr.   r   )r   r^   rW   config_homerepo_dirrR   rR   rS   _get_config_pathy  s(   "
zRepo._get_config_pathOptional[Lit_config_levels]r   c                 C  s   | j |dS )a  
        :return:
            :class:`~git.config.GitConfigParser` allowing to read the full git
            configuration, but not to write it.

            The configuration will include values from the system, user and repository
            configuration files.

        :param config_level:
            For possible values, see the :meth:`config_writer` method. If ``None``, all
            applicable levels will be used. Specify a level in case you know which file
            you wish to read to prevent reading multiple files.

        :note:
            On Windows, system configuration cannot currently be read as the path is
            unknown, instead the global path will be used.
        )r^   )r   r   r^   rR   rR   rS   r     s   zRepo.config_readerc                   s<   |d u r fddj D }n| g}t|ddS )Nc                   s(   g | ]}t t|rt t| qS rR   )r>   r*   r  ).0frW   r   rR   rS   
<listcomp>  s    z'Repo._config_reader.<locals>.<listcomp>T)	read_onlyrepo)r^   r  r   )r   r^   rW   filesrR   r  rS   r     s   zRepo._config_readerr]   c                 C  s   t | |d| ddS )au  
        :return:
            A :class:`~git.config.GitConfigParser` allowing to write values of the
            specified configuration file level. Config writers should be retrieved, used
            to change the configuration, and written right away as they will lock the
            configuration file in question and prevent other's to write it.

        :param config_level:
            One of the following values:

            * ``"system"`` = system wide configuration file
            * ``"global"`` = user level configuration file
            * ``"`repository"`` = configuration file for this repository only
        F)r  r  merge_includes)r   r  r  rR   rR   rS   config_writer  s   zRepo.config_writerrevUnion[str, Commit_ish, None]r   c                 C  s"   |du r| j jS | t|d S )zThe :class:`~git.objects.commit.Commit` object for the specified revision.

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

        :return:
            :class:`~git.objects.commit.Commit`
        Nz^0)r   rG   r&   ru   r   r   rR   rR   rS   rG     s   	zRepo.commitIterator['Tree']c                 O  s   dd | j |i |D S )z:return: Iterator yielding :class:`~git.objects.tree.Tree` objects

        :note:
            Accepts all arguments known to the :meth:`iter_commits` method.
        c                 s  s    | ]}|j V  qd S r   )tree)r  crR   rR   rS   	<genexpr>  s    z"Repo.iter_trees.<locals>.<genexpr>)iter_commitsr   rR   rR   rS   
iter_trees  s   zRepo.iter_treesUnion[Tree_ish, str, None]'Tree'c                 C  s$   |du r	| j jjS | t|d S )a&  The :class:`~git.objects.tree.Tree` object for the given tree-ish revision.

        Examples::

              repo.tree(repo.heads[0])

        :param rev:
            A revision pointing to a Treeish (being a commit or tree).

        :return:
            :class:`~git.objects.tree.Tree`

        :note:
            If you need a non-root level tree, find it by iterating the root tree.
            Otherwise it cannot know about its path relative to the repository root and
            subsequent operations might have unexpected results.
        Nz^{tree})r   rG   r$  r&   ru   r"  rR   rR   rS   r$    s   
z	Repo.tree-Union[str, Commit, 'SymbolicReference', None]paths#Union[PathLike, Sequence[PathLike]]Iterator[Commit]c                 K  s&   |du r| j j}tj| ||fi |S )a*  An iterator of :class:`~git.objects.commit.Commit` objects representing the
        history of a given ref/commit.

        :param rev:
            Revision specifier, see :manpage:`git-rev-parse(1)` for viable options.
            If ``None``, the active branch will be used.

        :param paths:
            An optional path or a list of paths. If set, only commits that include the
            path or paths will be returned.

        :param kwargs:
            Arguments to be passed to :manpage:`git-rev-list(1)`.
            Common ones are ``max_count`` and ``skip``.

        :note:
            To receive only commits between two named revisions, use the
            ``"revA...revB"`` revision specifier.

        :return:
            Iterator of :class:`~git.objects.commit.Commit` objects
        N)r   rG   r   
iter_items)r   r   r,  r   rR   rR   rS   r'    s   zRepo.iter_commitsr,   List[Commit]c              
   O  s   t |dk rtdt | g }z| jj|i | }W n ty7 } z|jdkr+ |W  Y d}~S d}~ww |D ]
}|| | q:|S )a  Find the closest common ancestor for the given revision
        (:class:`~git.objects.commit.Commit`\s, :class:`~git.refs.tag.Tag`\s,
        :class:`~git.refs.reference.Reference`\s, etc.).

        :param rev:
            At least two revs to find the common ancestor for.

        :param kwargs:
            Additional arguments to be passed to the ``repo.git.merge_base()`` command
            which does all the work.

        :return:
            A list of :class:`~git.objects.commit.Commit` objects. If ``--all`` was
            not passed as a keyword argument, the list will have at max one
            :class:`~git.objects.commit.Commit`, or is empty if no common merge base
            exists.

        :raise ValueError:
            If fewer than two revisions are provided.
           z-Please specify at least two revs, got only %i   N)	lenr   r   
merge_baser   r   statusappendrG   )r   r   r   reslineserrlinerR   rR   rS   r4    s   
	zRepo.merge_baseancestor_revc              
   C  sL   z| j j||dd W dS  ty% } z|jdkr W Y d}~dS  d}~ww )a  Check if a commit is an ancestor of another.

        :param ancestor_rev:
            Rev which should be an ancestor.

        :param rev:
            Rev to test against `ancestor_rev`.

        :return:
            ``True`` if `ancestor_rev` is an ancestor to `rev`.
        T)is_ancestorr"   NF)r   r4  r   r5  )r   r;  r   r9  rR   rR   rS   r<  B  s   
zRepo.is_ancestorshaobject_typeUnion[str, None]c                 C  sp   z(| j |}| j |}|r&|j| krW dS td|j | W dS W dS  ty7   td Y dS w )NTzQCommit hash points to an object of type '%s'. Requested were objects of type '%s'FzCommit hash is invalid.)	r   partial_to_complete_sha_hexinfotyper   _loggerdebugr   r   )r   r=  r>  complete_shaobject_inforR   rR   rS   is_valid_objectV  s"   
zRepo.is_valid_objectc                 C  s    | j rt| j | j}t|S r   )rW   r   r   DAEMON_EXPORT_FILEr|   )r   r   rR   rR   rS   _get_daemon_exportj  s   
zRepo._get_daemon_exportvaluec                 C  sR   | j rt| j | j}t|}|r|st| d S |s%|r't| d S d S d S r   )rW   r   r   rH  r|   r'   rq   unlink)r   rJ  r   
fileexistsrR   rR   rS   _set_daemon_exporto  s   
zRepo._set_daemon_exportz.If True, git-daemon may export this repository	List[str]c                 C  sj   | j rt| j ddd}t|r3t|d}| t}W d   n1 s(w   Y  | 	 S g S )zThe list of alternates for this repo from which objects can be retrieved.

        :return:
            List of strings being pathnames of alternates
        rp   rA  
alternatesr   N)
rW   r   r   r|   r   r   r   r	   r   r   )r   alternates_pathr  altsrR   rR   rS   _get_alternates  s   
zRepo._get_alternatesrQ  c                 C  sx   t | jddd}|st |rt| dS dS t|d}|d|t	 W d   dS 1 s5w   Y  dS )a  Set the alternates.

        :param alts:
            The array of string paths representing the alternates at which git should
            look for objects, i.e. ``/home/user/repo/.git/objects``.

        :raise git.exc.NoSuchPathError:

        :note:
            The method does not check for the existence of the paths in `alts`, as the
            caller is responsible.
        rp   rA  rO  r   r   N)
r   r   r   isfilerq   r
  r   r   r   r	   )r   rQ  rP  r  rR   rR   rS   _set_alternates  s   
"zRepo._set_alternateszPRetrieve a list of alternates paths or set a list paths to be used as alternatesr   working_treeuntracked_filesr   c                 C  s   | j rdS g d}|s|d |r|dt|g |r2t| jjr2t| j	j
dg|R  r2dS |r>t| j	j
| r>dS |rLt| j|| drLdS dS )a  
        :return:
            ``True`` if the repository is considered dirty. By default it will react
            like a :manpage:`git-status(1)` without untracked files, hence it is dirty
            if the index or the working copy have changes.
        F)z--abbrev=40z--full-indexz--rawz--ignore-submodules--z--cachedT)ignore_submodules)r   r6  extendru   r   rS  r   r_   r3  r   diff_get_untracked_files)r   r   rU  rV  r   r_   default_argsrR   rR   rS   is_dirty  s"   
&zRepo.is_dirtyc                 C  s   |   S )a  
        :return:
            list(str,...)

            Files currently untracked as they have not been staged yet. Paths are
            relative to the current working directory of the git command.

        :note:
            Ignored files will not appear here, i.e. files mentioned in ``.gitignore``.

        :note:
            This property is expensive, as no cache is involved. To process the result,
            please consider caching it yourself.
        )r[  r   rR   rR   rS   rV    s   zRepo.untracked_filesc                 O  s   | j j|dddd|}d}g }|jD ]A}|t}||s!q|t|d  d}|d |d   kr:dkrPn n|dd }|d	d
dt}|	| qt
| |S )NT)	porcelainrV  
as_processz?? r   r   "r"   asciiunicode_escapelatin1)r   r5  stdoutr   r	   r   r3  r   r   r6  r   )r   r   r   procprefixrV  r:  r   rR   rR   rS   r[    s   


 zRepo._get_untracked_filesc              
   G  s`   z| j j| }W n ty" } z|jdkrg W  Y d}~S  d}~ww |dddddS )a   Checks if paths are ignored via ``.gitignore``.

        This does so using the :manpage:`git-check-ignore(1)` method.

        :param paths:
            List of paths to check whether they are ignored or not.

        :return:
            Subset of those paths which are ignored
        r"   Nz\\\ra  rX   r   )r   check_ignorer   r5  replacer   )r   r,  rf  r9  rR   rR   rS   ignored  s   
	zRepo.ignoredr   c                 C  s   | j jS )zThe name of the currently active branch.

        :raise TypeError:
            If HEAD is detached.

        :return:
            :class:`~git.refs.head.Head` to the active branch
        )r   	referencer   rR   rR   rS   active_branch  r   zRepo.active_branchstr | HEAD | NonefileIterator['BlameEntry']c                 k  s   | j j|d|fdddd|}i }dd |dD }	 zt|}W n
 ty.   Y dS w | }|\}	}
}}t|}t|}t|
}|	|vri }	 zt|}W n
 ty\   Y dS w |d	krbqK|d
d\}}|||< |dkru|}nqLt| t|	tt	|d t	|d 
ddt|d tt	|d t	|d 
ddt|d d}|||	< n"	 zt|}W n
 ty   Y dS w |d
d\}}|dkr|}nqt||	 t||| t	|t||| V  q)aB  Iterator for blame information for the given file at the given revision.

        Unlike :meth:`blame`, this does not return the actual file's contents, only a
        stream of :class:`BlameEntry` tuples.

        :param rev:
            Revision specifier. If ``None``, the blame will include all the latest
            uncommitted changes. Otherwise, anything successfully parsed by
            :manpage:`git-rev-parse(1)` is a valid option.

        :return:
            Lazy iterator of :class:`BlameEntry` tuples, where the commit indicates the
            commit to blame for the line, and range indicates a span of line numbers in
            the resulting file.

        If you combine all line number ranges outputted by this command, you should get
        a continuous range spanning all line numbers in the file.
        rW  TF)pincrementalstdout_as_stringc                 s  s    | ]}|r|V  qd S r   rR   )r  r:  rR   rR   rS   r&  5  s    z)Repo.blame_incremental.<locals>.<genexpr>   
Ns   boundary    r"   s   filenames   authors   author-mail   <   >s   author-times	   committers   committer-mails   committer-timeauthorauthored_date	committercommitted_date)r   blamer   nextStopIterationr   r   r    r   r
   lstripr   rF   rH   )r   r   ro  r   datacommitsstreamr:  
split_linehexshaorig_lineno_blineno_bnum_lines_blineno	num_linesorig_linenopropsr   rJ  orig_filenamer%  rR   rR   rS   blame_incremental  s    




zRepo.blame_incrementalUnion[str, HEAD, None]rr  rev_optsOptional[List[str]]KList[List[Commit | List[str | bytes] | None]] | Iterator[BlameEntry] | Nonec                 K  s  |r| j ||fi |S |pg }| jj|g|d|R ddd|}i }g }G dd dtdd}	i }
d}||D ]K}z	| t}W n tyV   d}g }d}Y nw | j	
|d	}|d
 }d}| j|r|d 
d}t|dkrd|i}
|dg g q;|
d |krd|i}
|||g g q;| j|}|r|d
}|dkr|dr|d |
d< q;|drt|d |
d< q;||kr|d |
d< q;|dkr|dr|d |
d< q;|drt|d |
d< q;||kr|d |
d< q;|dr|d |
d< q;|dr|d |
d< q;|dkr|
r|
d }||}|du rSt| t|t|
d  d|
d  |
d t|
d  d|
d  |
d d}|||< ||d d
< |d d	 dur|sx|ru|d
 dkru|d	d }|}n|}|d d	 | d|i}
q;|S )a  The blame information for the given file at the given revision.

        :param rev:
            Revision specifier. If ``None``, the blame will include all the latest
            uncommitted changes. Otherwise, anything successfully parsed by
            :manpage:`git-rev-parse(1)` is a valid option.

        :return:
            list: [git.Commit, list: [<line>]]

            A list of lists associating a :class:`~git.objects.commit.Commit` object
            with a list of lines that changed within the given commit. The
            :class:`~git.objects.commit.Commit` objects will be given in order of
            appearance.
        rW  TF)rq  rs  c                   @  s^   e Zd ZU ded< ded< ded< ded< ded< ded< ded	< ded
< ded< ded< dS )zRepo.blame.<locals>.InfoTDru   r=  idr   summaryry  author_emailr   author_dater{  committer_emailcommitter_dateNrM   rR   rR   rR   rS   InfoTD  s   
 r  )totalrX   r"   r   r`      r  Nry  z-mailr  z-timer  r{  r  r  r   r  rx  	)r  r   r}  r@   r   r   r   r	   UnicodeDecodeErrorre_whitespacer   re_hexsha_onlyrx   r3  r6  r   re_author_committer_startgroupendswithr   r   r   r    r   _from_string)r   r   ro  rr  r  r   r  r  blamesr  rA  keepends
line_bytesline_str	firstpartparts	is_binarydigitsmroler=  r%  r:  rR   rR   rS   r}  z  s   (









z
Repo.blameUnion[PathLike, None]mkdirType[GitCmdObjectDB]c                 K  sR   |rt ||}|r|rt|st|d | |}|jdi | | ||dS )a  Initialize a git repository at the given path if specified.

        :param path:
            The full path to the repo (traditionally ends with ``/<name>.git``). Or
            ``None``, in which case the repository will be created in the current
            working directory.

        :param mkdir:
            If specified, will create the repository directory if it doesn't already
            exist. Creates the directory with a mode=0755.
            Only effective if a path is explicitly given.

        :param odbt:
            Object DataBase type - a type which is constructed by providing the
            directory containing the database objects, i.e. ``.git/objects``. It will be
            used to access all object data.

        :param expand_vars:
            If specified, environment variables will not be escaped. This can lead to
            information disclosure, allowing attackers to access the contents of
            environment variables.

        :param kwargs:
            Keyword arguments serving as additional options to the
            :manpage:`git-init(1)` command.

        :return:
            :class:`Repo` (the newly created repo)
        i  r`   NrR   )r   r   r|   rq   makedirsr   init)clsr_   r  r`   rd   r   r   rR   rR   rS   r    s   &

z	Repo.initr   'Git'odb_default_typeprogressPUnion['RemoteProgress', 'UpdateProgress', Callable[..., 'RemoteProgress'], None]multi_optionsallow_unsafe_protocolsallow_unsafe_optionsc	                 K  s  |	 d|}
t|tst|}t rd|	v rt|n|}|	d}|r,t||	d< d }|r8td	|}|sAt
t| |sOtjt|	 | jd |s[|r[tj|| jd |j|dtt||fdddddt|	||}|rt|d t| td	d
 n| \}}t|dd}t|}td|| t||d t|s|jd urt	|j|n|}| ||
d}|jjdi |  |j r|j d j!}|"dt|j d j# W d    |S 1 sw   Y  |S )Nr`   rn   separate_git_dirr  )optionsunsafe_optionsrW  T)with_extended_outputr_  vuniversal_newlinesF)decode_streamsr   rX   zCmd(%s)'s unused stdout: %s)stderrr  r   r  rR   )$poprv   ru   r   rt   
polish_urlr   shlexr   r   check_unsafe_protocolscheck_unsafe_optionslistkeysunsafe_git_clone_optionscloner   r   r   new_message_handlerr   communicategetattrr!   rC  rD  r   isabs_working_dirr   update_environmentenvironmentr   r  	set_valuer  )r  r   r  r_   r  r  r  r  r  r   r`   
clone_pathsep_dirmultirf  re  r  cmdliner  writerrR   rR   rS   _cloneC  sj   


	


zRepo._cloneOptional[CallableProgress]c                 K  s,   | j | j| j|t| j||f||d|S )a  Create a clone from this repository.

        :param path:
            The full path of the new repo (traditionally ends with ``./<name>.git``).

        :param progress:
            See :meth:`Remote.push <git.remote.Remote.push>`.

        :param multi_options:
            A list of :manpage:`git-clone(1)` options that can be provided multiple
            times.

            One option per list item which is passed exactly as specified to clone.
            For example::

                [
                    "--config core.filemode=false",
                    "--config core.ignorecase",
                    "--recurse-submodule=repo1_path",
                    "--recurse-submodule=repo2_path",
                ]

        :param allow_unsafe_protocols:
            Allow unsafe protocols to be used, like ``ext``.

        :param allow_unsafe_options:
            Allow unsafe options to be used, like ``--upload-pack``.

        :param kwargs:
            * ``odbt`` = ObjectDatabase Type, allowing to determine the object database
              implementation used by the returned :class:`Repo` instance.
            * All remaining keyword arguments are given to the :manpage:`git-clone(1)`
              command.

        :return:
            :class:`Repo` (the newly cloned repo)
        r  r  )r  r   r   rB  r   )r   r_   r  r  r  r  r   rR   rR   rS   r    s   .	z
Repo.cloneto_pathr(   envOptional[Mapping[str, str]]c           
      K  sH   |  t }	|dur|	jdi | | j|	||t||f||d|S )a  Create a clone from the given URL.

        :param url:
            Valid git url, see: https://git-scm.com/docs/git-clone#URLS

        :param to_path:
            Path to which the repository should be cloned to.

        :param progress:
            See :meth:`Remote.push <git.remote.Remote.push>`.

        :param env:
            Optional dictionary containing the desired environment variables.

            Note: Provided variables will be used to update the execution environment
            for ``git``. If some variable is not specified in `env` and is defined in
            :attr:`os.environ`, value from :attr:`os.environ` will be used. If you want
            to unset some variable, consider providing empty string as its value.

        :param multi_options:
            See the :meth:`clone` method.

        :param allow_unsafe_protocols:
            Allow unsafe protocols to be used, like ``ext``.

        :param allow_unsafe_options:
            Allow unsafe options to be used, like ``--upload-pack``.

        :param kwargs:
            See the :meth:`clone` method.

        :return:
            :class:`Repo` instance pointing to the cloned directory.
        Nr  rR   )r   rq   rs   r  r  r   )
r  r  r  r  r  r  r  r  r   r   rR   rR   rS   
clone_from  s    .	zRepo.clone_fromostreamUnion[TextIO, BinaryIO]treeishrg  c                 K  s   |du r| j j}|rd|vr||d< ||d< |dg }ttttt ttdf f |}t|t	t
fs6|g}| jjd|g|R i | | S )a  Archive the tree at the given revision.

        :param ostream:
            File-compatible stream object to which the archive will be written as bytes.

        :param treeish:
            The treeish name/id, defaults to active branch.

        :param prefix:
            The optional prefix to prepend to each filename in the archive.

        :param kwargs:
            Additional arguments passed to :manpage:`git-archive(1)`:

            * Use the ``format`` argument to define the kind of format. Use specialized
              ostreams to write any format supported by Python.
            * You may specify the special ``path`` keyword, which may either be a
              repository-relative path to a directory or file to place into the archive,
              or a list or tuple of multiple paths.

        :raise git.exc.GitCommandError:
            If something went wrong.

        :return:
            self
        Nrg  output_streamr_   .rW  )r   rG   r  r>   r=   r+   r4   r;   rv   tupler  r   archive)r   r  r  rg  r   r_   rR   rR   rS   r    s   ! zRepo.archivec                 C  s(   | j rdS | jrtt| jdS dS )ai  
        :return:
            True if our :attr:`git_dir` is not at the root of our
            :attr:`working_tree_dir`, but a ``.git`` file with a platform-agnostic
            symbolic link. Our :attr:`git_dir` will be wherever the ``.git`` file points
            to.

        :note:
            Bare repositories will always return ``False`` here.
        Frm   )rn   r   r   rS  r   r   rR   rR   rS   has_separate_working_tree?  s
   zRepo.has_separate_working_treec                 C  s   | j }d|j|j| jf S )Nz
<%s.%s %r>)	__class__rO   rN   rW   )r   clazzrR   rR   rS   __repr__S  s   zRepo.__repr__Commit | Nonec                 C  sb   | j r
t| j d}t|sdS t|d}|  }W d   n1 s'w   Y  | |S )z
        :return:
            The commit which is currently being replayed while rebasing.

            ``None`` if we are not currently rebasing.
        REBASE_HEADNrt)rW   r   r   rS  r   readliner   rG   )r   rebase_head_filer  contentrR   rR   rS   currently_rebasing_onW  s   

zRepo.currently_rebasing_on)
r_   rU   r`   ra   rb   rc   rd   rc   re   rf   )re   r   )r   r/   re   rf   )re   rf   )r   r   re   rc   )re   r   )re   ru   )r   ru   re   rf   )re   rU   )re   r+   )re   rc   )re   r   )re   r   )re   r   )re   r   )re   r   )r   )r   ru   re   r   )re   r   )r   ru   re   r   )r   r/   r   r/   re   r   )r   r/   r   r/   re   r   )re   r   )r_   r+   re   r   )r_   r+   re   ru   )r   FN)
r_   r+   rG   r   r   rc   r   rJ   re   r   )r   r   r   r/   re   rf   )r   NF)r_   r+   r  r  r  rJ   r   rc   r   r/   re   r   )r   r   re   rf   )r   ru   r  ru   r   r/   re   r   )r   r   re   ru   r   )r^   r*   rW   rU   re   ru   )r^   r  re   r   )NN)r^   r  rW   rU   re   r   )r]   )r^   r*   re   r   )r   r!  re   r   )r   r/   r   r/   re   r#  )r   r)  re   r*  )NrX   )r   r+  r,  r-  r   r/   re   r.  )r   r,   r   r/   re   r0  )r;  r   r   r   re   rc   )r=  ru   r>  r?  re   rc   )rJ  r   re   rf   )re   rN  )rQ  rN  re   rf   )TTFTN)r   rc   rU  rc   rV  rc   r   rc   r_   rU   re   rc   )r   r/   r   r/   re   rN  )r,  r+   re   rN  )re   r   )r   rn  ro  ru   r   r/   re   rp  )FN)r   r  ro  ru   rr  rc   r  r  r   r/   re   r  )r_   r  r  rc   r`   r  rd   rc   r   r/   re   r   )NNFF)r   r  r  r+   r_   r+   r  r  r  r  r  r  r  rc   r  rc   r   r/   re   r   )r_   r+   r  r  r  r  r  rc   r  rc   r   r/   re   r   )NNNFF)r  r+   r  r+   r  r(   r  r  r  r  r  rc   r  rc   r   r/   re   r   )
r  r  r  rJ   rg  rJ   r   r/   re   r   )re   r  )_rN   rO   rP   __doc__rH  r>   r   rQ   rV   rY   rw   compiler  r  re_hexsha_shortenedry   r  re_tab_full_liner  r^   r   r   r   r   r   r   r   r   r   r   r   r   r   propertyr   r   r   rn   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r   r  r  r  r	  r  r  r   r   r  rG   r(  r$  r'  r4  r<  rG  rI  rM  daemon_exportrR  rT  rO  r]  rV  r[  rk  rm  r  r}  classmethodr  r  r  r  r  r  r&   r  r  rR   rR   rR   rS   r   i   sH  
 






 	
	
		!+	)` /Y:?.)e
__future__r   __all__r   loggingrq   os.pathr_   r   pathlibr   rw   r  r   rz   r   gitdb.db.looser   	gitdb.excr   git.cmdr   r   
git.compatr	   r
   
git.configr   git.dbr   git.excr   r   r   	git.indexr   git.objectsr   r   r   git.refsr   r   r   r   
git.remoter   r   r   git.utilr   r   r   r   r    r!   funr#   r$   r%   r&   r'   	git.typesr(   r)   r*   r+   r,   r-   r.   typingr/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   git.objects.submodule.baserB   git.refs.symbolicrC   rD   rE   	getLoggerrN   rC  rF   r   rR   rR   rR   rS   <module>   sJ    	$
H	
