3

g8                 @   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 d dlmZ d d	lmZ d d
lmZmZmZmZ erd 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)display_pathhide_url)make_command)TempDirectory)MYPY_CHECK_RUNNING)RemoteNotFoundErrorVersionControl!find_path_to_setup_from_repo_rootvcs)OptionalTuple)
HiddenText)AuthInfo
RevOptionsz^[a-fA-F0-9]{40}$c             C   s   t tj| S )N)bool
HASH_REGEXmatch)sha r   9/tmp/pip-unpacked-wheel-v59g9nu1/pip/_internal/vcs/git.pylooks_like_hash*   s    r   c                   s   e Zd ZdZdZdZd/Zd0ZdZe	dd Z
dd Zdd Zedd Zdd Zedd Zedd Zedd Zdd Zdd Zd d! Zed"d# Zed1d%d&Zed'd( Ze fd)d*Zed+d, Ze fd-d.Z  ZS )2Gitgitz.gitclonegit+http	git+httpsgit+sshgit+gitgit+fileGIT_DIRGIT_WORK_TREEHEADc             C   s   | gS )Nr   )revr   r   r   get_base_rev_args:   s    zGit.get_base_rev_argsc             C   sJ   | j t|\}}|jsdS | j||js.dS t| j||jd }| S )NFr   )get_url_rev_optionsr   r&   is_commit_id_equalr   get_revision_sha)selfurldest_rev_optionsis_tag_or_branchr   r   r   is_immutable_rev_checkout>   s    zGit.is_immutable_rev_checkoutc             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
startswithlensplitjoinparse_version)r+   VERSION_PFXr2   r   r   r   get_git_versionO   s    
zGit.get_git_versionc             C   sB   dddg}| j |d	d|d}|j }|jdr>|tdd S dS )
zl
        Return the current branch, or None if HEAD isn't at a branch
        (e.g. detached HEAD).
        zsymbolic-refz-qr%      F)extra_ok_returncodesr3   cwdzrefs/heads/N)r?   )r7   stripr8   r9   )clslocationargsoutputrefr   r   r   get_current_branch\   s    


zGit.get_current_branchc             C   sX   |j ds|d }tdd2}| j|j|d | 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 location/export)kind)r,   zcheckout-indexz-az-fz--prefixF)r3   rA   N)endswithr	   unpackpathr7   )r+   rD   r,   temp_dirr   r   r   rJ   q   s    
z
Git.exportc       
      C   s   | j d|g|ddd}i }xh|j jdD ]V}|jd}|s>q*y|jddd	\}}W n" tk
rv   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)rA   r3   on_returncode
    )maxsplitzunexpected show-ref line: {!r}zrefs/remotes/origin/{}zrefs/tags/{}NT)r7   rB   r:   rstrip
ValueErrorformatget)
rC   r-   r&   rF   refsliner   rG   
branch_reftag_refr   r   r   r*   ~   s&    





zGit.get_revision_shac             C   s   |j }|dk	st| j||\}}|dk	rF|j|}|r<|nd|_|S t|sZtjd| |jdsh|S | j	t
dd||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)rA   
FETCH_HEAD)r&   )arg_revAssertionErrorr*   make_newbranch_namer   loggerwarningr8   r7   r   to_argsget_revision)rC   r-   r,   r/   r&   r   	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   )rC   r-   namer   r   r   r)      s    	zGit.is_commit_id_equalc             C   s   |j  }tjd||t| | jtdd|| |jr| j|||}t|dd }|d kr| j	||jstdd|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)rA   z	origin/{}z-bz--track)
to_displayre   infor   r7   r   r&   rj   getattrr)   rg   rH   rY   update_submodules)r+   r-   r,   r/   rev_displayrd   cmd_argstrack_branchr   r   r   	fetch_new   s     
zGit.fetch_newc             C   sB   | j tdd||d tdd|j }| j ||d | j| d S )Nconfigzremote.origin.url)rA   rl   z-q)r7   r   rg   rp   )r+   r-   r,   r/   rr   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|||}tddd|j }| j||d | j| d S )Nz1.9.0r_   z-qz--tags)rA   resetz--hard)r>   r<   r7   rj   r   rg   rp   )r+   r-   r,   r/   rr   r   r   r   update  s    z
Git.updatec             C   sz   | j dddgd
d|d}|j }y|d }W n tk
rD   tY nX x|D ]}|jdrL|}P qLW |jd	d }|j S )z
        Return URL of the first remote encountered.

        Raises RemoteNotFoundError if the repository does not have a remote
        url configured.
        ru   z--get-regexpzremote\..*\.urlr?   F)r@   r3   rA   r   zremote.origin.url rT   )r?   )r7   
splitlines
IndexErrorr   r8   r:   rB   )rC   rD   stdoutremotesfound_remoteremoter,   r   r   r   get_remote_url  s    



zGit.get_remote_urlNc             C   s(   |d krd}| j d|gd|d}|j S )Nr%   z	rev-parseF)r3   rA   )r7   rB   )rC   rD   r&   current_revr   r   r   rh   6  s
    zGit.get_revisionc             C   sR   | j ddgd|dj }tjj|s2tjj||}tjjtjj|d}t||S )z~
        Return the path to setup.py, relative to the repo root.
        Return None if setup.py is in the repo root.
        z	rev-parsez	--git-dirF)r3   rA   z..)r7   rB   osrN   isabsr;   abspathr   )rC   rD   git_dir	repo_rootr   r   r   get_subdirectory?  s    zGit.get_subdirectoryc                s   t |\}}}}}|jdr|dt|jd  }|tj|jddjd }t|||||f}|jdd }	|d|	 t||	d ||||f }d|krd|kst	|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.
        fileNrI   \+r?   z://zfile:zgit+z
git+ssh://zssh://r4   )urlsplitrL   r9   lstripurllib_requesturl2pathnamereplace
urlunsplitfindrb   superr   get_url_rev_and_auth)rC   r,   schemenetlocrN   queryfragmentinitial_slashesnewpath
after_plusr&   	user_pass)	__class__r   r   r   N  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)rA   )r   rN   existsr;   r7   )rC   rD   r   r   r   rp   q  s
    zGit.update_submodulesc                sV   t t| j|rdS y| jdg|dddd}| S  tk
rP   tjd| dS X d S )NTz	rev-parseFrP   )rA   r3   rQ   log_failed_cmdzKcould not determine if %s is under git control because git is not available)r   r   controls_locationr7   r   re   debug)rC   rD   r)r   r   r   r   z  s    zGit.controls_location)r   r   r   r    r!   r"   )r#   r$   )N)__name__
__module____qualname__rk   dirname	repo_nameschemesunset_environdefault_arg_revstaticmethodr'   r1   r>   classmethodrH   rJ   r*   rj   r)   rt   rv   rx   r   rh   r   r   rp   r   __classcell__r   r   )r   r   r   .   s0   )-#	r   )-
__future__r   loggingos.pathr   reZpip._vendor.packaging.versionr   r<   pip._vendor.six.moves.urlliburllib_parser   r   pip._internal.exceptionsr   pip._internal.utils.miscr   r   pip._internal.utils.subprocessr   pip._internal.utils.temp_dirr	   pip._internal.utils.typingr
    pip._internal.vcs.versioncontrolr   r   r   r   typingr   r   r   r   r   r   r   	getLoggerr   re   compiler   r   r   registerr   r   r   r   <module>   s2   

  _