B
    Kkd_4  ã               @   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 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 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)Úsamefile)Údisplay_pathÚmake_vcs_requirement_urlÚredact_password_from_url)ÚTempDirectory)ÚRemoteNotFoundErrorÚVersionControlÚvcsz[a-fA-F0-9]{40}c             C   s   t t | ¡ƒS )N)ÚboolÚ
HASH_REGEXÚmatch)Úsha© r   ú6/tmp/pip-install-gxxfd9b7/pip/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d,‡ fdd	„	Z	d
d„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Z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d$d%„ ƒZ‡ fd&d'„Z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ÚHEADNc                s¶   |ršt |ƒ\}}}}}| d¡rš|d t| d¡ƒ … }	|	t |¡ dd¡ d¡ }
t|||
||fƒ}| d¡d }|d |… t||d … ||
||fƒ }t	t
| ƒj|f|ž|Ž d S )NÚfileú/ú\ú+é   )ÚurlsplitÚendswithÚlenÚlstripÚurllib_requestÚurl2pathnameÚreplaceÚ
urlunsplitÚfindÚsuperr   Ú__init__)ÚselfÚurlÚargsÚkwargsÚschemeÚnetlocÚpathÚqueryÚfragmentÚinitial_slashesÚnewpathÚ
after_plus)Ú	__class__r   r   r*   -   s    

zGit.__init__c             C   s   |gS )Nr   )r+   Úrevr   r   r   Úget_base_rev_argsB   s    zGit.get_base_rev_argsc             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Ú
startswithr"   ÚsplitÚjoinÚparse_version)r+   ÚVERSION_PFXr:   r   r   r   Úget_git_versionE   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-refz-qr   )r   F)Úextra_ok_returncodesr;   Úcwdzrefs/heads/N)r?   Ústripr@   r"   )r+   Úlocationr-   ÚoutputÚrefr   r   r   Úget_current_branchR   s    	

zGit.get_current_branchc          	   C   sT   |  d¡s|d }tdd.}|  |j¡ | jdddd|gd|jd	 W d
Q R X d
S )z@Export the Git repository at the url to the destination locationr   Úexport)Úkindzcheckout-indexz-az-fz--prefixF)r;   rG   N)r!   r
   Úunpackr1   r?   )r+   rI   Útemp_dirr   r   r   rM   f   s    
z
Git.exportc       
   	   C   s¬   | j d|g|ddd}i }xP| ¡  ¡ D ]@}y| ¡ \}}W n" tk
r^   td |¡ƒ‚Y nX |||< q(W 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)rG   r;   Úon_returncodezunexpected show-ref line: {!r}zrefs/remotes/origin/{}zrefs/tags/{}NT)r?   rH   Ú
splitlinesrA   Ú
ValueErrorÚformatÚget)
r+   Údestr8   rJ   ÚrefsÚliner   rK   Ú
branch_refÚtag_refr   r   r   Úget_revision_shar   s     





zGit.get_revision_shac             C   s”   |j }|  ||¡\}}|dk	r:| |¡}|r0|nd|_|S t|ƒsNt d|¡ | d¡s\|S | jdd|g| 	¡  |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/Úfetchz-q)rG   Ú
FETCH_HEAD)r8   )Úarg_revr\   Úmake_newÚbranch_namer   ÚloggerÚwarningr@   r?   Úto_argsÚget_revision)r+   rW   r,   Úrev_optionsr8   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)re   )r+   rW   Únamer   r   r   Úis_commit_id_equal»   s    zGit.is_commit_id_equalc             C   sÊ   |  ¡ }t dt|ƒ|t|ƒ¡ |  dd||g¡ |jr¼|  |||¡}t|dd ƒ}|d krˆ|  	||j¡s¼ddg| 
¡  }| j||d n4|  |¡|kr¼d |¡}dd|d	|g}| j||d |  |¡ d S )
NzCloning %s%s to %sr   z-qra   Úcheckout)rG   z	origin/{}z-bz--track)Ú
to_displayrb   Úinfor	   r   r?   r8   rh   Úgetattrrj   rd   rL   rU   Úupdate_submodules)r+   rW   r,   rf   Úrev_displayra   Úcmd_argsÚtrack_branchr   r   r   Ú	fetch_newÉ   s"    
zGit.fetch_newc             C   s@   | j dd|g|d ddg| ¡  }| j ||d |  |¡ d S )NÚconfigzremote.origin.url)rG   rk   z-q)r?   rd   ro   )r+   rW   r,   rf   rq   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 |  |||¡}dddg| ¡  }| j||d |  |¡ d S )Nz1.9.0r]   z-qz--tags)rG   Úresetz--hard)rE   rC   r?   rh   rd   ro   )r+   rW   r,   rf   rq   r   r   r   Úupdateî   s    z
Git.updatec             C   sz   | j dddgdd|d}| ¡ }y|d }W n tk
rD   t‚Y nX x|D ]}| d¡rL|}P qLW | d	¡d
 }| ¡ S )z¢
        Return URL of the first remote encountered.

        Raises RemoteNotFoundError if the repository does not have a remote
        url configured.
        rt   z--get-regexpzremote\..*\.url)r   F)rF   r;   rG   r   zremote.origin.url ú r   )r?   rS   Ú
IndexErrorr   r@   rA   rH   )ÚclsrI   ÚstdoutÚremotesÚfound_remoteÚremoter,   r   r   r   Úget_remote_urlü   s    



zGit.get_remote_urlc             C   s(   |d krd}| j d|gd|d}| ¡ S )Nr   z	rev-parseF)r;   rG   )r?   rH   )rz   rI   r8   Úcurrent_revr   r   r   re     s
    zGit.get_revisionc             C   s¤   | j ddgd|d ¡ }tj |¡s2tj ||¡}tj |d¡}|}xBtj tj |d¡¡s†|}tj |¡}||krFt 	d|¡ dS qFW t
||ƒr–dS tj ||¡S )	z:Return the relative path of setup.py to the git repo root.z	rev-parsez	--git-dirF)r;   rG   z..zsetup.pyzGCould not find setup.py for directory %s (tried all parent directories)N)r?   rH   Úosr1   ÚisabsrB   ÚexistsÚdirnamerb   rc   r   Úrelpath)rz   rI   Úgit_dirÚroot_dirÚorig_locationÚlast_locationr   r   r   Ú_get_subdirectory   s"    

zGit._get_subdirectoryc             C   sH   |   |¡}| ¡  d¡s d| }|  |¡}|  |¡}t||||d}|S )Nzgit:zgit+)Úsubdir)r   Úlowerr@   re   rŠ   r   )rz   rI   Úproject_nameÚrepor€   r‹   Úreqr   r   r   Úget_src_requirement<  s    


zGit.get_src_requirementc                sd   d|krDd|kst ‚| 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.
        z://zfile:zgit+z
git+ssh://zssh://r<   )ÚAssertionErrorr&   r)   r   Úget_url_rev_and_auth)r+   r,   r8   Ú	user_pass)r7   r   r   r’   H  s    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--recursivez-q)rG   )r   r1   rƒ   rB   r?   )r+   rI   r   r   r   ro   Y  s
    zGit.update_submodulesc                sT   t t| ƒ |¡rdS y| jdg|ddd}| S  tk
rN   t d|¡ dS X d S )NTz	rev-parseFrQ   )rG   r;   rR   zKcould not determine if %s is under git control because git is not available)r)   r   Úcontrols_locationr?   r   rb   Údebug)rz   rI   Úr)r7   r   r   r•   a  s    zGit.controls_location)N)N)Ú__name__Ú
__module__Ú__qualname__ri   r„   Ú	repo_nameÚschemesÚunset_environÚdefault_arg_revr*   r9   rE   rL   rM   r\   rh   rj   rs   ru   rw   Úclassmethodr   re   rŠ   r   r’   ro   r•   Ú__classcell__r   r   )r7   r   r   !   s2   "'r   )%Ú
__future__r   ÚloggingÚos.pathr   ÚreZpip._vendor.packaging.versionr   rC   Úpip._vendor.six.moves.urllibÚurllib_parser   r$   Úpip._internal.exceptionsr   Úpip._internal.utils.compatr   Úpip._internal.utils.miscr   r   r	   Úpip._internal.utils.temp_dirr
   Úpip._internal.vcsr   r   r   r    r'   Ú	getLoggerr˜   rb   Úcompiler   r   r   Úregisterr   r   r   r   Ú<module>   s(   

  R