
§|j½+  ã               @   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 Gd	 d
 „  d
 e ƒ Z e j e ƒ d S)é    )Úabsolute_importN)Úsamefile)Ú
BadCommand)Úparse)Úrequest)Údisplay_pathÚrmtree)ÚvcsÚVersionControlc                   sK  e  Z d  Z d Z d Z d Z d6 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# „  Z d$ d% „  Z d& d' „  Z d( d) „  Z d* d+ „  Z d, d- „  Z d. d/ „  Z ‡  f d0 d1 †  Z d2 d3 „  Z e ‡  f d4 d5 †  ƒ Z ‡  S)7Ú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 | | | Ž 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-5c7ija6t/pip/pip/vcs/git.pyr"       s     #zGit.__init__c             C   sx   d } |  j  d g d d ƒ} | j | ƒ rF | t | ƒ d  … } n d } d j | j d ƒ d  d … ƒ } t | ƒ S)Nzgit version ÚversionÚshow_stdoutFÚ Ú.é   )Ú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 | ƒ zE | j d ƒ s; | d } |  j d d d d | g d d	 d
 | ƒWd t | ƒ Xd S)z@Export the Git repository at the url to the destination locationz-exportzpip-r   zcheckout-indexz-az-fz--prefixr3   FÚcwdN)ÚtempfileÚmkdtempÚunpackr   r7   r   )r#   ÚlocationÚtemp_dirr0   r0   r1   ÚexportB   s    
z
Git.exportc             C   s_   |  j  | ƒ } d | } | | k r0 | | g S| | k rG | | g St j d | ƒ | Sd 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   sJ   |  j  d d | g d | ƒ|  j  d d g | d | ƒ|  j | ƒ d  S)NÚconfigzremote.origin.urlr>   Úcheckoutz-q)r7   Úupdate_submodules)r#   rI   r$   rJ   r0   r0   r1   Úswitchl   s    z
Git.switchc             C   s    |  j  ƒ  t d ƒ k r7 |  j d d d g d | ƒn |  j d d g d | ƒ| ro |  j | d | | ƒ } |  j d d d g | d | ƒ|  j | ƒ d  S)	Nz1.9.0Úfetchz-qz--tagsr>   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   s~   |  j  d d d g d d d | ƒ} | j ƒ  } | d } x$ | D] } | j d ƒ rA | } PqA W| j d	 ƒ d
 } | j ƒ  S)z+Return URL of the first remote encountered.rP   z--get-regexpzremote\..*\.urlr3   Fr>   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 d | ƒ} | j ƒ  S)Nz	rev-parseÚHEADr3   Fr>   )r7   r^   )r#   rB   Úcurrent_revr0   r0   r1   rN   ©   s    zGit.get_revisionc             c   sn   |  j  d g d d d | ƒ} xI | j ƒ  j ƒ  D]5 } | j d d ƒ \ } } | j ƒ  | j ƒ  f Vq1 Wd S)z4Yields tuples of (commit, ref) for branches and tagszshow-refr3   Fr>   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]� \ } } d } |  j | ƒ rP | t d ƒ d … } nM |  j | ƒ rx | t d ƒ d … } n% |  j | ƒ r� | 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 d | ƒj ƒ  } t j j | ƒ sN t j j | | ƒ } t j j | d ƒ } | } x] t j j t j j | d ƒ ƒ sÈ | } t j j | ƒ } | | k rl t j	 d | ƒ d	 Sql Wt
 | | ƒ rÜ d	 St j j | | ƒ S)
z:Return the relative path of setup.py to the git repo root.z	rev-parsez	--git-dirr3   Fr>   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   s�   |  j  | ƒ } | j ƒ  j d ƒ s. d | } | j ƒ  j d d ƒ d } | sT d  S|  j | ƒ } d | | | f } |  j | ƒ } | r™ | 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                s‘   d |  j  k rl d |  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   sK   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-qr>   )rr   r)   rt   r9   r7   )r#   rB   r0   r0   r1   rR     s
    !zGit.update_submodulesc                sy   t  t |  ƒ j | ƒ r d Sy0 |  ƒ  j d g d | d d d d ƒ} | SWn& t k
 rt t j d | ƒ d SYn Xd  S)	NTz	rev-parser>   r3   FÚon_returncodeÚignorezKcould 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   )Ú__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‰   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    		ÿ 