î
Ó^ÝVê'  ã               @   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 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                   s?  e  Z d  Z d Z d Z d Z d4 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 ‡  f d. d/ †  Z d0 d1 „  Z e ‡  f d2 d3 †  ƒ Z ‡  S)5Ú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 ƒ } qß n  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-9m6vxulb/pip/pip/vcs/git.pyr"      s     )zGit.__init__c             C   sy   t  j d d ƒ } |  j | ƒ zH | j d ƒ s> | d } n  |  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--prefixÚshow_stdoutFÚcwdN)ÚtempfileÚmkdtempÚunpackr   Úrun_commandr   )r#   ÚlocationÚtemp_dirr0   r0   r1   Úexport4   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_optionsA   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_revisionÚ
startswith)r#   r?   r@   r0   r0   r1   Úcheck_versionU   s    zGit.check_versionc             C   sJ   |  j  d d | g d | ƒ|  j  d d g | d | ƒ|  j | ƒ d  S)NÚconfigzremote.origin.urlr3   Úcheckoutz-q)r7   Úupdate_submodules)r#   r?   r$   r@   r0   r0   r1   Úswitch^   s    z
Git.switchc             C   sl   |  j  d d g d | ƒ| r; |  j | d | | ƒ } n  |  j  d d d g | d | ƒ|  j | ƒ d  S)NÚfetchz-qr3   r   Úresetz--hard)r7   rC   rI   )r#   r?   r@   r0   r0   r1   Úupdated   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 | ƒqÚ n  |  j | ƒ n  d  S)	Nz (to %s)zorigin/masterÚ zCloning %s%s to %sr   z-qrH   r3   )	Úget_url_revÚcheck_destinationr<   Úinfor   r7   rC   rF   rI   )r#   r?   r$   r>   r@   Úrev_displayr0   r0   r1   Úobtainp   s"    		z
Git.obtainc             C   sQ   |  j  d d d g d d d | ƒ} | j ƒ  d } | j d ƒ d	 } | j ƒ  S)
z+Return URL of the first remote encountered.rG   z--get-regexpzremote\..*\.urlr2   Fr3   r   ú r   )r7   Ú
splitlinesÚsplitÚstrip)r#   r8   ÚremotesÚfirst_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ÚHEADr2   Fr3   )r7   rW   )r#   r8   Úcurrent_revr0   r0   r1   rD   ’   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-refr2   Fr3   rT   r   N)r7   rW   rU   rV   )r#   r8   ÚoutputÚlineÚcommitÚrefr0   r0   r1   Úget_full_refs—   s
    zGit.get_full_refsc             C   s   | j  d ƒ S)Nzrefs/remotes/)rE   )r#   r`   r0   r0   r1   Úis_ref_remoteŸ   s    zGit.is_ref_remotec             C   s   | j  d ƒ S)Nzrefs/heads/)rE   )r#   r`   r0   r0   r1   Úis_ref_branch¢   s    zGit.is_ref_branchc             C   s   | j  d ƒ S)Nz
refs/tags/)rE   )r#   r`   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)Úanyrb   rc   rd   )r#   r`   r0   r0   r1   Úis_ref_commit¨   s    zGit.is_ref_commitc             C   s   |  j  | ƒ S)N)r;   )r#   r8   r0   r0   r1   Úget_refs±   s    zGit.get_refsc             C   sÁ   i  } x´ |  j  | ƒ D]£ \ } } d } |  j | ƒ rP | t d ƒ d … } nP |  j | ƒ rx | t d ƒ d … } n( |  j | ƒ r  | t d ƒ d … } n  | d k	 r | | | <q q W| S)z=Return map of named refs (branches or tags) to commit hashes.Nzrefs/remotes/zrefs/heads/z
refs/tags/)ra   rb   r   rc   rd   )r#   r8   Úrvr_   r`   Úref_namer0   r0   r1   r;   ´   s    zGit.get_short_refsc             C   sò   |  j  d d g d d d | ƒj ƒ  } t j j | ƒ sQ t j j | | ƒ } n  t j j | d ƒ } | } x] t j j t j j | d ƒ ƒ sË | } t j j | ƒ } | | k ro t j	 d | ƒ d	 Sqo Wt
 | | ƒ rß d	 St j j | | ƒ S)
z:Return the relative path of setup.py to the git repo root.z	rev-parsez	--git-dirr2   Fr3   z..zsetup.pyzGCould not find setup.py for directory %s (tried all parent directories)N)r7   rW   Úosr)   ÚisabsÚjoinÚexistsÚdirnamer<   r=   r   Úrelpath)r#   r8   Úgit_dirÚroot_dirÚorig_locationÚlast_locationr0   r0   r1   Ú_get_subdirectoryÃ   s"    $zGit._get_subdirectoryc             C   s£   |  j  | ƒ } | j ƒ  j d ƒ s1 d | } n  | j ƒ  j d d ƒ d } | sW d  S|  j | ƒ } d | | | f } |  j | ƒ } | rŸ | d | 7} n  | S)Nzgit:zgit+ú-r   r   z%s@%s#egg=%sz&subdirectory=)rZ   ÚlowerrE   Úegg_namerV   rD   rt   )r#   Údistr8   ÚrepoÚegg_project_namer\   Ú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://rN   )r$   ÚAssertionErrorr   r!   r   rO   )r#   r$   r>   )r/   r0   r1   rO   ì   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Ú	submodulerM   z--initz--recursivez-qr3   )rj   r)   rm   rl   r7   )r#   r8   r0   r0   r1   rI   ý   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-parser3   r2   FÚon_returncodeÚignorezKcould not determine if %s is under git control because git is not available)r!   r   Úcontrols_locationr7   r   r<   Údebug)Úclsr8   Úr)r/   r0   r1   r‚     s    			zGit.controls_location)zgitr   r   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Únamern   Ú	repo_nameÚschemesr"   r:   rC   rF   rJ   rM   rS   rZ   rD   ra   rb   rc   rd   rf   rg   r;   rt   r}   rO   rI   Úclassmethodr‚   r0   r0   )r/   r1   r      s2   			r   )Ú
__future__r   Úloggingr4   Úos.pathrj   Ú
pip.compatr   Úpip.exceptionsr   Zpip._vendor.six.moves.urllibr   Úurllib_parser   r   Ú	pip.utilsr   r   Úpip.vcsr	   r
   r   r   Ú	getLoggerr†   r<   r   Úregisterr0   r0   r0   r1   Ú<module>   s   		þ