U
    Zޫ^U7                     @   s  d dl m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 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 d d
lmZmZmZmZ erd dlmZm Z  d dlm!Z! d dlm"Z"m#Z# e
j$Z$e
j%Z%e&e'Z(e)dZ*dd Z+G dd deZ,e-e, dS )    )absolute_importN)parse)request)
BadCommandInstallationError)display_pathhide_url)make_command)TempDirectory)MYPY_CHECK_RUNNING)RemoteNotFoundErrorVersionControl!find_path_to_setup_from_repo_rootvcs)OptionalTuple)
HiddenText)AuthInfo
RevOptionsz^[a-fA-F0-9]{40}$c                 C   s   t t| S N)bool
HASH_REGEXmatch)sha r   9/tmp/pip-unpacked-wheel-huh_82lg/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 Z
d	d
 Zdd Zedd Zdd Zedd Zedd Zedd Zdd Zdd Zdd Zedd Zed*d d!Zed"d# Ze fd$d%Zed&d' Ze fd(d)Z  ZS )+Gitgitz.gitclone)r   zgit+httpz	git+httpszgit+sshzgit+gitzgit+file)GIT_DIRGIT_WORK_TREEHEADc                 C   s   | gS r   r   revr   r   r   get_base_rev_args:   s    zGit.get_base_rev_argsc                 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)selfurldest_rev_optionsis_tag_or_branchr   r   r   is_immutable_rev_checkout>   s    zGit.is_immutable_rev_checkoutc                 C   s\   d}| j dgdd}||r8|t|d   d }nd}d|dd d }t|S )	Nzgit version versionF)show_stdoutr    .   )run_command
startswithlensplitjoinparse_version)r)   VERSION_PFXr0   r   r   r   get_git_versionO   s    
zGit.get_git_versionc                 C   sB   dddg}| j |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"      Fextra_ok_returncodesr1   cwdzrefs/heads/N)r5   stripr6   r7   )clslocationargsoutputrefr   r   r   get_current_branch\   s    

   
zGit.get_current_branchc              	   C   sX   | ds|d }tdd2}| j|j|d | jdddd|gd	|jd
 W 5 Q R X dS )z@Export the Git repository at the url to the destination location/export)kind)r*   zcheckout-indexz-az-fz--prefixFr1   rB   N)endswithr
   unpackpathr5   )r)   rE   r*   temp_dirr   r   r   rK   q   s    
 z
Git.exportc           
   	   C   s   | j d|g|ddd}i }|  D ]@}z| \}}W n" tk
r\   td|Y nX |||< q&d|}d|}	||}|dk	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-refFignore)rB   r1   on_returncodezunexpected show-ref line: {!r}zrefs/remotes/origin/{}zrefs/tags/{}NT)r5   rC   
splitlinesr8   
ValueErrorformatget)
rD   r+   r$   rG   refsliner   rH   
branch_reftag_refr   r   r   r(   ~   s$     




zGit.get_revision_shac                 C   s   |j }|dk	st| ||\}}|dk	rF||}|r<|nd|_|S t|sZtd| |dsh|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.
        Nz:Did not find branch or tag '%s', assuming revision or ref.zrefs/fetchr=   rB   
FETCH_HEADr#   )arg_revAssertionErrorr(   make_newbranch_namer   loggerwarningr6   r5   r	   to_argsget_revision)rD   r+   r*   r-   r$   r   	is_branchr   r   r   resolve_revision   s*    



zGit.resolve_revisionc                 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)rf   )rD   r+   namer   r   r   r'      s    	zGit.is_commit_id_equalc                 C   s   |  }td||t| | tdd|| |jr| |||}t|dd }|d kr| 	||jstdd|
 }| j||d n4| ||krd|}dd|d	|g}| j||d | | d S )
NzCloning %s%s to %sr   r=   rb   checkoutr]   z	origin/{}z-bz--track)
to_displayrc   infor   r5   r	   r$   rh   getattrr'   re   rI   rV   update_submodules)r)   r+   r*   r-   rev_displayrb   cmd_argstrack_branchr   r   r   	fetch_new   s0      
    zGit.fetch_newc                 C   sB   | j tdd||d tdd| }| j ||d | | d S )Nconfigzremote.origin.urlr]   rj   r=   )r5   r	   re   rn   r)   r+   r*   r-   rp   r   r   r   switch   s    
z
Git.switchc                 C   st   |   tdkr&| jdddg|d n| jddg|d | |||}tddd| }| j||d | | d S )Nz1.9.0r\   r=   z--tagsr]   resetz--hard)r<   r:   r5   rh   r	   re   rn   rt   r   r   r   update  s    z
Git.updatec                 C   sx   | j dddgdd|d}| }z|d }W n tk
rD   tY nX |D ]}|drJ|} qbqJ|d	d
 }| S )z
        Return URL of the first remote encountered.

        Raises RemoteNotFoundError if the repository does not have a remote
        url configured.
        rs   z--get-regexpzremote\..*\.urlr>   Fr@   r   zremote.origin.url  r?   )r5   rT   
IndexErrorr   r6   r8   rC   )rD   rE   stdoutremotesfound_remoteremoter*   r   r   r   get_remote_url  s"    
  

zGit.get_remote_urlNc                 C   s(   |d krd}| j d|gd|d}| S )Nr"   	rev-parseFrM   )r5   rC   )rD   rE   r$   current_revr   r   r   rf   0  s      zGit.get_revisionc                 C   sR   | j ddgd|d }tj|s2tj||}tjtj|d}t||S )z~
        Return the path to setup.py, relative to the repo root.
        Return None if setup.py is in the repo root.
        r   z	--git-dirFrM   z..)r5   rC   osrP   isabsr9   abspathr   )rD   rE   git_dir	repo_rootr   r   r   get_subdirectory9  s     
zGit.get_subdirectoryc                    s   t |\}}}}}|dr|dt|d  }|t|ddd }t|||||f}|dd }	|d|	 t||	d ||||f }d|krd|kst	|d	d
}t
t| |\}}
}|dd}nt
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.
        fileNrJ   \+r?   z://zfile:zgit+z
git+ssh://zssh://r2   )urlsplitrN   r7   lstripurllib_requesturl2pathnamereplace
urlunsplitfindr`   superr   get_url_rev_and_auth)rD   r*   schemenetlocrP   queryfragmentinitial_slashesnewpath
after_plusr$   	user_pass	__class__r   r   r   H  s0    

 zGit.get_url_rev_and_authc                 C   s6   t jt j|dsd S | jdddddg|d d S )Nz.gitmodules	submodulerw   z--initz--recursiver=   r]   )r   rP   existsr9   r5   )rD   rE   r   r   r   rn   k  s    zGit.update_submodulesc                    s~   t t| |}|r|S z| jddg|dddd}W n6 tk
rV   td| Y d S  tk
rj   Y d S X tj	
|dS )Nr   z--show-toplevelFraise)rB   r1   rS   log_failed_cmdzKcould not determine if %s is under git control because git is not availablez
)r   r   get_repository_rootr5   r   rc   debugr   r   rP   normpathrstrip)rD   rE   locrr   r   r   r   t  s&    
zGit.get_repository_root)N)__name__
__module____qualname__ri   dirname	repo_nameschemesunset_environdefault_arg_revstaticmethodr%   r/   r<   classmethodrI   rK   r(   rh   r'   rr   ru   rw   r~   rf   r   r   rn   r   __classcell__r   r   r   r   r   .   sD   


"
,


"
r   ).
__future__r   loggingos.pathr   reZpip._vendor.packaging.versionr   r:   pip._vendor.six.moves.urlliburllib_parser   r   pip._internal.exceptionsr   r   pip._internal.utils.miscr   r   pip._internal.utils.subprocessr	   pip._internal.utils.temp_dirr
   pip._internal.utils.typingr    pip._internal.vcs.versioncontrolr   r   r   r   typingr   r   r   r   r   r   r   	getLoggerr   rc   compiler   r   r   registerr   r   r   r   <module>   s2   

  ^