3
gE                 @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlm	Z	m
Z
mZ d dlmZmZ d dlmZmZmZ d dlmZ d dlmZmZmZmZmZmZmZ ejjZejjZe j e!Z"ej#dZ$ej#dZ%ej#d	ej&Z'e(e)d
ddZ*G dd deZ+ej,e+ dS )    N)ListOptionalTuple)
BadCommandInstallationError)
HiddenTextdisplay_pathhide_url)make_command)AuthInfoRemoteNotFoundErrorRemoteNotValidError
RevOptionsVersionControl(find_path_to_project_root_from_repo_rootvcsz(^git version (\d+)\.(\d+)(?:\.(\d+))?.*$z^[a-fA-F0-9]{40}$a/  ^
    # Optional user, e.g. 'git@'
    (\w+@)?
    # Server, e.g. 'github.com'.
    ([^/:]+):
    # The server-side path. e.g. 'user/project.git'. Must start with an
    # alphanumeric character so as not to be confusable with a Windows paths
    # like 'C:/foo/bar' or 'C:\foo\bar'.
    (\w[^:]*)
    $)shareturnc             C   s   t tj| S )N)bool
HASH_REGEXmatch)r    r   S/var/www/tester-filtro-web/env/lib/python3.6/site-packages/pip/_internal/vcs/git.pylooks_like_hash7   s    r   c                   s  e Zd ZdZdZdZd@ZdAZdZe	e
ee
 dddZe
e
edddZeedf dddZee
ee
 dddZee
e
eee
 ef dddZee
e
edddZee
eeeddd Zee
ee
 ed!d"d#Ze
eed$dd%d&Ze
eed$dd'd(Ze
eed$dd)d*Zee
e
dd+d,Ze	e
e
d-d.d/Zee
e
ed0d1d2Z edBe
ee
 e
d0d3d4Z!ee
ee
 dd5d6Z"ee
ee
ee
 e#f d- fd7d8Z$ee
d$dd9d:Z%ee
ee
 d fd;d<Z&e	e
ed=d>d?Z'  Z(S )CGitgitz.gitclonegit+http	git+httpsgit+sshgit+gitgit+fileGIT_DIRGIT_WORK_TREEHEAD)revr   c             C   s   | gS )Nr   )r%   r   r   r   get_base_rev_argsK   s    zGit.get_base_rev_args)urldestr   c             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)selfr'   r(   _rev_optionsZis_tag_or_branchr   r   r   is_immutable_rev_checkoutO   s    zGit.is_immutable_rev_checkout.)r   c             C   sF   | j dgddd}tj|}|s0tjd| f S tdd |j D S )NversionFT)show_stdoutstdout_onlyzCan't parse git version: %sc             s   s   | ]}t |V  qd S )N)int).0cr   r   r   	<genexpr>c   s    z&Git.get_git_version.<locals>.<genexpr>)run_commandGIT_VERSION_REGEXr   loggerwarningtuplegroups)r,   r0   r   r   r   r   get_git_version]   s    
zGit.get_git_version)locationr   c             C   sD   dddg}| j |d
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$      FT)extra_ok_returncodesr1   r2   cwdzrefs/heads/N)r?   )r7   strip
startswithlen)clsr>   argsoutputrefr   r   r   get_current_branche   s    


zGit.get_current_branch)r(   r%   r   c             C   s   | j d|g|dddd}i }xh|j jdD ]V}|jd}|s@q,y|jdd	d
\}}W n" tk
rx   td|Y nX |||< q,W d| }d| }	|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-refFTignore)rA   r1   r2   on_returncode
    )maxsplitzunexpected show-ref line: zrefs/remotes/origin/z
refs/tags/N)r7   rB   splitrstrip
ValueErrorget)rE   r(   r%   rG   refslineZref_shaZref_nameZ
branch_refZtag_refr   r   r   r   r+   ~   s.    




zGit.get_revision_shac             C   s.   |j drdS t|sdS | j||r*dS dS )a$  
        Return true if rev is a ref or is a commit that we don't have locally.

        Branches and tags are not considered in this method because they are
        assumed to be always available locally (which is a normal outcome of
        ``git clone`` and ``git fetch --tags``).
        zrefs/TF)rC   r   
has_commit)rE   r(   r%   r   r   r   _should_fetch   s    	
zGit._should_fetch)r(   r'   r.   r   c             C   s   |j }|dk	st| j||\}}|dk	rF|j|}|r<|nd|_|S t|sZtjd| | j||sj|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.fetchz-q)rA   Z
FETCH_HEAD)r%   )arg_revAssertionErrorr+   make_newbranch_namer   r9   r:   rX   r7   r
   to_argsget_revision)rE   r(   r'   r.   r%   r   Z	is_branchr   r   r   resolve_revision   s&    

zGit.resolve_revision)r(   namer   c             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)r_   )rE   r(   ra   r   r   r   r*      s    	zGit.is_commit_id_equalNc       	      C   s   |j  }tjd||t| | j dkr@| jtddd|| n| jtdd|| |jr| j|||}t	|dd }tj
d|| |d kr| j||jstd	d|j }| j||d
 n4| j||krd| }d	d|d|g}| j||d
 n| j|}|j|}tjd||j | j| d S )NzCloning %s%s to %srO      r   z--filter=blob:nonez-qr]   zRev options %s, branch_name %scheckout)rA   zorigin/z-bz--trackzResolved %s to commit %s)rO   rb   )
to_displayr9   infor   r=   r7   r
   r%   r`   getattrdebugr*   r^   rI   r_   r\   update_submodules)	r,   r(   r'   r.   rev_displayr]   cmd_argsZtrack_branchr   r   r   r   	fetch_new   sD    




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   rc   z-q)r7   r
   r^   rh   )r,   r(   r'   r.   rj   r   r   r   switch7  s    
z
Git.switchc             C   sp   | j  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 )
Nr?   	   rY   z-qz--tags)rA   resetz--hard)r?   rn   )r=   r7   r`   r
   r^   rh   )r,   r(   r'   r.   rj   r   r   r   updateA  s    z
Git.updatec             C   s   | j dddgddd|d}|j }y|d }W n tk
rF   tY nX x|D ]}|jd	rN|}P qNW |jd
d }| j|j S )z
        Return URL of the first remote encountered.

        Raises RemoteNotFoundError if the repository does not have a remote
        url configured.
        rl   z--get-regexpzremote\..*\.urlr?   FT)r@   r1   r2   rA   r   zremote.origin.url rN   )r?   )r7   
splitlines
IndexErrorr   rC   rQ   _git_remote_to_pip_urlrB   )rE   r>   stdoutZremotesZfound_remoteZremoter'   r   r   r   get_remote_urlO  s"    



zGit.get_remote_url)r'   r   c             C   sN   t jd| r| S tjj| r*tj| j S tj| }|rB|j	dS t
| dS )a8  
        Convert a remote url from what git uses to what pip accepts.

        There are 3 legal forms **url** may take:

            1. A fully qualified url: ssh://git@example.com/foo/bar.git
            2. A local project.git folder: /path/to/bare/repository.git
            3. SCP shorthand for form 1: git@example.com:foo/bar.git

        Form 1 is output as-is. Form 2 must be converted to URI and form 3 must
        be converted to form 1.

        See the corresponding test test_git_remote_url_to_pip() for examples of
        sample inputs/outputs.
        z\w+://zssh://\1\2/\3N)rer   ospathexistspathlibPurePathas_uri	SCP_REGEXexpandr   )r'   Z	scp_matchr   r   r   rs   m  s    

zGit._git_remote_to_pip_url)r>   r%   r   c             C   s>   y | j dddd| g|dd W n tk
r4   dS X dS dS )	zU
        Check if rev is a commit that is available in the local repository.
        z	rev-parsez-qz--verifyzsha^F)rA   log_failed_cmdTN)r7   r   )rE   r>   r%   r   r   r   rW     s    zGit.has_commitc             C   s*   |d krd}| j d|gdd|d}|j S )Nr$   z	rev-parseFT)r1   r2   rA   )r7   rB   )rE   r>   r%   Zcurrent_revr   r   r   r_     s    zGit.get_revisionc             C   sT   | j ddgdd|dj }tjj|s4tjj||}tjjtjj|d}t||S )z
        Return the path to Python project root, relative to the repo root.
        Return None if the project root is in the repo root.
        z	rev-parsez	--git-dirFT)r1   r2   rA   z..)r7   rB   rw   rx   isabsjoinabspathr   )rE   r>   Z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|jddjd }|jdd }	|d|	 t	||	d ||||f }d|krd|kst
|jd	d
}t j|\}}
}|jdd}n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.
        fileN/\+r?   z://zfile:zgit+z
git+ssh://zssh:// )urlsplitendswithrD   lstripurllibrequesturl2pathnamereplacefind
urlunsplitr[   superget_url_rev_and_auth)rE   r'   schemenetlocrx   queryfragmentinitial_slashesnewpathZ
after_plusr%   	user_pass)	__class__r   r   r     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.gitmodulesZ	submodulerp   z--initz--recursivez-q)rA   )rw   rx   ry   r   r7   )rE   r>   r   r   r   rh     s
    zGit.update_submodulesc                sx   t  j|}|r|S y| jddg|ddddd}W n2 tk
rR   tjd| d S  tk
rd   d S X tjj	|j
dS )	Nz	rev-parsez--show-toplevelFTraise)rA   r1   r2   rK   r   zKcould not determine if %s is under git control because git is not availablez
)r   get_repository_rootr7   r   r9   rg   r   rw   rx   normpathrR   )rE   r>   locr)r   r   r   r     s&    zGit.get_repository_root)repo_urlr   c             C   s   dS )zEIn either https or ssh form, requirements must be prefixed with git+.Tr   )r   r   r   r   should_add_vcs_url_prefix  s    zGit.should_add_vcs_url_prefix)r   r   r   r    r!   )r"   r#   )N))__name__
__module____qualname__ra   dirname	repo_nameschemesunset_environdefault_arg_revstaticmethodstrr   r&   r   r/   r   r3   r=   classmethodr   rI   r+   rX   r   r   r`   r*   rk   rm   rp   ru   rs   rW   r_   r   r   r   rh   r   r   __classcell__r   r   )r   r   r   ;   s\        -+7
$r   )-loggingos.pathrw   rz   rv   urllib.parser   urllib.requesttypingr   r   r   pip._internal.exceptionsr   r   pip._internal.utils.miscr   r   r	   pip._internal.utils.subprocessr
    pip._internal.vcs.versioncontrolr   r   r   r   r   r   r   parser   r   	getLoggerr   r9   compiler8   r   VERBOSEr}   r   r   r   r   registerr   r   r   r   <module>   s2   $



   I