a
    ñ»jÈJ  ã                   @  s  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	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mZ d dlmZ d dlmZmZmZmZmZmZmZ ejj Z ejj!Z!e "e#¡Z$e %d	¡Z&e %d
¡Z'e %dej(¡Z)dddœdd„Z*G dd„ deƒZ+e ,e+¡ dS )é    )ÚannotationsN)Úreplace)ÚAny)Ú
BadCommandÚInstallationError)Ú
HiddenTextÚdisplay_pathÚhide_url)Úmake_command)ÚAuthInfoÚRemoteNotFoundErrorÚRemoteNotValidErrorÚ
RevOptionsÚVersionControlÚ(find_path_to_project_root_from_repo_rootÚvcsz(^git version (\d+)\.(\d+)(?:\.(\d+))?.*$z^[a-fA-F0-9]{40}$a/  ^
    # Optional user, e.g. 'git@'
    (\w+@)?
    # Server, e.g. 'github.com'.
    ([^/:]+):
    # The server-side path. e.g. 'user/project.git'. Must start with an
    # alphanumeric character so as not to be confusable with a Windows paths
    # like 'C:/foo/bar' or 'C:\foo\bar'.
    (\w[^:]*)
    $ÚstrÚbool)ÚshaÚreturnc                 C  s   t t | ¡ƒS ©N)r   Ú
HASH_REGEXÚmatch)r   © r   ú;E:\soccer\ml_env\Lib\site-packages\pip/_internal/vcs/git.pyÚlooks_like_hash:   s    r   c                      sð  e Zd ZdZdZdZdZdZdZe	ddd	œd
d„ƒZ
eddddœ‡ fdd„ƒZddddœdd„Zddœdd„Zedddœdd„ƒZeddddœdd„ƒZeddddœd d!„ƒZedd"d#d#d$œd%d&„ƒZedddd'œd(d)„ƒZdd"d#d*d+d,œd-d.„ZdLdd"d#d*d+d,œd0d1„ZdMdd"d#d*d+d,œd2d3„Zedddœd4d5„ƒZe	ddd6œd7d8„ƒZedddd9œd:d;„ƒZedNdddd9œd=d>„ƒZedddœd?d@„ƒZeddAd6œ‡ fdBdC„ƒZedOdd*d+dDœdEdF„ƒZedddœ‡ fdGdH„ƒZe	dddIœdJdK„ƒZ‡  Z S )PÚGitÚgitz.gitÚclone)zgit+httpz	git+httpszgit+sshzgit+gitzgit+file)ÚGIT_DIRÚGIT_WORK_TREEÚHEADr   z	list[str])Úrevr   c                 C  s   | gS r   r   ©r"   r   r   r   Úget_base_rev_argsN   s    zGit.get_base_rev_argsr   )ÚargsÚkwargsr   c                   sB   t j d¡r0| di ¡}d|d< d|d< ||d< tƒ j|i |¤ŽS )NÚPIP_NO_INPUTÚextra_environÚ0ZGIT_TERMINAL_PROMPTzssh -oBatchMode=yesZGIT_SSH_COMMAND)ÚosÚenvironÚgetÚsuperÚrun_command)Úclsr%   r&   r(   ©Ú	__class__r   r   r.   R   s    zGit.run_commandr   )ÚurlÚdestr   c                 C  sJ   |   t|ƒ¡\}}|jsdS |  ||j¡s.dS t|  ||j¡d ƒ}| S )NFr   )Úget_url_rev_optionsr	   r"   Úis_commit_id_equalr   Úget_revision_sha)Úselfr2   r3   Ú_Úrev_optionsÚis_tag_or_branchr   r   r   Úis_immutable_rev_checkout[   s    zGit.is_immutable_rev_checkoutztuple[int, ...])r   c                 C  sN   | j dgdddd�}t |¡}|s2t d|¡ dS t| d¡ƒt| d	¡ƒfS )
NÚversionzgit versionFT)Úcommand_descÚshow_stdoutÚstdout_onlyzCan't parse git version: %sr   é   é   )r.   ÚGIT_VERSION_REGEXr   ÚloggerÚwarningÚintÚgroup)r7   r<   r   r   r   r   Úget_git_versioni   s    ü
zGit.get_git_versionz
str | None)Úlocationr   c                 C  sB   g d¢}| j |ddd|d�}| ¡ }| d¡r>|tdƒd… S dS )zl
        Return the current branch, or None if HEAD isn't at a branch
        (e.g. detached HEAD).
        )zsymbolic-refú-qr!   ©r@   FT©Úextra_ok_returncodesr>   r?   Úcwdzrefs/heads/N)r.   ÚstripÚ
startswithÚlen)r/   rH   r%   ÚoutputÚrefr   r   r   Úget_current_branchv   s    
û
zGit.get_current_branchztuple[str | None, bool])r3   r"   r   c              	   C  sÀ   | j d|g|dddd�}i }| ¡  d¡D ]T}| d¡}|s>q*z|jdd	d
�\}}W n  tyt   td|›�ƒ‚Y n0 |||< q*d|› �}d|› �}	| |¡}
|
dur®|
dfS | |	¡}
|
dfS )zö
        Return (sha_or_none, is_branch), where sha_or_none is a commit hash
        if the revision names a remote branch or tag, otherwise None.

        Args:
          dest: the repository directory.
          rev: the revision name.
        zshow-refFTÚignore)rM   r>   r?   Úon_returncodeÚ
úú rA   )Úmaxsplitzunexpected show-ref line: zrefs/remotes/origin/z
refs/tags/N)r.   rN   ÚsplitÚrstripÚ
ValueErrorr,   )r/   r3   r"   rQ   ÚrefsÚlineÚref_shaÚref_nameÚ
branch_refÚtag_refr   r   r   r   r6   �   s0    û





zGit.get_revision_shac                 C  s.   |  d¡rdS t|ƒsdS |  ||¡r*dS dS )a$  
        Return true if rev is a ref or is a commit that we don't have locally.

        Branches and tags are not considered in this method because they are
        assumed to be always available locally (which is a normal outcome of
        ``git clone`` and ``git fetch --tags``).
        zrefs/TF)rO   r   Ú
has_commit)r/   r3   r"   r   r   r   Ú_should_fetch½   s    	
zGit._should_fetchr   r   )r3   r2   r9   r   c                 C  s¨   |j }|dusJ ‚|  ||¡\}}|durL| |¡}t||r@|ndd�}|S t|ƒs`t d|¡ |  ||¡sp|S | jt	dd|| 
¡ ƒ|d� | j|dd�}| |¡}|S )	zµ
        Resolve a revision to a new RevOptions object with the SHA1 of the
        branch, tag, or ref if found.

        Args:
          rev_options: a RevOptions object.
        N)Úbranch_namez:Did not find branch or tag '%s', assuming revision or ref.ÚfetchrI   ©rM   Ú
FETCH_HEADr#   )Úarg_revr6   Úmake_newr   r   rC   Úinford   r.   r
   Úto_argsÚget_revision)r/   r3   r2   r9   r"   r   Ú	is_branchr   r   r   Úresolve_revisionÔ   s*    
þþ
zGit.resolve_revision)r3   Únamer   c                 C  s   |sdS |   |¡|kS )z§
        Return whether the current commit hash equals the given name.

        Args:
          dest: the repository directory.
          name: a string name.
        F)rm   )r/   r3   rp   r   r   r   r5     s    	zGit.is_commit_id_equalrE   ÚNone)r3   r2   r9   Ú	verbosityr   c                 C  s\  |  ¡ }t d||t|ƒ¡ |dkr*d}n|dkr8d}nd}|  ¡ dkrj|  tdd	g|¢|‘|‘R Ž ¡ n|  tdg|¢|‘|‘R Ž ¡ |j�r&|  |||¡}t	|d
d ƒ}t 
d||¡ |d u rî|  ||j¡sìtdd| ¡ ƒ}| j||d� n6|  |¡|k�r:d|› �}	dd|d|	g}| j||d� n|  |¡}
| |
¡}t d||j¡ | j||d� d S )NzCloning %s%s to %sr   )z--quietr@   r   )z	--verbosez
--progress)rA   é   r   z--filter=blob:nonere   zRev options %s, branch_name %sÚcheckoutrI   rg   zorigin/z-bz--trackzResolved %s to commit %s©rr   )Ú
to_displayrC   rk   r   rG   r.   r
   r"   ro   ÚgetattrÚdebugr5   rl   rS   rm   rj   Úupdate_submodules)r7   r3   r2   r9   rr   Úrev_displayÚflagsre   Úcmd_argsÚtrack_branchr   r   r   r   Ú	fetch_new  s\    þýüûÿ
ý
û

zGit.fetch_newr   c                 C  sd   | j tdd|ƒ|d� g }|dkr,| d¡ tdg|¢| ¡ ‘R Ž }| j ||d� | j||d� d S )NÚconfigzremote.origin.urlrg   r   rI   rt   ru   )r.   r
   Úappendrl   ry   ©r7   r3   r2   r9   rr   Úextra_flagsr|   r   r   r   ÚswitchP  s    
þ
z
Git.switchc                 C  s–   g }|dkr|  d¡ |  ¡ dkr:| jddg|¢|d� n| jdg|¢|d� |  |||¡}tddg|¢| ¡ ‘R Ž }| j||d� | j||d	� d S )
Nr   rI   )r@   é	   rf   z--tagsrg   Úresetz--hardru   )r€   rG   r.   ro   r
   rl   ry   r�   r   r   r   Úupdatef  s"    
þýüz
Git.updatec                 C  s|   | j g d¢ddd|d�}| ¡ }z|d }W n tyB   t‚Y n0 |D ]}| d¡rH|} q`qH| d¡d	 }|  | ¡ ¡S )
z¢
        Return URL of the first remote encountered.

        Raises RemoteNotFoundError if the repository does not have a remote
        url configured.
        )r   z--get-regexpzremote\..*\.urlrJ   FTrK   r   zremote.origin.url rX   r@   )r.   Ú
splitlinesÚ
IndexErrorr   rO   rZ   Ú_git_remote_to_pip_urlrN   )r/   rH   ÚstdoutÚremotesÚfound_remoteÚremoter2   r   r   r   Úget_remote_url„  s$    
û

zGit.get_remote_url)r2   r   c                 C  sN   t  d| ¡r| S tj | ¡r*t | ¡ ¡ S t | ¡}|rB| 	d¡S t
| ƒ‚dS )a8  
        Convert a remote url from what git uses to what pip accepts.

        There are 3 legal forms **url** may take:

            1. A fully qualified url: ssh://git@example.com/foo/bar.git
            2. A local project.git folder: /path/to/bare/repository.git
            3. SCP shorthand for form 1: git@example.com:foo/bar.git

        Form 1 is output as-is. Form 2 must be converted to URI and form 3 must
        be converted to form 1.

        See the corresponding test test_git_remote_url_to_pip() for examples of
        sample inputs/outputs.
        z\w+://zssh://\1\2/\3N)Úrer   r*   ÚpathÚexistsÚpathlibÚPurePathÚas_uriÚ	SCP_REGEXÚexpandr   )r2   Ú	scp_matchr   r   r   r‰   ¢  s    

zGit._git_remote_to_pip_url)rH   r"   r   c                 C  s>   z | j dddd| g|dd� W n ty4   Y dS 0 dS dS )	zU
        Check if rev is a commit that is available in the local repository.
        ú	rev-parserI   z--verifyzsha^F)rM   Úlog_failed_cmdTN)r.   r   )r/   rH   r"   r   r   r   rc   Á  s    ý
zGit.has_commitNc                 C  s*   |d u rd}| j d|gdd|d�}| ¡ S )Nr!   r˜   FT©r>   r?   rM   )r.   rN   )r/   rH   r"   Úcurrent_revr   r   r   rm   Ñ  s    üzGit.get_revisionc                 C  sT   | j ddgdd|d� ¡ }tj |¡s4tj ||¡}tj tj |d¡¡}t||ƒS )z‘
        Return the path to Python project root, relative to the repo root.
        Return None if the project root is in the repo root.
        r˜   z	--git-dirFTrš   z..)r.   rN   r*   r�   ÚisabsÚjoinÚabspathr   )r/   rH   Úgit_dirÚ	repo_rootr   r   r   Úget_subdirectoryÝ  s    ü
zGit.get_subdirectoryz tuple[str, str | None, AuthInfo]c                   sâ   t |ƒ\}}}}}| d¡r†|dt| d¡ƒ … }|tj |¡ dd¡ d¡ }| d¡d }	|d|	… t	||	d… ||||fƒ }d|vrÆd|vsšJ ‚| d	d
¡}t
ƒ  |¡\}}
}| dd¡}nt
ƒ  |¡\}}
}||
|fS )a9  
        Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'.
        That's required because although they use SSH they sometimes don't
        work with a ssh:// scheme (e.g. GitHub). But we need a scheme for
        parsing. Hence we remove it again afterwards and return it as a stub.
        ÚfileNú/ú\ú+r@   z://zfile:zgit+z
git+ssh://zssh://Ú )ÚurlsplitÚendswithrP   ÚlstripÚurllibÚrequestÚurl2pathnamer   ÚfindÚ
urlunsplitr-   Úget_url_rev_and_auth)r/   r2   ÚschemeÚnetlocr�   ÚqueryÚfragmentÚinitial_slashesÚnewpathÚ
after_plusr"   Ú	user_passr0   r   r   r¯   ï  s&    

ÿþÿzGit.get_url_rev_and_auth)rH   rr   r   c                 C  sF   g d¢}|dkr|  d¡ tj tj |d¡¡s4d S | j||d� d S )N)Ú	submoduler†   z--initz--recursiver   rI   z.gitmodulesrg   )r€   r*   r�   r‘   r�   r.   )r/   rH   rr   Úargvr   r   r   ry     s    
þzGit.update_submodulesc                   sx   t ƒ  |¡}|r|S z| jddg|ddddd�}W n2 tyR   t d|¡ Y d S  tyd   Y d S 0 tj 	| 
d¡¡S )	Nr˜   z--show-toplevelFTÚraise)rM   r>   r?   rU   r™   zKcould not determine if %s is under git control because git is not availablez
)r-   Úget_repository_rootr.   r   rC   rx   r   r*   r�   Únormpathr[   )r/   rH   ÚlocÚrr0   r   r   r»     s*    ú
ýzGit.get_repository_root)Úrepo_urlr   c                 C  s   dS )zEIn either https or ssh form, requirements must be prefixed with git+.Tr   )r¿   r   r   r   Úshould_add_vcs_url_prefix5  s    zGit.should_add_vcs_url_prefix)r   )r   )N)r   )!Ú__name__Ú
__module__Ú__qualname__rp   ÚdirnameÚ	repo_nameÚschemesÚunset_environÚdefault_arg_revÚstaticmethodr$   Úclassmethodr.   r;   rG   rS   r6   rd   ro   r5   r~   rƒ   r†   rŽ   r‰   rc   rm   r¡   r¯   ry   r»   rÀ   Ú__classcell__r   r   r0   r   r   >   sZ   	--D û ûr   )-Ú
__future__r   ÚloggingÚos.pathr*   r’   r�   Úurllib.parserª   Úurllib.requestÚdataclassesr   Útypingr   Úpip._internal.exceptionsr   r   Úpip._internal.utils.miscr   r   r	   Úpip._internal.utils.subprocessr
   Ú pip._internal.vcs.versioncontrolr   r   r   r   r   r   r   Úparser§   r®   Ú	getLoggerrÁ   rC   ÚcompilerB   r   ÚVERBOSEr•   r   r   Úregisterr   r   r   r   Ú<module>   s<   $

ÿ

õ    