U
    KQh+                     @   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eZG d	d
 d
eZe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dZd2 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d,d-Zd.d/ Ze fd0d1Z  ZS )3Gitgitz.gitclone)r   zgit+httpz	git+httpszgit+sshzgit+gitzgit+fileNc                    s   |rt |\}}}}}|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__ */tmp/pip-build-tlro1kwj/pip/pip/vcs/git.pyr       s&    

 zGit.__init__c                 C   sT   d}| j dgdd}||r0|t|d  }nd}d|dd d }t|S )Nzgit version versionF)show_stdout .   )run_command
startswithr   joinsplitparse_version)r   VERSION_PFXr.   r,   r,   r-   get_git_version5   s    
zGit.get_git_versionc                 C   sV   t dd}| | z0|ds*|d }| jdddd|gd|d	 W 5 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r/   cwdN)tempfilemkdtempunpackr   r   r3   )r   locationtemp_dirr,   r,   r-   exportB   s    

 
z
Git.exportc                 C   sJ   |  |}d| }||kr$|| gS ||kr6|| gS td| |S dS )zCheck 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_revr,   r,   r-   check_rev_optionsO   s    


 zGit.check_rev_optionsc                 C   s   |  ||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_revisionr4   r   rF   rG   r,   r,   r-   check_versionc   s    zGit.check_versionc                 C   s8   | j dd|g|d | j ddg| |d | | d S )Nconfigzremote.origin.urlr;   checkout-q)r3   update_submodules)r   rF   r   rG   r,   r,   r-   switchl   s    z
Git.switchc                 C   st   |   tdkr&| jdddg|d n| jddg|d |rN| |d ||}| jdddg| |d | | d S )	Nz1.9.0fetchrQ   z--tagsrO   r   resetz--hard)r9   r7   r3   rJ   rR   rL   r,   r,   r-   updater   s      z
Git.updatec                 C   s   |   \}}|r |g}d| }n
dg}d}| ||||rtd||t| | dd||g |r| |||}| ||s| jddg| |d | | d S )	Nz (to %s)zorigin/masterr0   zCloning %s%s to %sr   rQ   rP   rO   )	get_url_revcheck_destinationrC   infor   r3   rJ   rM   rR   )r   rF   r   rE   rG   rev_displayr,   r,   r-   obtain   s,    
   
z
Git.obtainc                 C   sX   | j dddgd|d}| }|d }|D ]}|dr*|} qBq*|dd	 }| S )
z+Return URL of the first remote encountered.rN   z--get-regexpzremote\..*\.urlFr:   r   zremote.origin.url  r   )r3   
splitlinesr4   r6   strip)r   r?   remotesfound_remoteremoter   r,   r,   r-   get_url   s     
zGit.get_urlc                 C   s   | j ddgd|d}| S )N	rev-parseHEADFr:   )r3   r^   )r   r?   current_revr,   r,   r-   rK      s      zGit.get_revisionc                 c   sJ   | j dgd|d}|  D ]&}|dd\}}| | fV  qdS )z4Yields tuples of (commit, ref) for branches and tagszshow-refFr:   r\   r   N)r3   r^   r]   r6   )r   r?   outputlinecommitrefr,   r,   r-   get_full_refs   s     zGit.get_full_refsc                 C   s
   | dS )Nrefs/remotes/r4   r   ri   r,   r,   r-   is_ref_remote   s    zGit.is_ref_remotec                 C   s
   | dS )Nrefs/heads/rl   rm   r,   r,   r-   is_ref_branch   s    zGit.is_ref_branchc                 C   s
   | dS )N
refs/tags/rl   rm   r,   r,   r-   
is_ref_tag   s    zGit.is_ref_tagc                 C   s"   t | || || |f S )z0A ref is a commit sha if it is not anything else)anyrn   rp   rr   rm   r,   r,   r-   is_ref_commit   s
    zGit.is_ref_commitc                 C   s
   |  |S )N)rB   r   r?   r,   r,   r-   get_refs   s    zGit.get_refsc                 C   s   i }|  |D ]n\}}d}| |r6|tdd }n6| |rR|tdd }n| |rl|tdd }|dk	r|||< q|S )z=Return map of named refs (branches or tags) to commit hashes.Nrk   ro   rq   )rj   rn   r   rp   rr   )r   r?   rvrh   ri   ref_namer,   r,   r-   rB      s    



zGit.get_short_refsc                 C   s   | j ddgd|d }tj|s2tj||}tj|d}|}tjtj|ds|}tj|}||krDt	d| dS qDt
||rdS tj||S )	z:Return the relative path of setup.py to the git repo root.rc   z	--git-dirFr:   z..zsetup.pyzGCould not find setup.py for directory %s (tried all parent directories)N)r3   r^   osr$   isabsr5   existsdirnamerC   rD   r   relpath)r   r?   git_dirroot_dirorig_locationlast_locationr,   r,   r-   _get_subdirectory   s(    
 

zGit._get_subdirectoryc                 C   sr   |  |}| ds d| }| ddd }|s<d S | |}d|||f }| |}|rn|d| 7 }|S )Nzgit:git+-r   r   z%s@%s#egg=%sz&subdirectory=)rb   lowerr4   egg_namer6   rK   r   )r   distr?   repoegg_project_namere   reqsubdirectoryr,   r,   r-   get_src_requirement   s    


zGit.get_src_requirementc                    sb   d| j krHd| j kst| j dd| _ tt|  \}}|dd}ntt|  \}}||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:r   z
git+ssh://zssh://r0   )r   AssertionErrorr   r   r   rW   )r   r   rE   r*   r,   r-   rW     s    
zGit.get_url_revc                 C   s6   t jt j|dsd S | jdddddg|d d S )Nz.gitmodules	submodulerV   z--initz--recursiverQ   rO   )ry   r$   r{   r5   r3   ru   r,   r,   r-   rR     s    zGit.update_submodulesc                    sZ   t t| |rdS z|  jdg|ddd}| W S  tk
rT   td| Y dS X d S )NTrc   Fignore)r;   r/   on_returncodezKcould not determine if %s is under git control because git is not available)r   r   controls_locationr3   r   rC   debug)clsr?   rr*   r,   r-   r     s    
zGit.controls_location)N)__name__
__module____qualname__namer|   	repo_nameschemesr   r9   rA   rJ   rM   rS   rV   r[   rb   rK   rj   rn   rp   rr   rt   rv   rB   r   r   rW   rR   classmethodr   __classcell__r,   r,   r*   r-   r      s6   		r   )
__future__r   loggingr<   os.pathry   
pip.compatr   pip.exceptionsr   Zpip._vendor.six.moves.urllibr   urllib_parser   r   Zpip._vendor.packaging.versionr7   	pip.utilsr   r   pip.vcsr	   r
   r   r   	getLoggerr   rC   r   registerr,   r,   r,   r-   <module>   s"   
  