3
[$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jeZejd
Zdd Z G dd deZ!ej"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j| S )N)bool
HASH_REGEXmatch)sha r   6/tmp/pip-install-65viz3iy/pip/pip/_internal/vcs/git.pylooks_like_hash   s    r   c                   s   e Zd ZdZdZdZd1Zd2ZdZd3 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d4d%d&Zd'd( Zd)d* Z fd+d,Zd-d. Ze fd/d0Z  ZS )5Gitgitz.gitclonegit+http	git+httpsgit+sshgit+gitgit+fileGIT_DIRGIT_WORK_TREEHEADNc                s   |rt |\}}}}}|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__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}|j|r8|t|d  j d }nd}dj|jdd d }t|S )	Nzgit version versionF)show_stdoutr    .   )run_command
startswithr%   splitjoinparse_version)r.   VERSION_PFXr=   r   r   r   get_git_versionC   s    
zGit.get_git_versionc             C   s2   dddg}| j |d|d}|j }|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)r>   cwdN)rB   strip)r.   locationr0   outputbranchr   r   r   
get_branchP   s    
zGit.get_branchc             C   sT   |j ds|d }tdd.}| j|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)r>   rI   N)r$   r	   unpackr4   rB   )r.   rK   temp_dirr   r   r   rO   ^   s    
z
Git.exportc       
      C   s   | j d|g|ddd}i }xP|j j D ]@}y|j \}}W n" tk
r^   tdj|Y nX |||< q(W dj|}dj|}	|j|}|dk	r|d	fS |j|	}|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)rI   r>   on_returncodezunexpected show-ref line: {!r}zrefs/remotes/origin/{}zrefs/tags/{}NT)rB   rJ   
splitlinesrD   
ValueErrorformatget)
r.   destr;   rL   refsliner   ref
branch_reftag_refr   r   r   get_revision_shaj   s     





zGit.get_revision_shac             C   s   |j }| j||\}}|dk	r:|j|}|r0|nd|_|S t|sNtjd| |jds\|S | jdd|g|j	  |d | j
|dd}|j|}|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)rI   
FETCH_HEAD)r;   )arg_revr_   make_newbranch_namer   loggerwarningrC   rB   to_argsget_revision)r.   rY   r/   rev_optionsr;   r   Z	is_branchr   r   r   resolve_revision   s$    


zGit.resolve_revisionc             C   s   |sdS | j ||kS )z
        Return whether the current commit hash equals the given name.

        Args:
          dest: the repository directory.
          name: a string name.
        F)rh   )r.   rY   namer   r   r   is_commit_id_equal   s    zGit.is_commit_id_equalc             C   s   |j  }tjd||t| | jdd||g |jr| j|||}t|dd }|d kr| j||jsddg|j	  }| j||d n4| j
||krdj|}dd|d	|g}| j||d | j| d S )
NzCloning %s%s to %sr   z-qrd   checkout)rI   z	origin/{}z-bz--track)
to_displayre   infor   rB   r;   rj   getattrrl   rg   rN   rW   update_submodules)r.   rY   r/   ri   rev_displayrd   cmd_argsZtrack_branchr   r   r   	fetch_new   s     
zGit.fetch_newc             C   s@   | j dd|g|d ddg|j  }| j ||d | j| d S )Nconfigzremote.origin.url)rI   rm   z-q)rB   rg   rq   )r.   rY   r/   ri   rs   r   r   r   switch   s    z
Git.switchc             C   st   | j  tdkr&| jdddg|d n| jddg|d | j|||}dddg|j  }| j||d | j| d S )Nz1.9.0r`   z-qz--tags)rI   resetz--hard)rH   rF   rB   rj   rg   rq   )r.   rY   r/   ri   rs   r   r   r   update   s    z
Git.updatec             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.ru   z--get-regexpzremote\..*\.urlF)r>   rI   r   zremote.origin.url  r"   )rB   rU   rC   rD   rJ   )r.   rK   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}|j S )Nr   z	rev-parseF)r>   rI   )rB   rJ   )r.   rK   r;   current_revr   r   r   rh     s
    zGit.get_revisionc             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
||rdS tjj||S )	z:Return the relative path of setup.py to the git repo root.z	rev-parsez	--git-dirF)r>   rI   z..zsetup.pyzGCould not find setup.py for directory %s (tried all parent directories)N)rB   rJ   osr4   isabsrE   existsdirnamere   rf   r   relpath)r.   rK   git_dirroot_dirorig_locationlast_locationr   r   r   _get_subdirectory
  s"    

zGit._get_subdirectoryc             C   s\   | j |}|j jds d| }| j|}|j jddd }| j|}t||||d}|S )Nzgit:zgit+-r"   r   )subdir)r}   lowerrC   rh   egg_namerD   r   r   )r.   distrK   repor~   egg_project_namer   reqr   r   r   get_src_requirement%  s    


zGit.get_src_requirementc                sd   d|krDd|kst |jdd}tt| j|\}}}|jdd}ntt| j|\}}}|||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/   r;   	user_pass)r:   r   r   r   1  s    zGit.get_url_rev_and_authc             C   s6   t jjt jj|dsd S | jdddddg|d d S )Nz.gitmodules	submodulerx   z--initz--recursivez-q)rI   )r   r4   r   rE   rB   )r.   rK   r   r   r   rq   B  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-parseFrS   )rI   r>   rT   zKcould not determine if %s is under git control because git is not available)r,   r   controls_locationrB   r   re   debug)clsrK   r)r:   r   r   r   J  s    
zGit.controls_location)r   r   r   r   r   r   )r   r   )N)N)__name__
__module____qualname__rk   r   	repo_nameschemesunset_environdefault_arg_revr-   r<   rH   rN   rO   r_   rj   rl   rt   rv   rx   r}   rh   r   r   r   rq   classmethodr   __classcell__r   r   )r:   r   r      s0   "'
r   )#
__future__r   loggingos.pathr   reZpip._vendor.packaging.versionr   rF   Zpip._vendor.six.moves.urlliburllib_parser   r'   pip._internal.exceptionsr   Zpip._internal.utils.compatr   pip._internal.utils.miscr   r   pip._internal.utils.temp_dirr	   pip._internal.vcsr
   r   r#   r*   	getLoggerr   re   compiler   r   r   registerr   r   r   r   <module>   s(   

  =