a
    0fG                     @   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	 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 "e#Z$e%dZ&e%d	Z'e%d
ej(Z)e*e+dddZ,G dd deZ-e.e- dS )    N)replace)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| S N)bool
HASH_REGEXmatch)r    r   N/var/www/ai-form-bot/venv/lib/python3.9/site-packages/pip/_internal/vcs/git.pylooks_like_hash8   s    r   c                       s  e Zd ZdZdZdZdZdZ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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d,d-d.Z ed<e
ee
 e
d,d/d0Z!ee
ee
 dd1d2Z"ee
ee
ee
 e#f d) fd3d4Z$ee
ddd5d6Z%ee
ee
 d fd7d8Z&e	e
ed9d:d;Z'  Z(S )=Gitgitz.gitclone)zgit+httpz	git+httpszgit+sshzgit+gitzgit+file)GIT_DIRGIT_WORK_TREEHEAD)revr   c                 C   s   | gS r   r   r"   r   r   r   get_base_rev_argsL   s    zGit.get_base_rev_args)urldestr   c                 C   sJ   |  t|\}}|jsdS | ||js.dS t| ||jd }| S )NFr   )get_url_rev_optionsr
   r"   is_commit_id_equalr   get_revision_sha)selfr%   r&   _rev_optionsis_tag_or_branchr   r   r   is_immutable_rev_checkoutP   s    zGit.is_immutable_rev_checkout.)r   c                 C   sN   | j dgdddd}t|}|s2td| dS t|dt|d	fS )
Nversionzgit versionFT)command_descshow_stdoutstdout_onlyzCan't parse git version: %sr         )run_commandGIT_VERSION_REGEXr   loggerwarningintgroup)r*   r/   r   r   r   r   get_git_version^   s    
zGit.get_git_version)locationr   c                 C   sB   g d}| j |ddd|d}| }|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-ref-qr!   r3   FTextra_ok_returncodesr1   r2   cwdzrefs/heads/N)r5   strip
startswithlen)clsr<   argsoutputrefr   r   r   get_current_branchk   s    

zGit.get_current_branch)r&   r"   r   c              	   C   s   | j d|g|dddd}i }| dD ]T}|d}|s>q*z|jdd	d
\}}W n  tyt   td|Y n0 |||< q*d| }d| }	||}
|
dur|
dfS ||	}
|
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
 r4   )maxsplitzunexpected show-ref line: zrefs/remotes/origin/z
refs/tags/N)r5   rB   splitrstrip
ValueErrorget)rE   r&   r"   rG   refslineref_sharef_name
branch_reftag_refr   r   r   r   r)      s0    





zGit.get_revision_shac                 C   s.   | drdS t|sdS | ||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usJ | ||\}}|durL||}t||r@|ndd}|S t|s`td| | ||sp|S | jt	dd||
 |d | j|dd}||}|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.
        N)branch_namez:Did not find branch or tag '%s', assuming revision or ref.fetchr=   rA   
FETCH_HEADr#   )arg_revr)   make_newr   r   r7   r8   r[   r5   r   to_argsget_revision)rE   r&   r%   r,   r"   r   	is_branchr   r   r   resolve_revision   s*    

zGit.resolve_revision)r&   namer   c                 C   s   |sdS |  ||kS )z
        Return whether the current commit hash equals the given name.

        Args:
          dest: the repository directory.
          name: a string name.
        F)rc   )rE   r&   rf   r   r   r   r(      s    	zGit.is_commit_id_equalN)r&   r%   r,   	verbosityr   c                 C   sX  |  }td||t| |dkr*d}n|dkr8d}nd}|  dkrj| tdd	g|||R   n| tdg|||R   |jr&| |||}t	|d
d }t
d|| |d u r| ||jstdd| }| j||d n6| ||kr:d| }	dd|d|	g}| j||d n| |}
||
}td||j | | d S )NzCloning %s%s to %sr   )z--quietr3   r   )z	--verbosez
--progress)r4      r   z--filter=blob:noner\   zRev options %s, branch_name %scheckoutr=   r^   zorigin/z-bz--trackzResolved %s to commit %s)
to_displayr7   infor	   r;   r5   r   r"   re   getattrdebugr(   rb   rI   rc   ra   update_submodules)r*   r&   r%   r,   rg   rev_displayflagsr\   cmd_argstrack_branchr   r   r   r   	fetch_new  s\    



zGit.fetch_newc                 C   sB   | j tdd||d tdd| }| j ||d | | d S )Nconfigzremote.origin.urlr^   ri   r=   )r5   r   rb   rn   r*   r&   r%   r,   rq   r   r   r   switchE  s    
z
Git.switchc                 C   sn   |   dkr | jg d|d n| jddg|d | |||}tddd| }| j||d | | d S )N)r3   	   )r]   r=   z--tagsr^   r]   r=   resetz--hard)r;   r5   re   r   rb   rn   ru   r   r   r   updateO  s    z
Git.updatec                 C   s|   | j g dddd|d}| }z|d }W n tyB   tY n0 |D ]}|drH|} q`qH|dd	 }| | S )
z
        Return URL of the first remote encountered.

        Raises RemoteNotFoundError if the repository does not have a remote
        url configured.
        )rt   z--get-regexpzremote\..*\.urlr>   FTr?   r   zremote.origin.url rN   r3   )r5   
splitlines
IndexErrorr   rC   rP   _git_remote_to_pip_urlrB   )rE   r<   stdoutremotesfound_remoteremoter%   r   r   r   get_remote_url]  s$    


zGit.get_remote_url)r%   r   c                 C   sN   t d| r| S tj| r*t|  S t| }|rB|	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%   	scp_matchr   r   r   r|   {  s    

zGit._git_remote_to_pip_url)r<   r"   r   c                 C   s>   z | j dddd| g|dd W n ty4   Y dS 0 dS dS )	zU
        Check if rev is a commit that is available in the local repository.
        	rev-parser=   z--verifyzsha^F)rA   log_failed_cmdTN)r5   r   )rE   r<   r"   r   r   r   rZ     s    
zGit.has_commitc                 C   s*   |d u rd}| j d|gdd|d}| S )Nr!   r   FTr1   r2   rA   )r5   rB   )rE   r<   r"   current_revr   r   r   rc     s    zGit.get_revisionc                 C   sT   | j ddgdd|d }tj|s4tj||}tjt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.
        r   z	--git-dirFTr   z..)r5   rB   r   r   isabsjoinabspathr   )rE   r<   git_dir	repo_rootr   r   r   get_subdirectory  s    
zGit.get_subdirectoryc                    s   t |\}}}}}|dr|dt|d  }|tj|ddd }|dd }	|d|	 t	||	d ||||f }d|vrd|vsJ |d	d
}t
 |\}}
}|dd}nt
 |\}}
}||
|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/\+r3   z://zfile:zgit+z
git+ssh://zssh:// )urlsplitendswithrD   lstripurllibrequesturl2pathnamer   find
urlunsplitsuperget_url_rev_and_auth)rE   r%   schemenetlocr   queryfragmentinitial_slashesnewpath
after_plusr"   	user_pass	__class__r   r   r     s&    

zGit.get_url_rev_and_authc                 C   s0   t jt j|dsd S | jg d|d d S )Nz.gitmodules)	submodulery   z--initz--recursiver=   r^   )r   r   r   r   r5   )rE   r<   r   r   r   rn     s    zGit.update_submodulesc                    sx   t  |}|r|S z| jddg|ddddd}W n2 tyR   td| Y d S  tyd   Y d S 0 tj	|
dS )	Nr   z--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_rootr5   r   r7   rm   r   r   r   normpathrQ   )rE   r<   locrr   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)N))__name__
__module____qualname__rf   dirname	repo_nameschemesunset_environdefault_arg_revstaticmethodstrr   r$   r   r.   r   r9   r;   classmethodr   rI   r)   r[   r   r   re   r(   rs   rv   ry   r   r|   rZ   rc   r   r   r   rn   r   r   __classcell__r   r   r   r   r   <   sZ   	 --?
$r   )/loggingos.pathr   r   r   urllib.parser   urllib.requestdataclassesr   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   r7   compiler6   r   VERBOSEr   r   r   r   r   registerr   r   r   r   <module>   s8   $



   V