3
zYði½+  ã               @   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mZ ejZejZejeƒZG d	d
„ d
eƒZejeƒ dS )é    )Úabsolute_importN)Úsamefile)Ú
BadCommand)Úparse)Úrequest)Údisplay_pathÚrmtree)ÚvcsÚVersionControlc                   sâ   e Zd ZdZdZdZd6Zd7‡ 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#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Z‡ fd0d1„Zd2d3„ Ze‡ fd4d5„ƒZ‡  ZS )8ÚGitÚgitz.gitÚcloneúgit+httpú	git+httpsúgit+sshúgit+gitúgit+fileNc                s¶   |ršt |ƒ\}}}}}|jdƒrš|d t|jdƒƒ … }	|	tj|ƒjddƒjdƒ }
t|||
||fƒ}|j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__© ú*/tmp/pip-build-ue6tjl93/pip/pip/vcs/git.pyr"       s    

zGit.__init__c             C   sT   d}| j dgdd�}|j|ƒr0|t|ƒd … }nd}dj|jdƒd d… ƒ}t|ƒS )Nzgit version ÚversionF)Úshow_stdoutÚ Ú.é   )Úrun_commandÚ
startswithr   ÚjoinÚsplitÚparse_version)r#   ÚVERSION_PFXr2   r0   r0   r1   Úget_git_version5   s    
zGit.get_git_versionc             C   sV   t jddƒ}| j|ƒ z0|jdƒs*|d }| jdddd|gd|d	� W d
t|ƒ X d
S )z@Export the Git repository at the url to the destination locationz-exportzpip-r   zcheckout-indexz-az-fz--prefixF)r3   ÚcwdN)ÚtempfileÚmkdtempÚunpackr   r7   r   )r#   ÚlocationÚtemp_dirr0   r0   r1   ÚexportB   s    

z
Git.exportc             C   sJ   | j |ƒ}d| }||kr$|| gS ||kr6|| gS tjd|ƒ |S dS )z¶Check the revision options before checkout to compensate that tags
        and branches may need origin/ as a prefix.
        Returns the SHA1 of the branch or tag if found.
        z	origin/%sz5Could not find a tag or branch '%s', assuming commit.N)Úget_short_refsÚloggerÚwarning)r#   ÚrevÚdestÚrev_optionsÚ	revisionsÚ
origin_revr0   r0   r1   Úcheck_rev_optionsO   s    


zGit.check_rev_optionsc             C   s   | j |ƒj|d ƒS )a
  
        Compare the current sha to the ref. ref may be a branch or tag name,
        but current rev will always point to a sha. This means that a branch
        or tag will never compare as True. So this ultimately only matches
        against exact shas.
        r   )Úget_revisionr8   )r#   rI   rJ   r0   r0   r1   Úcheck_versionc   s    zGit.check_versionc             C   s8   | j dd|g|d� | j ddg| |d� | j|ƒ d S )NÚconfigzremote.origin.url)r>   Úcheckoutz-q)r7   Úupdate_submodules)r#   rI   r$   rJ   r0   r0   r1   Úswitchl   s    z
Git.switchc             C   st   | j ƒ tdƒkr&| jdddg|d� n| jddg|d� |rN| j|d ||ƒ}| jdddg| |d� | j|ƒ d S )	Nz1.9.0Úfetchz-qz--tags)r>   r   Úresetz--hard)r=   r;   r7   rM   rR   )r#   rI   rJ   r0   r0   r1   Úupdater   s    z
Git.updatec             C   s¢   | j ƒ \}}|r |g}d| }n
dg}d}| j||||ƒržtjd||t|ƒƒ | jdd||gƒ |r”| j|||ƒ}| j||ƒs”| jddg| |d� | j|ƒ d S )	Nz (to %s)zorigin/masterr4   zCloning %s%s to %sr   z-qrQ   )r>   )	Úget_url_revÚcheck_destinationrF   Úinfor   r7   rM   rO   rR   )r#   rI   r$   rH   rJ   Úrev_displayr0   r0   r1   Úobtain‚   s"    

z
Git.obtainc             C   sZ   | j dddgd|d�}|jƒ }|d }x|D ]}|jdƒr,|}P q,W |jdƒd	 }|jƒ S )
z+Return URL of the first remote encountered.rP   z--get-regexpzremote\..*\.urlF)r3   r>   r   zremote.origin.url ú r   )r7   Ú
splitlinesr8   r:   Ústrip)r#   rB   ÚremotesÚfound_remoteÚremoter$   r0   r0   r1   Úget_url›   s    


zGit.get_urlc             C   s   | j ddgd|d�}|jƒ S )Nz	rev-parseÚHEADF)r3   r>   )r7   r^   )r#   rB   Úcurrent_revr0   r0   r1   rN   ©   s    zGit.get_revisionc             c   sN   | j dgd|d�}x6|jƒ jƒ D ]&}|jddƒ\}}|jƒ |jƒ fV  q W dS )z4Yields tuples of (commit, ref) for branches and tagszshow-refF)r3   r>   r\   r   N)r7   r^   r]   r:   )r#   rB   ÚoutputÚlineÚcommitÚrefr0   r0   r1   Úget_full_refs®   s
    
zGit.get_full_refsc             C   s
   |j dƒS )Nzrefs/remotes/)r8   )r#   rh   r0   r0   r1   Úis_ref_remote¶   s    zGit.is_ref_remotec             C   s
   |j dƒS )Nzrefs/heads/)r8   )r#   rh   r0   r0   r1   Úis_ref_branch¹   s    zGit.is_ref_branchc             C   s
   |j dƒS )Nz
refs/tags/)r8   )r#   rh   r0   r0   r1   Ú
is_ref_tag¼   s    zGit.is_ref_tagc             C   s"   t | j|ƒ| j|ƒ| j|ƒfƒ S )z0A ref is a commit sha if it is not anything else)Úanyrj   rk   rl   )r#   rh   r0   r0   r1   Úis_ref_commit¿   s    zGit.is_ref_commitc             C   s
   | j |ƒS )N)rE   )r#   rB   r0   r0   r1   Úget_refsÈ   s    zGit.get_refsc             C   s†   i }x|| j |ƒD ]n\}}d}| j|ƒr8|tdƒd… }n6| j|ƒrT|tdƒd… }n| j|ƒrn|tdƒd… }|dk	r|||< qW |S )z=Return map of named refs (branches or tags) to commit hashes.Nzrefs/remotes/zrefs/heads/z
refs/tags/)ri   rj   r   rk   rl   )r#   rB   Úrvrg   rh   Úref_namer0   r0   r1   rE   Ë   s    


zGit.get_short_refsc             C   s¤   | j ddgd|d�jƒ }tjj|ƒs2tjj||ƒ}tjj|dƒ}|}xBtjjtjj|dƒƒs†|}tjj|ƒ}||krFtj	d|ƒ dS qFW t
||ƒr–dS tjj||ƒS )	z:Return the relative path of setup.py to the git repo root.z	rev-parsez	--git-dirF)r3   r>   z..zsetup.pyzGCould not find setup.py for directory %s (tried all parent directories)N)r7   r^   Úosr)   Úisabsr9   ÚexistsÚdirnamerF   rG   r   Úrelpath)r#   rB   Úgit_dirÚroot_dirÚorig_locationÚlast_locationr0   r0   r1   Ú_get_subdirectoryÚ   s"    

zGit._get_subdirectoryc             C   sr   | j |ƒ}|jƒ jdƒs d| }|jƒ jddƒd }|s<d S | j|ƒ}d|||f }| j|ƒ}|rn|d| 7 }|S )Nzgit:zgit+ú-r   r   z%s@%s#egg=%sz&subdirectory=)rb   Úlowerr8   Úegg_namer:   rN   r{   )r#   ÚdistrB   ÚrepoÚegg_project_namerd   ÚreqÚsubdirectoryr0   r0   r1   Úget_src_requirementõ   s    


zGit.get_src_requirementc                sb   d| j krHd| j kst‚| j jddƒ| _ tt| ƒjƒ \}}|jddƒ}ntt| ƒjƒ \}}||fS )a;  
        Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'.
        That's required because although they use SSH they sometimes doesn'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://r4   )r$   ÚAssertionErrorr   r!   r   rW   )r#   r$   rH   )r/   r0   r1   rW     s    
zGit.get_url_revc             C   s6   t jjt jj|dƒƒsd S | jdddddg|d� d S )Nz.gitmodulesÚ	submodulerV   z--initz--recursivez-q)r>   )rr   r)   rt   r9   r7   )r#   rB   r0   r0   r1   rR     s
    zGit.update_submodulesc                sV   t t| ƒj|ƒrdS y| ƒ jdg|ddd�}| S  tk
rP   tjd|ƒ dS X d S )NTz	rev-parseFÚignore)r>   r3   Úon_returncodezKcould not determine if %s is under git control because git is not available)r!   r   Úcontrols_locationr7   r   rF   Údebug)ÚclsrB   Úr)r/   r0   r1   r‰     s    
zGit.controls_location)r   r   r   r   r   r   )N)Ú__name__Ú
__module__Ú__qualname__Únameru   Ú	repo_nameÚschemesr"   r=   rD   rM   rO   rS   rV   r[   rb   rN   ri   rj   rk   rl   rn   ro   rE   r{   r„   rW   rR   Úclassmethodr‰   Ú__classcell__r0   r0   )r/   r1   r      s4   		r   )Ú
__future__r   Úloggingr?   Úos.pathrr   Ú
pip.compatr   Úpip.exceptionsr   Zpip._vendor.six.moves.urllibr   Úurllib_parser   r   Zpip._vendor.packaging.versionr;   Ú	pip.utilsr   r   Úpip.vcsr	   r
   r   r   Ú	getLoggerr�   rF   r   Úregisterr0   r0   r0   r1   Ú<module>   s"   
  