B
    ãUvg$1  ã               @   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 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)Úsamefile)Údisplay_pathÚmake_vcs_requirement_url)ÚTempDirectory)ÚVersionControlÚvcsz[a-fA-F0-9]{40}c             C   s   t t | ¡ƒS )N)ÚboolÚ
HASH_REGEXÚmatch)Úsha© r   ú6/tmp/pip-install-r_9ig3yj/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dd„ Zd-d d!„Zd"d#„ Z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_args@   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_PFXr8   r   r   r   Úget_git_versionC   s    
zGit.get_git_versionc             C   s2   dddg}| j |d|d}| ¡ }|dkr.dS |S )zl
        Return the current branch, or None if HEAD isn't at a branch
        (e.g. detached HEAD).
        z	rev-parsez--abbrev-refr   F)r9   ÚcwdN)r=   Ústrip)r)   Úlocationr+   ÚoutputÚbranchr   r   r   Ú
get_branchP   s    
zGit.get_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)r9   rD   N)r   r	   Úunpackr/   r=   )r)   rF   Útemp_dirr   r   r   rJ   ^   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)rD   r9   Úon_returncodezunexpected show-ref line: {!r}zrefs/remotes/origin/{}zrefs/tags/{}NT)r=   rE   Ú
splitlinesr?   Ú
ValueErrorÚformatÚget)
r)   Údestr6   rG   ÚrefsÚliner   ÚrefÚ
branch_refÚtag_refr   r   r   Úget_revision_shaj   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)rD   Ú
FETCH_HEAD)r6   )Úarg_revrZ   Úmake_newÚbranch_namer   ÚloggerÚwarningr>   r=   Úto_argsÚget_revision)r)   rT   r*   Úrev_optionsr6   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)rc   )r)   rT   Únamer   r   r   Úis_commit_id_equal³   s    zGit.is_commit_id_equalc             C   sÆ   |  ¡ }t d||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-qr_   Úcheckout)rD   z	origin/{}z-bz--track)Ú
to_displayr`   Úinfor   r=   r6   rf   Úgetattrrh   rb   rI   rR   Úupdate_submodules)r)   rT   r*   rd   Úrev_displayr_   Ú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)rD   ri   z-q)r=   rb   rm   )r)   rT   r*   rd   ro   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)rD   Úresetz--hard)rC   rA   r=   rf   rb   rm   )r)   rT   r*   rd   ro   r   r   r   Úupdateå   s    z
Git.updatec             C   sZ   | j dddgd|d}| ¡ }|d }x|D ]}| d¡r,|}P q,W | d¡d	 }| ¡ S )
z+Return URL of the first remote encountered.rr   z--get-regexpzremote\..*\.urlF)r9   rD   r   zremote.origin.url ú r   )r=   rP   r>   r?   rE   )r)   rF   ÚremotesÚfound_remoteÚremoter*   r   r   r   Úget_urló   s    


zGit.get_urlc             C   s(   |d krd}| j d|gd|d}| ¡ S )Nr   z	rev-parseF)r9   rD   )r=   rE   )r)   rF   r6   Úcurrent_revr   r   r   rc     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)r9   rD   z..zsetup.pyzGCould not find setup.py for directory %s (tried all parent directories)N)r=   rE   Úosr/   Úisabsr@   ÚexistsÚdirnamer`   ra   r   Úrelpath)r)   rF   Úgit_dirÚroot_dirÚorig_locationÚlast_locationr   r   r   Ú_get_subdirectory
  s"    

zGit._get_subdirectoryc             C   s\   |   |¡}| ¡  d¡s d| }|  |¡}| ¡  dd¡d }|  |¡}t||||d}|S )Nzgit:zgit+ú-r   r   )Úsubdir)rz   Úlowerr>   rc   Úegg_namer?   r…   r   )r)   ÚdistrF   Úrepor{   Úegg_project_namer‡   Ú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*   r6   Ú	user_pass)r5   r   r   r   1  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Ú	submoduleru   z--initz--recursivez-q)rD   )r|   r/   r~   r@   r=   )r)   rF   r   r   r   rm   B  s
    zGit.update_submodulesc                sV   t t| ƒ |¡rdS y| ƒ jdg|ddd}| S  tk
rP   t d|¡ dS X d S )NTz	rev-parseFrN   )rD   r9   rO   zKcould not determine if %s is under git control because git is not available)r'   r   Úcontrols_locationr=   r   r`   Údebug)ÚclsrF   Úr)r5   r   r   r“   J  s    
zGit.controls_location)N)N)Ú__name__Ú
__module__Ú__qualname__rg   r   Ú	repo_nameÚschemesÚunset_environÚdefault_arg_revr(   r7   rC   rI   rJ   rZ   rf   rh   rq   rs   ru   rz   rc   r…   rŽ   r   rm   Úclassmethodr“   Ú__classcell__r   r   )r5   r   r      s0   "'
r   )#Ú
__future__r   ÚloggingÚos.pathr|   ÚreZpip._vendor.packaging.versionr   rA   Zpip._vendor.six.moves.urllibÚurllib_parser   r"   Úpip._internal.exceptionsr   Úpip._internal.utils.compatr   Úpip._internal.utils.miscr   r   Úpip._internal.utils.temp_dirr	   Úpip._internal.vcsr
   r   r   r%   Ú	getLoggerr—   r`   Úcompiler   r   r   Úregisterr   r   r   r   Ú<module>   s(   

  =